-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfunction.c
More file actions
78 lines (76 loc) · 1.92 KB
/
function.c
File metadata and controls
78 lines (76 loc) · 1.92 KB
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
#include "function.h"
#include "ast.h"
#include "symbol_table.h"
#include "Loops.h"
#include <stdlib.h>
struct ast *newuserfunction(struct symbol *s, struct ast *l) {
struct userfunction *a = malloc(sizeof(struct userfunction));
if (!a) {
yyerror("out of space");
exit(0);
}
a->nodetype = 'C';
a->l = l;
a->s = s;
return (struct ast *)a;
}
double calluserfunction(struct userfunction *f) {
struct symbol *fn = f->s; /* function name */
struct symlist *sl; /* dummy arguments */
struct ast *args = f->l; /* actual arguments */
double *oldval, *newval; /* saved arg values */
double v;
int nargs;
int i;
if (!fn->func) {
yyerror("call to undefined function", fn->name);
return 0;
}
/* count the arguments */
sl = fn->syms;
for (nargs = 0; sl; sl = sl->next)
nargs++;
/* prepare to save them */
oldval = (double *)malloc(nargs * sizeof(double));
newval = (double *)malloc(nargs * sizeof(double));
if (!oldval || !newval) {
yyerror("Out of space in %s", fn->name);
return 0.0;
}
/* evaluate the arguments */
for (i = 0; i < nargs; i++) {
if (!args) {
yyerror("too few args in call to %s", fn->name);
free(oldval);
free(newval);
return 0.0;
}
if (args->nodetype == 'L') { /* if this is a list node */
newval[i] = eval(args->l);
args = args->r;
} else { /* if it's the end of the list */
newval[i] = eval(args);
args = NULL;
}
}
/* save old values of dummies, assign new ones */
sl = fn->syms;
for (i = 0; i < nargs; i++) {
struct symbol *s = sl->sym;
oldval[i] = s->value;
s->value = newval[i];
sl = sl->next;
}
free(newval);
/* evaluate the function */
v = eval(fn->func);
/* put the real values of the dummies back */
sl = fn->syms;
for (i = 0; i < nargs; i++) {
struct symbol *s = sl->sym;
s->value = oldval[i];
sl = sl->next;
}
free(oldval);
return v;
}