summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/mathexamples.pcdt2
-rw-r--r--src/eval.c24
-rw-r--r--src/hashtable.c14
-rw-r--r--src/hashtable.h1
-rw-r--r--src/parse.c8
-rw-r--r--stdlib/math.pcdt12
6 files changed, 57 insertions, 4 deletions
diff --git a/examples/mathexamples.pcdt b/examples/mathexamples.pcdt
new file mode 100644
index 0000000..31d4f1d
--- /dev/null
+++ b/examples/mathexamples.pcdt
@@ -0,0 +1,2 @@
+@../stdlib/math.pcdt
+print(multiply(12; 5;))
diff --git a/src/eval.c b/src/eval.c
index dc15223..386442c 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -86,7 +86,6 @@ sym_t* try_eval_internal(sym_t* symbol, hashtable_t* symbolScope) {
exec_all(symbol->args, symbol->argCount - 1, symbolScope);
return eval(symbol->args[symbol->argCount - 1], symbolScope);
}
- /* TODO: rename storel */
else if (hash == get_hash("store")) {
/* first arg is value, remaining args are names */
/* TODO: recursion for multiple pairs */
@@ -99,6 +98,18 @@ sym_t* try_eval_internal(sym_t* symbol, hashtable_t* symbolScope) {
hashtable_add_pair(symbolScope->parent, p);
return init_sym_int(1);
}
+ else if (hash == get_hash("update")) {
+ /* first arg is value, remaining args are names */
+ /* TODO: recursion for multiple pairs */
+ sym_t* v = eval(symbol->args[1], symbolScope);
+ char* k = symtos(v);
+ destroy_sym(v);
+ sym_t* value = symbol->args[0];
+ pair_t p = init_pair(k, (void*)value);
+ free(k);
+ hashtable_update_pair_recurse(symbolScope->parent, p);
+ return init_sym_int(1);
+ }
/* TODO: release()/free() method? */
else if (hash == get_hash("eq")) {
litType_t type = NO_TYPE;
@@ -175,6 +186,17 @@ sym_t* try_eval_internal(sym_t* symbol, hashtable_t* symbolScope) {
}
return init_sym_int(sum);
}
+ else if (hash == get_hash("sub")) {
+ sym_t* v1 = eval(symbol->args[0], symbolScope);
+ int sum = symtoi(v1);
+ destroy_sym(v1);
+ for (int i = 1; i < symbol->argCount; i++) {
+ sym_t* v = eval(symbol->args[i], symbolScope);
+ sum -= symtoi(v);
+ destroy_sym(v);
+ }
+ return init_sym_int(sum);
+ }
else if (hash == get_hash("print")) {
sym_t* v = eval(symbol->args[0], symbolScope);
if (v->litType == INT) {
diff --git a/src/hashtable.c b/src/hashtable.c
index 3a83861..2ec766d 100644
--- a/src/hashtable.c
+++ b/src/hashtable.c
@@ -49,18 +49,28 @@ unsigned int hashtable_add_pair(hashtable_t* hashtable, pair_t pair) {
unsigned int hash = get_hash(pair.key);
for (int i = 0; i < hashtable->capacity; i++) {
pair_t p = hashtable->pairs[hash % hashtable->capacity];
- if (p.key == NULL || p.key == pair.key) {
+ if (p.key == NULL || strcmp(p.key, pair.key) == 0) {
hashtable->pairs[hash % hashtable->capacity] = pair;
return hash;
}
}
return 0;
}
+unsigned int hashtable_update_pair_recurse(hashtable_t* origin, pair_t pair) {
+ pair_t p = hashtable_get_pair(origin, pair.key);
+ if (p.key != NULL) {
+ return hashtable_add_pair(origin, pair);
+ }
+ if (origin->parent != NULL) {
+ return hashtable_update_pair_recurse(origin->parent, pair);
+ }
+ return 0;
+}
pair_t hashtable_get_pair(hashtable_t* hashtable, char* key) {
unsigned int hash = get_hash(key);
for (int i = 0; i < hashtable->capacity; i++) {
pair_t p = hashtable->pairs[hash % hashtable->capacity];
- if (p.key == key) {
+ if (p.key != NULL && strcmp(p.key, key) == 0) {
return p;
}
else if (p.key == NULL) {
diff --git a/src/hashtable.h b/src/hashtable.h
index 34751fa..6f0dc51 100644
--- a/src/hashtable.h
+++ b/src/hashtable.h
@@ -16,6 +16,7 @@ hashtable_t* init_hashtable(unsigned int capacity, hashtable_t* parent);
void destroy_hashtable(hashtable_t* hashtable);
unsigned int get_hash(char* str);
unsigned int hashtable_add_pair(hashtable_t* hashtable, pair_t pair);
+unsigned int hashtable_update_pair_recurse(hashtable_t* origin, pair_t pair);
pair_t hashtable_get_pair(hashtable_t* hashtable, char* key);
pair_t hashtable_get_pair_recurse(hashtable_t* origin, char* key);
diff --git a/src/parse.c b/src/parse.c
index 0144f44..79c1dc4 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -104,7 +104,13 @@ symset_t* parse_symbols(char** str) {
}
/* int */
else {
- int v = atoi(symbolName);
+ int v;
+ if (symbolName[0] == '-') {
+ v = atoi(symbolName + 1) * -1;
+ }
+ else {
+ v = atoi(symbolName);
+ }
symbol = init_sym_int(v);
}
symset_add_symbol(symbolSet, symbol);
diff --git a/stdlib/math.pcdt b/stdlib/math.pcdt
new file mode 100644
index 0000000..078045d
--- /dev/null
+++ b/stdlib/math.pcdt
@@ -0,0 +1,12 @@
+store(
+ (
+ store(0; last;)
+ if(not(eq(arg0() 1;))
+ (
+ update(multiply(sub(arg0() 1;) arg1()) last;)
+ )
+ )
+ sum(arg1() last())
+ )
+ multiply;
+)