1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
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;
}
|