summaryrefslogtreecommitdiff
path: root/parser.c
diff options
context:
space:
mode:
authorthing 1 <thing1@seacrossedlovers.xyz>2025-01-10 17:38:56 +0000
committerthing 1 <thing1@seacrossedlovers.xyz>2025-01-10 17:38:56 +0000
commite46e08fceff29622399855043554635d6e33c3c4 (patch)
treeb8074819364bd54b54b4798f07002fe234c506ac /parser.c
init commit
Diffstat (limited to 'parser.c')
-rw-r--r--parser.c116
1 files changed, 116 insertions, 0 deletions
diff --git a/parser.c b/parser.c
new file mode 100644
index 0000000..9bbc50b
--- /dev/null
+++ b/parser.c
@@ -0,0 +1,116 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include <ctype.h>
+#include "stack.h"
+#include "parser.h"
+#include "eval.h"
+
+static unsigned int jumpdist;
+
+static char *readexpr(char *expr){
+ char *out = malloc(strlen(expr+1));
+ char *c = expr;
+ stack *s = push(NULL, *c);
+ int i;
+
+ for (i = 0; s->len != 0; i++){
+ out[i] = *c;
+ c++;
+ if (*c == '(') s = push(s, '(');
+ else if (*c == ')' && peek(s) == '(') pop(s);
+ }
+ cleanstack(s);
+
+ out[i] = ')';
+ out[i+1] = 0;
+ out = realloc(out, strlen(out));
+ jumpdist = i+1;
+ return out;
+}
+
+static char *readval(char *expr){
+ char *out = strdup(expr);
+ char *gap = strchr(out, ' ');
+ if (gap == NULL) gap = strchr(out, ')');
+ jumpdist = (gap - out)+1;
+ *gap = 0;
+ out = realloc(out, strlen(out));
+ return out;
+}
+
+static luckyval *readargs(char *expr){
+ luckyval *head = malloc(sizeof(luckyval));
+
+ if (*expr != ')' && expr[0] != 0){
+ if (expr[0] == '(' ){ // nested function
+ char *subexpr = readexpr(expr);
+ expr += jumpdist + 1;
+ head->tree = parse(subexpr);
+ head->type = LUCKYTREE;
+ free(subexpr);
+ }
+ else if (strchr(expr, '.') != NULL){ // float
+ char *val = readval(expr);
+ expr += jumpdist;
+ head->f = atof(val);
+ head->type = LUCKYFLOAT;
+ free(val);
+ }
+ else if (isdigit(expr[0])){ // int
+ char *val = readval(expr);
+ expr += jumpdist;
+ head->i = atoi(val);
+ head->type = LUCKYINT;
+ free(val);
+ }
+ else { // var name
+ char *val = readval(expr);
+ expr += jumpdist;
+ head->var = strdup(val);
+ head->type = LUCKYVAR;
+ }
+ } else return NULL;
+
+ head->nextelement = readargs(expr);
+ return head;
+}
+
+luckytree *parse(char *expr){
+ char *c = expr;
+ stack *s = push(NULL, *c);
+ while (*c != 0){
+ c++;
+ if (*c == '(') s = push(s, '(');
+ else if (*c == ')' && peek(s) == '(') pop(s);
+ }
+ if (s->len != 0){
+ printf("%s\n", expr);
+ for (int i = 0; i < (c - expr) - 1; i++) printf(" ");
+ printf("^\n");
+ printf("bracket mismatch!\n");
+ exit(1);
+ }
+ cleanstack(s);
+
+ luckytree *tree = malloc(sizeof(luckytree));
+
+ int funcnamelen;
+ if (strchr(expr+1, ' ') == NULL)
+ funcnamelen = (strchr(expr+1, ')') - expr) - 1;
+ else
+ funcnamelen = (strchr(expr+1, ' ') - expr) - 1;
+
+ tree->function = malloc(funcnamelen + 1);
+
+ memcpy(tree->function, expr + 1, funcnamelen);
+ tree->function[funcnamelen] = 0;
+
+ expr += funcnamelen + 2;
+
+ tree->arguments = readargs(expr);
+
+ return tree;
+}
+