git @ Cat's Eye Technologies Bhuna / 53aa72d
Import of Bhuna 0.3 sources. catseye 10 years ago
74 changed file(s) with 1475 addition(s) and 1495 deletion(s). Raw diff Collapse all Expand all
00 Program ::= {Statement}.
11 Block ::= Statement | "{" {Statement} "}".
2 Statement ::= (Control | Command | Assignment | Block) [";"].
2 Statement ::= (Definition | Assignment | Command | Control | Block) [";"].
3
4 Definition ::= {"local" | "const"} Var "=" Expr<0>. [[1]]
5 Assignment ::= Var {LAccessor} "=" Expr<0>.
6 Command ::= Var {LAccessor} Expr<0> {"," Expr<0>}.
37
48 Control ::= "if" Expr<0> Block ["else" Block]
5 | "while" Expr<0> Block.
6
7 Command ::= VarExpr Expr<0> {"," Expr<0>}
8 Assignment ::= ["local"] VarExpr "=" Expr<0>.
9 | "while" Expr<0> Block
10 .
911
1012 Expr<N> ::= Expr<N+1> {Op<N> Expr<N+1>}.
1113 Expr<4> ::= Primitive.
1719
1820 Primitive ::= "(" Expr<0> ")"
1921 | "!" Primitive
20 | VarExpr
22 | Var {RAccessor}
2123 | "^" {Var [","]} Block
22 | FunName "(" [Expr<0> {"," Expr<0>}] ")"
2324 | "[" [Expr<0> {"," Expr<0>}] "]"
24 | Literal.
25 | Literal
26 .
2527
26 Literal ::=
27 | <<symbol>> [[3]]
28 | <<number>>.
28 Literal ::= <<symbol>> [[3]]
29 | <<number>>
30 .
2931
30 VarExpr ::= Var {"[" Expr<0> "]"}.
3132 Var ::= <<symbol>>. [[4]]
33
34 LAccessor ::= "[" Expr<0> "]"
35 | "." Literal
36 .
37
38 RAccessor ::= "[" Expr<0> "]"
39 | "." Literal
40 | "(" [Expr<0> {"," Expr<0>}] ")"
41 .
3242
3343 Footnotes:
3444
45 [[1]]: Var must not itself be mentioned in the Expr<0>.
3546 [[3]]: Must start with lowercase letter.
3647 [[4]]: Must start with Uppercase letter.
0 #!/usr/bin/perl
1 # $Id: ackermann.perl.html,v 1.5 2004/07/03 07:11:34 bfulgham Exp $
2 # http://www.bagley.org/~doug/shootout/
3
4 # With help from Ernesto Hernandez-Novich
5 use integer;
6
7 # Note: If memoization were allowed in this program, we could
8 # do so by adding:
9 # use Memoization;
10 # memoize("Ack");
11 #
12
13 # It's prettier but slower to do this
14 #sub Ack {
15 # my($M, $N) = @_;
16 # return( $N + 1 ) if ($M == 0);
17 # return( Ack($M - 1, 1) ) if ($N == 0);
18 # Ack($M - 1, Ack($M, $N - 1));
19 #}
20
21 # in our quest for speed, we must get ugly:
22 # it helps reduce stack frame size a little bit
23 # from Leif Stensson
24 sub Ack {
25 return $_[0] ? ($_[1] ? Ack($_[0]-1, Ack($_[0], $_[1]-1))
26 : Ack($_[0]-1, 1))
27 : $_[1]+1;
28 }
29
30 my $NUM = $ARGV[0];
31 $NUM = 1 if ($NUM < 1);
32 my $ack = Ack(3, $NUM);
33 print "Ack(3,$NUM): $ack\n";
0 #!/usr/bin/python
1 # $Id: ackermann.python.html,v 1.5 2004/07/03 07:11:34 bfulgham Exp $
2 # http://www.bagley.org/~doug/shootout/
3 # from Brad Knotwell
4
5 import sys
6
7 def Ack(M, N):
8 if (not M):
9 return( N + 1 )
10 if (not N):
11 return( Ack(M-1, 1) )
12 return( Ack(M-1, Ack(M, N-1)) )
13
14 def main():
15 NUM = int(sys.argv[1])
16 sys.setrecursionlimit(3000)
17 print "Ack(3,%d): %d" % (NUM, Ack(3, NUM))
18
19 main()
55 One = 1
66 Two = 2
77
8 Ack = {
9 M = Arg[One]
10 N = Arg[Two]
8 Ack = ^ M, N {
119 if M = Zero
1210 Return N + One
1311 else if N = Zero
0 Stack = ^ Size {
1 S = [1,2,3,4,5,6,7]
2 SP = 1
3
4 Push = ^ E {
5 //S[SP] = E
6 Store S, SP, E
7 SP = SP + 1
8 }
9
10 Pop = ^ {
11 SP = SP - 1
12 return S[SP]
13 }
14
15 return ^{}
16 }
17
18 Q = Stack(256)
19
20 Print Q.1, EoL
21 Print Q.2, EoL
22 Print Q.3, EoL
23 Print Q.4, EoL
24 Print Q.5, EoL
0 Stack = ^ Size {
1 S = [1,2,3,4,5,6,7]
2 SP = 1
3
4 Push = ^ E {
5 //S[SP] = E
6 Store S, SP, E
7 SP = SP + 1
8 }
9
10 Pop = ^ {
11 SP = SP - 1
12 return S[SP]
13 }
14
15 return [Push, Pop]
16 }
17
18 Q = Stack(256)
19 Q_Push = Q[1]
20 Q_Pop = Q[2]
21
22 T = Stack(256)
23 T_Push = T[1]
24 T_Pop = T[2]
25
26 T_Push 23
27
28 Q_Push 15
29 Print Q_Pop(), EoL
30
31 T_Push 71
32 Print T_Pop(), " ", T_Pop(), EoL
33
55 // Z = Y + 7
66 // X = [1, Z * Y, 3]
77
8 X = []
9
10 Print X, EoL
11
12 X = [1]
13
14 Print X, EoL
15
16 X = [1, 2]
17
18 Print X, EoL
19
820 X = [1, 2, 3]
921
10 Print X
22 Print X, EoL
11 const Paul = 23
22 const Mary = 10 * Peter
33 Jim = 14
4 const Earl = Jim * 8
4 // const Earl = Jim * 8
55 // Print Peter
66 // Print Paul
77 Print Mary
0 D = Dict(5, 123)
1
2 Print "D=", D, EoL
3 Print "D[5]=", D[5], EoL
4
5 D[6] = 23
6
7 Print "D=", D, EoL
8 Print "D[6]=", D[6], EoL
9
10 D[5] = 76
11 Print "D[5]=", D[5], EoL
12
13 R = D
14 Print "R=", R, EoL
15 Print "R[5]=", R[5], EoL
16 R[5] = "maloney"
17 Print "R=", R, EoL
18 Print "R[5]=", R[5], EoL
19 Print "D[5]=", D[5], EoL
20
21 C = R[5]
22 R[5] = 88
23 Print "C=", C, ", R[5]=", R[5], EoL
0 A = 1
1 B = 2 * A
2 C = C * 3
44 return 1
55 }
66
7 Print Fact(6)
7 Print Fact(6), EoL
77 return 1
88 }
99
10 Print Fact(6)
10 Print Fact(6), EoL
66
77 I = 1
88 while I <= 25 {
9 Print Fib(I)
10 Print EoL
9 Print Fib(I), EoL
1110 I = I + 1
1211 }
00 F = ^ M,N {
1 Print "Hello from F"
2 Print EoL
3 Print M
4 Print EoL
5 Print N
6 Print EoL
7 Print "Goodbye from F"
8 Print EoL
1 Print "Hello from F", EoL, M, EoL, N, Eol, "Goodbye from F", EoL
92 return M + N
103 }
114
125 G = F(19, 23)
13 Print "Result is: "
14 Print G
15 Print EoL
6 Print "Result is: ", G, EoL
167
0 G = {
0 G = ^{
11 Q = "hello"
2 F = {
3 Print Q
2 F = ^{
3 Print Q, EoL
44 }
55 F
66 }
0 F = {
0 F = ^{
11 T = 123
2 Return { Return 17 }
2 Return ^{ Return 17 }
33 }
44
55 Print F, EoL
0 F = {
1 Level = Index(Arg, 1)
0 F = ^ Level {
21 Print "Level is ", Level, EoL
3 Q = {
4 QLev = Index(Arg, 1)
2 Q = ^ QLev {
53 Print "QLev is ", QLev, EoL
64 Print "(And Q thinks Level is ", Level, ")", EoL
75 if (QLev < 3)
1311 F Level + 1
1412 } else {
1513 Print "At level three, woo!", EoL
16 Q(0)
14 Q 0
1715 }
1816 }
1917
20 F(0)
18 F 0
0 F = {
1 C = Index(Arg, 1)
2 C Index(Arg, 2)
0 F = ^ C, D {
1 C D
32 C "cheese"
43 }
54
6 R = {
7 Print "R was called with ", Index(Arg, 1), EoL
5 R = ^ C {
6 Print "R was called with ", C, EoL
87 }
98
109 F R, "Spam Spam Spam Spam wonderful Spam!"
0
1 Q = {}
2 P = {
3 Level = Arg[1]
0 Q = ^{}
1 P = ^ Level {
42 if (Level > 0) {
53 Print "Calling Q at level ", Level, EoL
64 Q Level - 1
75 Print "Called Q, Exiting P at level ", Level, EoL
86 }
97 }
10 Q = {
11 Level = Arg.1
8 Q = ^ Level {
129 if (Level > 0) {
1310 Print "Calling P at level ", Level, EoL
1411 P Level - 1
0 F = {
0 F = ^{
11 Q = 17
2 G = {
2 G = ^{
33 Print "Q is ", Q, EoL
44 }
55 G;
0 F = {
0 F = ^{
11 Q = 17
2 G = {
2 G = ^{
33 Print "Q is ", Q, EoL
44 }
55 G;
00 F = 19
11
2 Foo = {
2 Foo = ^{
33 local F = 23
4 print F
4 print F, EoL
55 }
66
7 Print F
7 Print F, EoL
88 Foo;
9 Print F
9 Print F, EoL
0 Foo = {
1 Print Arg
2 }
0 //Foo = {
1 // Print Arg
2 //}
33
4 Foo 19, 23, 76;
4 //Foo 19, 23, 76;
0 A = 23
1 I = 19
2 A[I] = 23
3 // Store A, I, 23
4
5 A[A[A[I]][23]] = 57
6
7 // Store A, A[A[I]][23], 57
8
9 A[I][J] = 12
10
11 // Store A[I], J, 12
0 Song = {
0 Song = ^{
11 Bottles = 99
22
3 Sing = {
3 Sing = ^{
44 Print Bottles, " bottles of beer on the wall,", EoL,
55 Bottles, " bottles of beer,", EoL,
66 "Take none down, pass none around,", EoL,
0 F = {
0 F = ^{
11 Q = 17
2 Return { T = 0 Print Q }
2 Return ^{ T = 0 Print Q, EoL }
33 }
44
55 X = 10
00 A = ["moe","larry","curly"]
1
2 Print A, EoL
13
24 B = Index(A, 1)
35
4 Print B
6 Print B, EoL
57
68 // B = [1,"hello","there"]
79 // Print A, EoL
1012 // Print A, EoL
1113 // Print B, EoL
1214
15 C = List("moe", "larry", "curly")
16 Print C
00 X = 10
11 while X > 0 {
2 Print X
3 Print EoL
2 Print X, EoL
43 X = X - 1
54 }
65
00
1 F = {
2 Print "hello!"
1 F = ^{
2 Print "hello!", EoL
33 }
44
5 G = {
6 Print "naff!"
5 G = ^{
6 Print "naff!", EoL
77 }
88
99 H = G // does not dup the AST...
00 G = 3
11
2 R = {
2 R = ^{
33 if G > 0 {
44 G = G - 1
55 R
0 Q = ^ A, B {
1 T = A - B
2 Print T, EoL
3 if T > 0
4 Q T, B
5 }
6
7 Q 10, 2
00
1 R = {
2 P = Arg[1]
1 R = ^ P {
32 Print "P is ", P, EoL
43 if (P > 0) R P - 1
54 Print "P is still ", P, EoL
0 Fun = ^ A {
1 if A > 5
2 return A + 7
3 else {
4 return A - 2
5 }
6 Print "No!"
7 }
8
9 Print Fun(8)
11 while F > 20 {
22 local F = 10
33 print F
4 // global f = 3
4 // global F = 3
55 }
66 print F
77
0 A = ["moe", "larry", 76]
1
2 Print A, EoL
3 Print A[2], EoL
4
5 Store A, 2, [5, 6, 7]
6 Print A, EoL
7
8 Store A[2], 3, "XXX"
9 Print A, EoL
0 A = [1, 3, "boo"]
1
2 Print A, EoL
3 A[1] = ["frank", "dr_forrester", "joel"]
4 Print A, EoL
5 A[1][A[2]] = "mike"
6 Print A, EoL
00 Sub = ^ {
1 Print "hello from Sub"
2 Print EoL
1 Print "hello from Sub", EoL
32 }
43
54 Sub
00 Sub = ^ A, B, C {
1 Print "hello from Sub"
2 Print A
3 Print B
4 Print C
1 Print "hello from Sub, A=", A, ", B=", B, ", C=", C
52 }
63
74 Sub "A", "B", "C"
0 Print 1 + 3
0 Print 1 + 3, " is ", 4
1
0 Print ["There was a farmer", "had a dog", 23, "and Bingo was his", "name-o"]
0 Print "There was a farmer", "had a dog", 23, "and Bingo was his", "name-o"
00 PROG= bhuna
11 SRCS= scan.c parse.c \
22 symbol.c ast.c \
3 mem.c \
3 mem.c pool.c \
44 list.c atom.c buffer.c closure.c dict.c value.c \
55 activation.c eval.c \
66 gen.c vm.c \
77 builtin.c \
88 main.c
99
10 # gen.c pool.c \
11 #CFLAGS+=-DPOOL_VALUES
12 CFLAGS+=-O2
10 CFLAGS+=-DPOOL_VALUES
1311 CFLAGS+=-DINLINE_BUILTINS
1412 CFLAGS+=-Wall -I/usr/local/include
1513 .ifndef NODEBUG
1816 CFLAGS+=-DNDEBUG
1917 .endif
2018
19 .ifdef OPTIMIZED
20 CFLAGS+=-O2 -finline-functions
21 .endif
2122 .ifdef PROFILED
2223 CFLAGS+=-pg
2324 .endif
00 Ack(3,7): 1021
1 2.586u 0.000s 0:02.62 98.4% 31+532k 0+0io 0pf+0w
1 1.178u 0.000s 0:01.18 99.1% 30+1092k 0+0io 0pf+0w
0 Ack(3,7): 1021
1 1.320u 0.000s 0:01.33 99.2% 46+1090k 0+0io 0pf+0w
2424 static struct activation *a_head = NULL;
2525 static int a_count = 0;
2626
27 #define A_STACK_SIZE 65536
28
29 unsigned char a_stack[A_STACK_SIZE];
30 unsigned char *a_sp = a_stack;
31
2732 struct activation *
28 activation_new(int size, struct activation *caller, struct activation *enclosing)
33 activation_new_on_heap(int size, struct activation *caller, struct activation *enclosing)
2934 {
3035 struct activation *a;
3136
5863
5964 a = bhuna_malloc(sizeof(struct activation) +
6065 sizeof(struct value *) * size);
61 bzero(a, sizeof(struct activation) +
62 sizeof(struct value *) * size);
66 /*bzero(a, sizeof(struct activation) +
67 sizeof(struct value *) * size);*/
6368 a->size = size;
6469 a->caller = caller;
6570 a->enclosing = enclosing;
6671 a->marked = 0;
6772
73 /*
74 * Link up to our GC list.
75 */
76 a->next = a_head;
77 a_head = a;
78
6879 #ifdef DEBUG
6980 if (trace_activations > 1) {
70 printf("[ARC] created ");
81 printf("[ARC] created on HEAP");
7182 activation_dump(a, -1);
7283 printf("\n");
7384 }
7889 return(a);
7990 }
8091
81 void
82 activation_register(struct activation *a)
83 {
84 a->next = a_head;
85 a_head = a;
86 }
87
88 void
89 activation_free(struct activation *a)
90 {
91 int i;
92 struct activation *
93 activation_new_on_stack(int size, struct activation *caller, struct activation *enclosing)
94 {
95 struct activation *a;
96
97 a = (struct activation *)a_sp;
98 a_sp += sizeof(struct activation) + sizeof(struct value *) * size;
99
100 a->size = size;
101 a->caller = caller;
102 a->enclosing = enclosing;
92103
93104 #ifdef DEBUG
94105 if (trace_activations > 1) {
95 printf("[ARC] freeing ");
106 printf("[ARC] created on STACK ");
96107 activation_dump(a, -1);
97108 printf("\n");
98109 }
110 activations_allocated++;
111 #endif
112
113 return(a);
114 }
115
116 void
117 activation_free_from_heap(struct activation *a)
118 {
119 int i;
120
121 #ifdef DEBUG
122 if (trace_activations > 1) {
123 printf("[ARC] freeing from HEAP ");
124 activation_dump(a, -1);
125 printf("\n");
126 }
99127 activations_freed++;
100128 #endif
129
101130 for (i = 0; i < a->size; i++)
102131 value_release(VALARY(a, i));
103132
104133 bhuna_free(a);
105134 a_count--;
135 }
136
137 int
138 activation_is_on_stack(struct activation *a)
139 {
140 return ((unsigned char *)a >= a_stack &&
141 (unsigned char *)a < (a_stack + A_STACK_SIZE));
142 }
143
144 void
145 activation_free_from_stack(struct activation *a)
146 {
147 int i;
148
149 #ifdef DEBUG
150 if (trace_activations > 1) {
151 printf("[ARC] freeing from STACK ");
152 activation_dump(a, -1);
153 printf("\n");
154 }
155 activations_freed++;
156 #endif
157
158 for (i = 0; i < a->size; i++)
159 value_release(VALARY(a, i));
160
161 a_sp -= (sizeof(struct activation) + sizeof(struct value *) * a->size);
106162 }
107163
108164 struct value *
143199 }
144200
145201 void
202 activation_initialize_value(struct activation *a, int index,
203 struct value *v)
204 {
205 assert(a != NULL);
206 assert(index < a->size);
207 value_grab(v);
208 VALARY(a, index) = v;
209 }
210
211 void
146212 activation_dump(struct activation *a, int detail)
147213 {
148214 #ifdef DEBUG
158224 if (detail > 0) {
159225 for (i = 0; i < a->size; i++) {
160226 printf(" ");
161 value_print(VALARY(a, i));
227 if (VALARY(a, i) != NULL && VALARY(a, i)->type == VALUE_CLOSURE) {
228 printf("(closure) ");
229 } else {
230 value_print(VALARY(a, i));
231 }
162232 }
163233 }
164234
267337 printf("\n");
268338 }
269339 #endif
270 activation_free(a);
340 activation_free_from_heap(a);
271341 }
272342 }
273343
0 #define DEFAULT_GC_TRIGGER 10240
0 #define DEFAULT_GC_TRIGGER 512
11
22 struct value;
33
1818 */
1919 };
2020
21 struct activation *activation_new(int, struct activation *, struct activation *);
22 void activation_free(struct activation *);
21 struct activation *activation_new_on_heap(int, struct activation *, struct activation *);
22 struct activation *activation_new_on_stack(int, struct activation *, struct activation *);
23 int activation_is_on_stack(struct activation *);
24 void activation_free_from_heap(struct activation *);
25 void activation_free_from_stack(struct activation *);
2326
2427 struct value *activation_get_value(struct activation *, int, int);
2528 void activation_set_value(struct activation *, int, int, struct value *);
29 void activation_initialize_value(struct activation *, int, struct value *);
2630
2731 void activation_dump(struct activation *, int);
2832
29 void activation_register(struct activation *);
3033 void activation_gc(void);
55 #include "list.h"
66 #include "value.h"
77 #include "builtin.h"
8 #include "activation.h"
9 #include "vm.h"
810
911 #ifdef DEBUG
1012 #include "symbol.h"
1113 #endif
1214
15 extern unsigned char program[];
16
1317 /***** constructors *****/
1418
1519 struct ast *
20 ast_new(int type)
21 {
22 struct ast *a;
23
24 a = malloc(sizeof(struct ast));
25 a->type = type;
26 a->label = NULL;
27
28 return(a);
29 }
30
31 struct ast *
1632 ast_new_local(int index, int upcount, void *sym)
1733 {
1834 struct ast *a;
1935
20 a = malloc(sizeof(struct ast));
21 a->type = AST_LOCAL;
22
36 a = ast_new(AST_LOCAL);
2337 a->u.local.index = index;
2438 a->u.local.upcount = upcount;
2539 #ifdef DEBUG
3448 {
3549 struct ast *a;
3650
37 a = malloc(sizeof(struct ast));
38 a->type = AST_VALUE;
39
51 a = ast_new(AST_VALUE);
4052 value_grab(v);
4153 a->u.value.value = v;
4254
4456 }
4557
4658 struct ast *
47 ast_new_builtin(struct ast *left, struct ast *right, struct builtin *bi)
48 {
49 struct ast *a;
50
51 a = malloc(sizeof(struct ast));
52 a->type = AST_BUILTIN;
53
54 a->u.builtin.left = left;
59 ast_new_builtin(struct builtin *bi, struct ast *right)
60 {
61 struct ast *a;
62
63 /*
64 * Fold constants.
65 */
66 if (bi->is_pure && ast_is_constant(right)) {
67 struct value *v = NULL;
68 struct activation *ar;
69 struct ast *g;
70 int i = 0;
71 int varity;
72
73 if (bi->arity == -1) {
74 varity = ast_count_args(right);
75 } else {
76 varity = bi->arity;
77 }
78 ar = activation_new_on_stack(varity, NULL, NULL);
79 for (g = right, i = 0;
80 g != NULL && g->type == AST_ARG && i < varity;
81 g = g->u.arg.right, i++) {
82 if (g->u.arg.left != NULL)
83 activation_initialize_value(ar, i,
84 g->u.arg.left->u.value.value);
85 }
86 bi->fn(ar, &v);
87 activation_free_from_stack(ar);
88 a = ast_new_value(v);
89 value_release(v);
90
91 return(a);
92 }
93
94 a = ast_new(AST_BUILTIN);
95
96 a->u.builtin.bi = bi;
5597 a->u.builtin.right = right;
56 a->u.builtin.bi = bi;
5798
5899 return(a);
59100 }
63104 {
64105 struct ast *a;
65106
66 a = malloc(sizeof(struct ast));
67 a->type = AST_APPLY;
68
107 a = ast_new(AST_APPLY);
69108 a->u.apply.left = fn;
70109 a->u.apply.right = args;
71110 a->u.apply.is_pure = is_pure;
78117 {
79118 struct ast *a;
80119
81 a = malloc(sizeof(struct ast));
82 a->type = AST_ARG;
83
120 a = ast_new(AST_ARG);
84121 a->u.arg.left = left;
85122 a->u.arg.right = right;
123
124 return(a);
125 }
126
127 struct ast *
128 ast_new_routine(int arity, int locals, int cc, struct ast *body)
129 {
130 struct ast *a;
131
132 a = ast_new(AST_ROUTINE);
133 a->u.routine.arity = arity;
134 a->u.routine.locals = locals;
135 a->u.routine.cc = cc;
136 a->u.routine.body = body;
86137
87138 return(a);
88139 }
99150 if (right == NULL)
100151 return(left);
101152
102 a = malloc(sizeof(struct ast));
103 a->type = AST_STATEMENT;
104
153 a = ast_new(AST_STATEMENT);
105154 a->u.statement.left = left;
106155 a->u.statement.right = right;
107156
113162 {
114163 struct ast *a;
115164
116 a = malloc(sizeof(struct ast));
117 a->type = AST_ASSIGNMENT;
118
165 a = ast_new(AST_ASSIGNMENT);
119166 a->u.assignment.left = left;
120167 a->u.assignment.right = right;
121168
127174 {
128175 struct ast *a;
129176
130 a = malloc(sizeof(struct ast));
131 a->type = AST_CONDITIONAL;
132
177 a = ast_new(AST_CONDITIONAL);
133178 a->u.conditional.test = test;
134179 a->u.conditional.yes = yes;
135180 a->u.conditional.no = no;
136 /*a->u.conditional.index = index;*/
137181
138182 return(a);
139183 }
157201 {
158202 struct ast *a;
159203
160 a = malloc(sizeof(struct ast));
161 a->type = AST_RETR;
162
204 a = ast_new(AST_RETR);
163205 a->u.retr.body = body;
164206
165207 return(a);
166208 }
209
210 /*** DESTRUCTOR ***/
167211
168212 void
169213 ast_free(struct ast *a)
178222 value_release(a->u.value.value);
179223 break;
180224 case AST_BUILTIN:
181 ast_free(a->u.apply.left);
182 ast_free(a->u.apply.right);
225 ast_free(a->u.builtin.right);
183226 break;
184227 case AST_APPLY:
185228 ast_free(a->u.apply.left);
188231 case AST_ARG:
189232 ast_free(a->u.arg.left);
190233 ast_free(a->u.arg.right);
234 break;
235 case AST_ROUTINE:
236 ast_free(a->u.routine.body);
191237 break;
192238 case AST_STATEMENT:
193239 ast_free(a->u.statement.left);
212258 }
213259 free(a);
214260 }
261
262 /*** PREDICATES &c. ***/
263
264 int
265 ast_is_constant(struct ast *a)
266 {
267 if (a == NULL)
268 return(1);
269 switch (a->type) {
270 case AST_VALUE:
271 return(1);
272 case AST_ARG:
273 return(ast_is_constant(a->u.arg.left) &&
274 ast_is_constant(a->u.arg.right));
275 }
276 return(0);
277 }
278
279 int
280 ast_count_args(struct ast *a)
281 {
282 int ac;
283
284 for (ac = 0; a != NULL && a->type == AST_ARG; a = a->u.arg.right, ac++)
285 ;
286
287 return(ac);
288 }
289
290 /*** DEBUGGING ***/
215291
216292 char *
217293 ast_name(struct ast *a)
230306 return("AST_APPLY");
231307 case AST_ARG:
232308 return("AST_ARG");
309 case AST_ROUTINE:
310 return("AST_ROUTINE");
233311 case AST_STATEMENT:
234312 return("AST_STATEMENT");
235313 case AST_ASSIGNMENT:
255333 return;
256334 }
257335 for (i = 0; i < indent; i++) printf(" ");
336 if (a->label != NULL) {
337 printf("@#%d -> ", a->label - (vm_label_t)program);
338 }
258339 switch (a->type) {
259340 case AST_LOCAL:
260341 printf("local(%d,%d)=", a->u.local.index, a->u.local.upcount);
269350 break;
270351 case AST_BUILTIN:
271352 printf("builtin `%s`{\n", a->u.builtin.bi->name);
272 ast_dump(a->u.builtin.left, indent + 1);
273353 ast_dump(a->u.builtin.right, indent + 1);
274354 for (i = 0; i < indent; i++) printf(" "); printf("}\n");
275355 break;
283363 printf("arg {\n");
284364 ast_dump(a->u.arg.left, indent + 1);
285365 ast_dump(a->u.arg.right, indent + 1);
366 for (i = 0; i < indent; i++) printf(" "); printf("}\n");
367 break;
368 case AST_ROUTINE:
369 printf("routine/%d (contains %d) {\n",
370 a->u.routine.arity, a->u.routine.cc);
371 ast_dump(a->u.routine.body, indent + 1);
286372 for (i = 0; i < indent; i++) printf(" "); printf("}\n");
287373 break;
288374 case AST_STATEMENT:
319405 }
320406 #endif
321407 }
322
323 int
324 ast_is_constant(struct ast *a)
325 {
326 if (a == NULL) {
327 return(1);
328 }
329 switch (a->type) {
330 case AST_LOCAL:
331 return(0);
332 case AST_VALUE:
333 return(1);
334 case AST_BUILTIN:
335 return(a->u.builtin.bi->purity &&
336 ast_is_constant(a->u.builtin.left) &&
337 ast_is_constant(a->u.builtin.right));
338 case AST_APPLY:
339 return(a->u.apply.is_pure &&
340 ast_is_constant(a->u.apply.left) &&
341 ast_is_constant(a->u.apply.right));
342 case AST_ARG:
343 return(ast_is_constant(a->u.arg.left) &&
344 ast_is_constant(a->u.arg.right));
345 case AST_STATEMENT:
346 return(ast_is_constant(a->u.statement.left) &&
347 ast_is_constant(a->u.statement.right));
348 case AST_ASSIGNMENT:
349 return(0);
350 /*
351 return(ast_is_constant(a->u.assignment.left) &&
352 ast_is_constant(a->u.assignment.right));
353 */
354 case AST_CONDITIONAL:
355 return(ast_is_constant(a->u.conditional.test) &&
356 ast_is_constant(a->u.conditional.yes) &&
357 ast_is_constant(a->u.conditional.no));
358 case AST_WHILE_LOOP:
359 return(ast_is_constant(a->u.while_loop.test) &&
360 ast_is_constant(a->u.while_loop.body));
361 case AST_RETR:
362 return(ast_is_constant(a->u.retr.body));
363 }
364 return(0);
365 }
00 #ifndef __AST_H_
11 #define __AST_H_
2
3 #include "vm.h"
24
35 struct value;
46 struct builtin;
1618 };
1719
1820 struct ast_builtin {
19 struct ast *left; /* ISA var(/...?) (fn/cmd) */
21 struct builtin *bi;
2022 struct ast *right; /* ISA arg */
21 struct builtin *bi;
2223 };
2324
2425 struct ast_apply {
3031 struct ast_arg {
3132 struct ast *left; /* ISA arg/apply/var */
3233 struct ast *right; /* ISA arg/apply/var */
34 };
35
36 struct ast_routine {
37 int arity; /* takes this many arguments */
38 int locals;/* has this many local variables */
39 int cc; /* contains this many closures */
40 struct ast *body;
3341 };
3442
3543 struct ast_statement {
6371 #define AST_BUILTIN 3
6472 #define AST_APPLY 4
6573 #define AST_ARG 5
66 #define AST_STATEMENT 6
67 #define AST_ASSIGNMENT 7
68 #define AST_CONDITIONAL 8
69 #define AST_WHILE_LOOP 9
70 #define AST_RETR 10
74 #define AST_ROUTINE 6
75 #define AST_STATEMENT 7
76 #define AST_ASSIGNMENT 8
77 #define AST_CONDITIONAL 9
78 #define AST_WHILE_LOOP 10
79 #define AST_RETR 11
7180
7281 union ast_union {
7382 struct ast_local local;
7584 struct ast_builtin builtin;
7685 struct ast_apply apply;
7786 struct ast_arg arg;
87 struct ast_routine routine;
7888 struct ast_statement statement;
7989 struct ast_assignment assignment;
8090 struct ast_conditional conditional;
8393 };
8494
8595 struct ast {
86 int is_constant;
8796 int type;
97 vm_label_t label;
8898 union ast_union u;
8999 };
90100
91101 struct ast *ast_new_local(int, int, void *);
92102 struct ast *ast_new_value(struct value *);
93 struct ast *ast_new_builtin(struct ast *, struct ast *, struct builtin *);
103 struct ast *ast_new_builtin(struct builtin *, struct ast *);
94104 struct ast *ast_new_apply(struct ast *, struct ast *, int);
95105 struct ast *ast_new_arg(struct ast *, struct ast *);
106 struct ast *ast_new_routine(int, int, int, struct ast *);
96107 struct ast *ast_new_statement(struct ast *, struct ast *);
97108 struct ast *ast_new_assignment(struct ast *, struct ast *);
98109 struct ast *ast_new_conditional(struct ast *, struct ast *, struct ast *);
100111 struct ast *ast_new_retr(struct ast *);
101112 void ast_free(struct ast *);
102113
114 int ast_is_constant(struct ast *);
115 int ast_count_args(struct ast *);
116
103117 void ast_dump(struct ast *, int);
104118 char *ast_name(struct ast *);
105119
106120 void ast_eval_init(void);
107121 void ast_eval(struct ast *, struct value **);
108122
109 int ast_is_constant(struct ast *);
110
111123 #endif /* !__AST_H_ */
1212 */
1313
1414 struct builtin builtins[] = {
15 {"Print", builtin_print, 1, 0, 1, 0},
16 {"!", builtin_not, 1, 1, 1, 1},
17 {"&", builtin_and, 2, 1, 1, 2},
18 {"|", builtin_or, 2, 1, 1, 3},
19 {"=", builtin_equ, 2, 1, 1, 4},
20 {"!=", builtin_neq, 2, 1, 1, 5},
21 {">", builtin_gt, 2, 1, 1, 6},
22 {"<", builtin_lt, 2, 1, 1, 7},
23 {">=", builtin_gte, 2, 1, 1, 8},
24 {"<=", builtin_lte, 2, 1, 1, 9},
25 {"+", builtin_add, 2, 1, 1, 10},
26 {"-", builtin_sub, 2, 1, 1, 11},
27 {"*", builtin_mul, 2, 1, 1, 12},
28 {"/", builtin_div, 2, 1, 1, 13},
29 {"%", builtin_mod, 2, 1, 1, 14},
30 {"Cons", builtin_cons, 2, 1, 1, 15},
31 {"Index", builtin_index, 2, 1, 1, 16},
32 {NULL, NULL, 0, 0, 0, 17}
15 {"Print", builtin_print, -1, 0, 1, 0},
16 {"!", builtin_not, 1, 1, 1, 1},
17 {"&", builtin_and, 2, 1, 1, 2},
18 {"|", builtin_or, 2, 1, 1, 3},
19 {"=", builtin_equ, 2, 1, 1, 4},
20 {"!=", builtin_neq, 2, 1, 1, 5},
21 {">", builtin_gt, 2, 1, 1, 6},
22 {"<", builtin_lt, 2, 1, 1, 7},
23 {">=", builtin_gte, 2, 1, 1, 8},
24 {"<=", builtin_lte, 2, 1, 1, 9},
25 {"+", builtin_add, 2, 1, 1, 10},
26 {"-", builtin_sub, 2, 1, 1, 11},
27 {"*", builtin_mul, 2, 1, 1, 12},
28 {"/", builtin_div, 2, 1, 1, 13},
29 {"%", builtin_mod, 2, 1, 1, 14},
30 {"List", builtin_list, -1, 1, 1, 15},
31 {"Fetch", builtin_fetch, 2, 1, 1, 16},
32 {"Store", builtin_store, 3, 0, 1, 17},
33 {"Dict", builtin_dict, -1, 1, 1, 18},
34 {NULL, NULL, 0, 0, 0, 19}
3335 };
3436
3537 void
3638 builtin_print(struct activation *ar, struct value **q)
3739 {
38 struct value *v = activation_get_value(ar, 0, 0);
39
40 switch (v->type) {
41 case VALUE_INTEGER:
42 printf("%d", v->v.i);
43 break;
44 case VALUE_BOOLEAN:
45 printf("%s", v->v.b ? "true" : "false");
46 break;
47 case VALUE_STRING:
48 printf("%s", v->v.s);
49 break;
50 case VALUE_LIST:
51 list_dump(v->v.l);
52 break;
53 case VALUE_ERROR:
54 printf("#ERR<%s>", v->v.e);
55 break;
56 case VALUE_BUILTIN:
57 printf("#BIF<%08lx>", (unsigned long)v->v.bi);
58 break;
59 case VALUE_CLOSURE:
60 closure_dump(v->v.k);
61 break;
62 case VALUE_DICT:
63 dict_dump(v->v.d);
64 break;
65 default:
66 printf("???unknown(%d)???", v->type);
67 break;
40 int i;
41 /*struct list *l;*/
42 struct value *v = NULL;
43
44 for (i = 0; i < ar->size; i++) {
45 v = activation_get_value(ar, i, 0);
46 if (v == NULL) {
47 printf("(null)");
48 continue;
49 }
50
51 switch (v->type) {
52 case VALUE_INTEGER:
53 printf("%d", v->v.i);
54 break;
55 case VALUE_BOOLEAN:
56 printf("%s", v->v.b ? "true" : "false");
57 break;
58 case VALUE_STRING:
59 printf("%s", v->v.s);
60 break;
61 case VALUE_LIST:
62 /*
63 printf("[");
64 for (l = v->v.l; l != NULL; l = l->next) {
65 */
66
67 list_dump(v->v.l);
68 break;
69 case VALUE_ERROR:
70 printf("#ERR<%s>", v->v.e);
71 break;
72 case VALUE_BUILTIN:
73 printf("#BIF<%08lx>", (unsigned long)v->v.bi);
74 break;
75 case VALUE_CLOSURE:
76 closure_dump(v->v.k);
77 break;
78 case VALUE_DICT:
79 dict_dump(v->v.d);
80 break;
81 default:
82 printf("???unknown(%d)???", v->type);
83 break;
84 }
6885 }
6986
7087 value_set_from_value(q, v);
274291 /*** list ***/
275292
276293 void
277 builtin_cons(struct activation *ar, struct value **v)
278 {
279 struct value *l = activation_get_value(ar, 0, 0);
280 struct value *r = activation_get_value(ar, 1, 0);
281
282 if (l->type == VALUE_LIST) {
283 list_cons(&l->v.l, r);
284 value_set_from_value(v, l);
285 } else {
286 return(value_set_error(v, "type mismatch"));
287 }
288 }
289
290 void
291 builtin_index(struct activation *ar, struct value **v)
292 {
293 struct value *l = activation_get_value(ar, 0, 0);
294 struct value *r = activation_get_value(ar, 1, 0);
294 builtin_list(struct activation *ar, struct value **v)
295 {
296 int i;
297 struct value *x = NULL;
298
299 value_set_list(v);
300
301 for (i = ar->size - 1; i >= 0; i--) {
302 x = activation_get_value(ar, i, 0);
303 value_list_append(v, x);
304 value_release(x);
305 }
306 }
307
308 void
309 builtin_fetch(struct activation *ar, struct value **v)
310 {
311 struct value *l = activation_get_value(ar, 0, 0);
312 struct value *r = activation_get_value(ar, 1, 0);
313 struct value *q;
295314 int count;
296315 struct list *li;
297316
298 if (l->type == VALUE_LIST && r->type == VALUE_INTEGER) {
317 if (l->type == VALUE_CLOSURE && r->type == VALUE_INTEGER) {
318 int i = r->v.i - 1;
319 /*
320 * This is _EVIL_!
321 */
322 if (i >= 0 && i < l->v.k->ar->size) {
323 q = activation_get_value(l->v.k->ar, i, 0);
324 value_set_from_value(v, q);
325 } else {
326 value_set_error(v, "out of bounds");
327 }
328 } else if (l->type == VALUE_DICT) {
329 q = dict_fetch(l->v.d, r);
330 value_set_from_value(v, q);
331 value_release(q);
332 } else if (l->type == VALUE_LIST && r->type == VALUE_INTEGER) {
299333 li = l->v.l;
300 for (count = 1; l != NULL && count < r->v.i; count++)
334 for (count = 1; li != NULL && count < r->v.i; count++)
301335 li = li->next;
302336 if (li == NULL)
303 return(value_set_error(v, "no such element"));
337 return(value_set_error(v, "out of bounds"));
304338 else {
305339 value_set_from_value(v, li->value);
306340 }
308342 return(value_set_error(v, "type mismatch"));
309343 }
310344 }
345
346 void
347 builtin_store(struct activation *ar, struct value **v)
348 {
349 struct value *d = activation_get_value(ar, 0, 0);
350 struct value *i = activation_get_value(ar, 1, 0);
351 struct value *p = activation_get_value(ar, 2, 0);
352 int count;
353 struct list *li;
354
355 if (d->type == VALUE_DICT) {
356 dict_store(d->v.d, i, p);
357 value_set_from_value(v, d);
358 } else if (d->type == VALUE_LIST && i->type == VALUE_INTEGER) {
359 li = d->v.l;
360 for (count = 1; li != NULL && count < i->v.i; count++)
361 li = li->next;
362 if (li == NULL)
363 value_set_error(v, "no such element");
364 else {
365 value_set_from_value(&li->value, p);
366 value_set_from_value(v, d);
367 }
368 } else {
369 value_set_error(v, "type mismatch");
370 }
371 }
372
373 void
374 builtin_dict(struct activation *ar, struct value **v)
375 {
376 int i;
377 struct value *key = NULL, *val = NULL;
378
379 value_set_dict(v);
380
381 if (ar->size % 2 != 0) {
382 value_set_error(v, "number of argument must be even");
383 } else {
384 for (i = 0; i < ar->size; i += 2) {
385 key = activation_get_value(ar, i, 0);
386 val = activation_get_value(ar, i + 1, 0);
387 value_dict_store(v, key, val);
388 value_release(key);
389 value_release(val);
390 }
391 }
392 }
77 char *name;
88 void (*fn)(struct activation *, struct value **);
99 int arity;
10 int purity;
11 int constness;
10 int is_pure;
11 int is_const;
1212 int index;
1313 };
1414
2727 #define INDEX_BUILTIN_MUL 12
2828 #define INDEX_BUILTIN_DIV 13
2929 #define INDEX_BUILTIN_MOD 14
30 #define INDEX_BUILTIN_CONS 15
31 #define INDEX_BUILTIN_INDEX 16
30 #define INDEX_BUILTIN_LIST 15
31 #define INDEX_BUILTIN_FETCH 16
32 #define INDEX_BUILTIN_STORE 17
33 #define INDEX_BUILTIN_DICT 18
3234
3335 #define INDEX_BUILTIN_LAST 127
3436
5355 void builtin_div(struct activation *, struct value **);
5456 void builtin_mod(struct activation *, struct value **);
5557
56 void builtin_cons(struct activation *, struct value **);
57 void builtin_index(struct activation *, struct value **);
58 void builtin_list(struct activation *, struct value **);
59 void builtin_fetch(struct activation *, struct value **);
60 void builtin_store(struct activation *, struct value **);
61
62 void builtin_dict(struct activation *, struct value **);
5863
5964 #endif
99 #include "vm.h"
1010
1111 struct closure *
12 closure_new(struct ast *a, struct activation *ar, int arity, int cc)
12 closure_new(struct ast *a, struct activation *ar)
1313 {
1414 struct closure *c;
1515
1616 c = bhuna_malloc(sizeof(struct closure));
1717 c->ast = a;
18 c->label = NULL;
1918 c->ar = ar;
20 c->arity = arity;
21 c->cc = cc;
2219
2320 return(c);
2421 }
2623 void
2724 closure_free(struct closure *c)
2825 {
29 /*activation_release(c->ar);*/
3026 bhuna_free(c);
3127 }
3228
3430 closure_dump(struct closure *c)
3531 {
3632 #ifdef DEBUG
37 printf("closure(arity=%d,contains=%d){", c->arity, c->cc);
38 activation_dump(c->ar, 0);
39 ast_dump(c->ast, 0);
33 printf("closure{");
34 activation_dump(c->ar, 1);
35 ast_dump(c->ast, 1);
4036 printf("}");
4137 #endif
4238 }
77
88 struct closure {
99 struct ast *ast;
10 vm_label_t label;
1110 struct activation *ar; /* env in which we were created */
12 int arity; /* takes this many arguments */
13 int cc; /* contains this many sub-closures */
1411 };
1512
16 struct closure *closure_new(struct ast *, struct activation *, int, int);
13 struct closure *closure_new(struct ast *, struct activation *);
1714 void closure_free(struct closure *);
1815 void closure_dump(struct closure *);
1916
7070 return(d);
7171 }
7272
73 static struct chain *
74 chain_dup(struct chain *f)
75 {
76 struct chain *c, *n, *p = NULL, *h = NULL;
77
78 for (c = f; c != NULL; c = c->next) {
79 n = bhuna_malloc(sizeof(struct chain));
80
81 n->next = NULL;
82 value_grab(c->key);
83 n->key = c->key;
84 value_grab(c->value);
85 n->value = c->value;
86
87 if (h == NULL)
88 h = n;
89 else
90 p->next = n;
91
92 p = n;
93 }
94
95 return(h);
96 }
97
98 struct dict *
99 dict_dup(struct dict *f)
100 {
101 struct dict *d;
102 int i;
103
104 d = bhuna_malloc(sizeof(struct dict));
105 d->num_buckets = 31;
106 d->bucket = bhuna_malloc(sizeof(struct chain *) * d->num_buckets);
107 for (i = 0; i < d->num_buckets; i++) {
108 d->bucket[i] = chain_dup(f->bucket[i]);
109 }
110 d->cursor = NULL; /* hmmm... dup'ing this would take trickery. */
111 d->cur_bucket = 0;
112
113 return(d);
114 }
115
73116 /*** DESTRUCTORS ***/
74117
75118 static void
116159 * This is naff... for certain values this will work.
117160 * For others, it won't...
118161 */
119 for (p = (char *)key; p - (char *)key < sizeof(struct value); p++) {
120 h = (h << 4) + (*p);
121 if ((g = h & 0xf0000000))
122 h = (h ^ (g >> 24)) ^ g;
162 if (key->type == VALUE_INTEGER ||
163 key->type == VALUE_BOOLEAN ||
164 key->type == VALUE_ATOM) {
165 for (p = (char *)key; p - (char *)key < sizeof(int); p++) {
166 h = (h << 4) + (*p);
167 if ((g = h & 0xf0000000))
168 h = (h ^ (g >> 24)) ^ g;
169 }
170 } else {
171 assert("key no good" == NULL);
123172 }
124173
125174 return(h % table_size);
136185 c = bhuna_malloc(sizeof(struct chain));
137186
138187 c->next = NULL;
139 /* XXX grab? */
140188 c->key = key;
141189 c->value = value;
142190
171219
172220 dict_locate(d, k, &i, &c);
173221 if (c != NULL) {
174 /* XXX grab? */
222 value_grab(c->value);
175223 return(c->value);
176224 } else {
177225 return(NULL);
190238 dict_locate(d, k, &i, &c);
191239 if (c == NULL) {
192240 /* Chain does not exist, add a new one. */
241 value_grab(k);
242 value_grab(v);
193243 c = chain_new(k, v);
194244 c->next = d->bucket[i];
195245 d->bucket[i] = c;
196246 } else {
197247 /* Chain already exists, replace the value. */
198248 value_release(c->value);
249 value_grab(v);
199250 c->value = v;
200251 }
201252 }
5656 };
5757
5858 struct dict *dict_new(void);
59 struct dict *dict_dup(struct dict *);
5960 void dict_free(struct dict *);
6061
6162 struct value *dict_fetch(struct dict *, struct value *);
1313 extern int trace_gen;
1414
1515 static vm_label_t gptr;
16 static unsigned char program[65536];
16 unsigned char program[65536];
1717
1818 vm_label_t patch_stack[4096];
1919 int psp = 0;
6969 #endif
7070
7171 gen(INSTR_PUSH_VALUE);
72 value_grab(v);
7273 *(((struct value **)gptr)++) = v;
7374 }
7475
183184 }
184185
185186 static void
186 gen_set_activation_bp(int *bpid)
187 {
188 #ifdef DEBUG
189 if (trace_gen)
190 printf("#%d: *SET_ACTIVATION", gptr - program);
187 gen_set_activation(void)
188 {
189 #ifdef DEBUG
190 if (trace_gen)
191 printf("#%d: *SET_ACTIVATION\n", gptr - program);
191192 #endif
192193 gen(INSTR_SET_ACTIVATION);
193 *bpid = request_backpatch(&gptr);
194 #ifdef DEBUG
195 if (trace_gen)
196 printf("($%d)\n", *bpid);
197 #endif
194 }
195
196 static void
197 gen_deep_copy(void)
198 {
199 #ifdef DEBUG
200 if (trace_gen)
201 printf("#%d: *DEEP_COPY\n", gptr - program);
202 #endif
203 gen(INSTR_DEEP_COPY);
198204 }
199205
200206 static void
202208 {
203209 int bpid_1, bpid_2;
204210 vm_label_t label;
211 struct value *v;
205212
206213 if (a == NULL)
207214 return;
208215
216 a->label = gptr;
209217 switch (a->type) {
210218 case AST_LOCAL:
211219 gen_push_local(a->u.local.index, a->u.local.upcount);
213221 case AST_VALUE:
214222 gen_push_value(a->u.value.value);
215223 if (a->u.value.value->type == VALUE_CLOSURE) {
216 gen_set_activation_bp(&bpid_1);
217 gen_jmp_bp(&bpid_2);
218 backpatch(bpid_1);
224 gen_set_activation();
225 gen_jmp_bp(&bpid_1);
219226 ast_gen_r(a->u.value.value->v.k->ast);
220227 gen_ret();
221 backpatch(bpid_2);
228 backpatch(bpid_1);
222229 }
223230 break;
224231 case AST_BUILTIN:
225 ast_gen_r(a->u.builtin.left);
226232 ast_gen_r(a->u.builtin.right);
233 if (a->u.builtin.bi->arity == -1) {
234 v = value_new_integer(ast_count_args(a->u.builtin.right));
235 gen_push_value(v);
236 value_release(v);
237 }
227238 gen_builtin(a->u.builtin.bi);
228239 break;
229240 case AST_APPLY:
231242 ast_gen_r(a->u.apply.left);
232243 gen_apply();
233244 break;
245 case AST_ROUTINE:
246 ast_gen_r(a->u.routine.body);
247 break;
234248 case AST_ARG:
235249 ast_gen_r(a->u.arg.left);
236250 ast_gen_r(a->u.arg.right);
243257 assert(a->u.assignment.left != NULL);
244258 assert(a->u.assignment.left->type == AST_LOCAL);
245259 ast_gen_r(a->u.assignment.right);
260 gen_deep_copy();
246261 gen_pop_local(a->u.assignment.left->u.local.index,
247262 a->u.assignment.left->u.local.upcount);
248263 break;
1515 n->value = v;
1616 n->next = *l;
1717 *l = n;
18 }
19
20 struct list *
21 list_dup(struct list *l)
22 {
23 struct list *n;
24
25 /* ... XXX ... */
26
27 return(n);
1828 }
1929
2030 void
99 struct value *value;
1010 };
1111
12 void list_cons(struct list **, struct value *);
13 void list_free(struct list **);
14 size_t list_length(struct list *);
15 int list_contains(struct list *, struct value *);
12 void list_cons(struct list **, struct value *);
13 struct list *list_dup(struct list *);
14 void list_free(struct list **);
15 size_t list_length(struct list *);
16 int list_contains(struct list *, struct value *);
1617
17 void list_dump(struct list *);
18 void list_dump(struct list *);
1819
1920 #endif /* !__LIST_H_ */
2525 int trace_closures = 0;
2626 int trace_vm = 0;
2727 int trace_gen = 0;
28 int trace_pool = 0;
2829
2930 int num_vars_created = 0;
3031 int num_vars_grabbed = 0;
3839 #endif
3940
4041 #ifdef DEBUG
41 #define OPTS "acfg:klmnoprstvxz"
42 #define OPTS "acdfg:klmnoprstvxz"
4243 #define RUN_PROGRAM run_program
4344 #else
4445 #define OPTS "g:x"
5859 #ifdef DEBUG
5960 fprintf(stderr, " -a: trace assignments\n");
6061 fprintf(stderr, " -c: trace calls\n");
62 fprintf(stderr, " -d: trace pooling\n");
6163 fprintf(stderr, " -f: trace frames\n");
6264 #endif
6365 fprintf(stderr, " -g int: set garbage collection threshold\n");
9092 for (i = 0; b[i].name != NULL; i++) {
9193 v = value_new_builtin(&b[i]);
9294 sym = symbol_define(stab, b[i].name, SYM_KIND_COMMAND, v);
93 sym->is_pure = b[i].purity;
95 sym->is_pure = b[i].is_pure;
9496 sym->builtin = &b[i];
9597 value_release(v);
9698 }
97
99
98100 /* XXX */
99101 v = value_new_string("\n");
100102 sym = symbol_define(stab, "EoL", SYM_KIND_VARIABLE, v);
116118 struct scan_st *sc;
117119 struct symbol_table *stab;
118120 struct ast *a;
119 struct value *v;
120121 char *source = NULL;
121122 int opt;
122123 int use_vm = 0;
151152 case 'c':
152153 trace_calls++;
153154 break;
155 case 'd':
156 trace_pool++;
157 break;
154158 case 'f':
155159 debug_frame++;
156160 break;
215219 gc_target = gc_trigger;
216220 if ((sc = scan_open(source)) != NULL) {
217221 stab = symbol_table_new(NULL, 0);
218 global_ar = activation_new(100, NULL, NULL);
219 activation_register(global_ar);
222 global_ar = activation_new_on_stack(100, NULL, NULL);
220223 load_builtins(stab, builtins);
221224 a = parse_program(sc, stab);
222225 scan_close(sc);
235238 unsigned char *program;
236239
237240 program = ast_gen(a);
241 /* ast_dump(a, 0); */
238242 if (RUN_PROGRAM) {
239243 vm_run(program);
240244 }
245 vm_release(program);
246 /*value_dump_global_table();*/
241247 #ifdef RECURSIVE_AST_EVALUATOR
242248 } else if (sc->errors == 0 && RUN_PROGRAM) {
243249 v = value_new_integer(76);
252258 #endif
253259 ast_free(a);
254260 activation_gc();
255 activation_free(global_ar);
261 activation_free_from_stack(global_ar);
256262 #ifdef DEBUG
257263 symbol_table_free(stab);
258264 if (trace_refcounting > 0) {
4242
4343 #include <sys/types.h>
4444
45 #ifdef DEBUG
45 /*#ifdef DEBUG
4646 void *bhuna_malloc(size_t);
4747 char *bhuna_strdup(char *);
4848 void bhuna_free(void *);
49 #else
49 #else*/
5050 #define bhuna_malloc(x) malloc(x)
5151 #define bhuna_strdup(x) strdup(x)
5252 #define bhuna_free(x) free(x)
53 #endif
53 /*#endif*/
5454
5555 #endif
+0
-367
src/misc/i_eval.c less more
0 #include <assert.h>
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 #include "ast.h"
6 #include "value.h"
7 #include "list.h"
8 #include "closure.h"
9 #include "activation.h"
10
11 #ifdef DEBUG
12 #include "symbol.h"
13
14 extern int trace_assignments;
15 extern int trace_calls;
16 extern int trace_ast;
17 extern int trace_closures;
18 #endif
19
20 extern struct activation *current_ar;
21
22 /*** UTILITY ***/
23
24 #define MOVE 0
25 #define QUERY 1
26
27 struct stack {
28 struct tree *t;
29 int state;
30 } s[256];
31 int sp = 0;
32
33 static void
34 push(struct ast *t, int state)
35 {
36 if (t == NULL) return;
37 s[sp].t = t;
38 s[sp].state = state;
39 sp++;
40 }
41
42 static void
43 pop(struct ast **t, int *state)
44 {
45 --sp;
46 *t = s[sp].t;
47 *state = s[sp].state;
48 }
49
50 /*** OPERATIONS ***/
51
52 /*
53 * Fill out an activation record with arguments.
54 * !!!!!!!!ar in here is part of the G.D. root set!!!!!!!!!!!
55 */
56 static void
57 ast_fillout(struct ast *a, struct activation *ar, int *idxp)
58 {
59 struct value *v = NULL;
60
61 if (a == NULL)
62 return;
63
64 switch (a->type) {
65 case AST_ARG:
66 ast_fillout(a->u.arg.left, ar, idxp);
67 ast_fillout(a->u.arg.right, ar, idxp);
68 break;
69 default:
70 ast_eval(a, &v);
71
72 activation_set_value(ar, (*idxp)++, 0, v);
73 value_release(v);
74 }
75 }
76
77 /*** EVALUATOR ***/
78
79 /*
80 * a is roughly analogous to the program counter (PC.)
81 *
82 * v is roughly analogous to the accumulator (A) or top of stack (ToS).
83 */
84 void
85 ast_eval(struct ast *a, struct value **v)
86 {
87 int state;
88
89 push(a, MOVE);
90
91 while (sp != 0) {
92 pop(&a, &state);
93 if (state == MOVE) {
94 switch (a->type) {
95 case AST_LOCAL:
96 case AST_VALUE:
97 case AST_SCOPE:
98 ast_eval(a->u.scope.body, v);
99 break;
100 case AST_APPLY:
101 ast_eval(a->u.apply.left, &l);
102 ast_eval(l->v.k->ast, v);
103 break;
104 case AST_ARG:
105 assert("this should never happen" == NULL);
106 /*value_set_list(v);
107 ast_flatten(a, v);*/
108 break;
109 case AST_STATEMENT:
110 push(a, QUERY);
111 push(a->u.statement.right, MOVE);
112 push(a->u.statement.left, MOVE);
113 break;
114 case AST_ASSIGNMENT:
115 ast_eval(a->u.assignment.right, v);
116 break;
117 case AST_CONDITIONAL:
118 ast_eval(a->u.conditional.test, &l);
119 ast_eval(a->u.conditional.yes, v);
120 ast_eval(a->u.conditional.no, v);
121 case AST_WHILE_LOOP:
122 ast_eval(a->u.while_loop.test, &l);
123 ast_eval(a->u.while_loop.body, v);
124 }
125
126 push(t, QUERY);
127 if (t->r != NULL) push(t->r, MOVE);
128 if (t->l != NULL) push(t->l, MOVE);
129 }
130 } else if (state == QUERY) {
131 printf(" %c", t->c);
132 }
133 }
134 }
135
136
137
138
139 void
140 ast_eval(struct ast *a, struct value **v)
141 {
142 struct value *l = NULL, *lv = NULL;
143 struct activation *new_ar = NULL, *old_ar = NULL;
144 int i;
145
146 if (a == NULL)
147 return;
148
149 #ifdef DEBUG
150 if (trace_ast) {
151 printf(">>> ENTERING %s[0x%08lx]\n", ast_name(a), (unsigned long)a);
152 }
153 #endif
154
155 switch (a->type) {
156 case AST_LOCAL:
157 /*
158 printf("index = %d, upcount = %d\n",
159 a->u.local.index, a->u.local.upcount);
160 activation_dump(current_ar, 0);
161 printf("\n");
162 */
163 lv = activation_get_value(current_ar,
164 a->u.local.index, a->u.local.upcount);
165 assert(lv != NULL);
166 value_set_from_value(v, lv);
167 /*value_release(lv);*/
168 break;
169 case AST_VALUE:
170 value_set_from_value(v, a->u.value.value);
171 if (*v != NULL && (*v)->type == VALUE_CLOSURE) {
172 #ifdef DEBUG
173 if (trace_closures) {
174 printf("Freshening ");
175 closure_dump((*v)->v.k);
176 printf(" with ");
177 activation_dump(current_ar, 1);
178 printf("\n");
179 }
180 #endif
181 /*activation_release((*v)->v.k->ar);
182 activation_grab(current_ar);*/
183 (*v)->v.k->ar = current_ar;
184 }
185 /*value_release(a->u.value.value);*/
186 break;
187 case AST_SCOPE:
188 /*
189 * pretty sure we don't need to do anything with the stab, here.
190 * although we may want to note somewhere that this is the
191 * most recently encountered stab.
192 */
193 ast_eval(a->u.scope.body, v);
194 break;
195 case AST_APPLY:
196 /*
197 * Get the function we're being asked to apply.
198 */
199 ast_eval(a->u.apply.left, &l);
200
201 /*
202 * Create a new activation record apropos to l.
203 * When l is a closure, include the closure's
204 * environment as the lexical link of the record.
205 */
206 assert(l->type == VALUE_BUILTIN || l->type == VALUE_CLOSURE);
207 old_ar = current_ar;
208 if (l->type == VALUE_BUILTIN) {
209 new_ar = activation_new(2, current_ar, NULL); /* haha */
210 } else if (l->type == VALUE_CLOSURE) {
211 assert(l->v.k->ast->type == AST_SCOPE);
212 /* value_print(l); */
213 new_ar = activation_new(
214 l->v.k->ast->u.scope.frame_size,
215 current_ar,
216 l->v.k->ar);
217 }
218 assert(current_ar == old_ar);
219
220 /*
221 * Now, fill out that activation record with the
222 * supplied arguments.
223 */
224 i = 0;
225 ast_fillout(a->u.apply.right, new_ar, &i);
226 /*printf(":: filled out %d\n", i);*/
227
228 #ifdef DEBUG
229 if (trace_calls) {
230 printf("---> call:");
231 value_print(l);
232 printf("(");
233 activation_dump(current_ar, 1);
234 printf(")\n");
235 }
236 #endif
237
238 if (l->type == VALUE_BUILTIN) {
239 struct value *g;
240 g = l->v.f(new_ar);
241 assert(current_ar == old_ar);
242 value_set_from_value(v, g);
243 value_release(g);
244 } else if (l->type == VALUE_CLOSURE) {
245 current_ar = new_ar;
246 ast_eval(l->v.k->ast, v);
247 assert(current_ar == new_ar);
248 assert(current_ar->caller == old_ar);
249 current_ar = current_ar->caller;
250 }
251
252 /*
253 * Indicate that we're not longer using ar and that
254 * the refcounter can deallocate it if it wants.
255 */
256 /*activation_release(current_ar);*/
257
258 /*
259 * Restore the environment of the symbols to what it was
260 * before the closure was evaluated.
261 */
262 /*
263 printf("Returning to caller:\n");
264 activation_dump(current_ar->prev, 1);
265 printf("\n");
266 */
267
268
269 /*
270 current_ar = old_ar;
271 */
272
273 #ifdef DEBUG
274 if (trace_calls) {
275 printf("<--- call done, retval=");
276 value_print(*v);
277 printf("\n");
278 }
279 #endif
280
281 value_release(l);
282 break;
283 case AST_ARG:
284 assert("this should never happen" == NULL);
285 /*value_set_list(v);
286 ast_flatten(a, v);*/
287 break;
288 case AST_STATEMENT:
289 ast_eval(a->u.statement.left, &l);
290 value_release(l);
291 ast_eval(a->u.statement.right, v);
292 break;
293 case AST_ASSIGNMENT:
294 ast_eval(a->u.assignment.right, v);
295 assert(a->u.assignment.left != NULL);
296 if (a->u.assignment.left->type == AST_LOCAL) {
297 activation_set_value(current_ar,
298 a->u.assignment.left->u.local.index,
299 a->u.assignment.left->u.local.upcount,
300 *v);
301 #ifdef DEBUG
302 if (trace_assignments) {
303 symbol_dump(a->u.assignment.left->u.local.sym, 1);
304 printf(":=");
305 value_print(*v);
306 printf("\n");
307 }
308 #endif
309 } else {
310 value_set_error(v, "bad lvalue");
311 }
312 break;
313 case AST_CONDITIONAL:
314 ast_eval(a->u.conditional.test, &l);
315 if (l == NULL || l->type != VALUE_BOOLEAN) {
316 value_set_error(v, "type mismatch");
317 } else {
318 if (l->v.b) {
319 ast_eval(a->u.conditional.yes, v);
320 } else if (a->u.conditional.no != NULL) {
321 ast_eval(a->u.conditional.no, v);
322 } else {
323 value_set_error(v, "missing else");
324 }
325 }
326 value_release(l);
327 break;
328 case AST_WHILE_LOOP:
329 for (;;) {
330 ast_eval(a->u.while_loop.test, &l);
331 if (l == NULL || l->type != VALUE_BOOLEAN) {
332 value_release(l);
333 value_set_error(v, "type mismatch");
334 break;
335 } else {
336 /*
337 printf("WHILE: test=");
338 value_print(l);
339 printf("\n");
340 */
341 if (!l->v.b) {
342 /*
343 * `while' condition evaluated to false.
344 */
345 value_release(l);
346 break;
347 }
348 ast_eval(a->u.while_loop.body, v);
349 /*
350 printf("WHILE: body=");
351 value_print(*v);
352 printf("\n");
353 */
354 }
355 }
356 break;
357 }
358
359 #ifdef DEBUG
360 if (trace_ast) {
361 printf("<<< LEAVING %s[0x%08lx] w/value=", ast_name(a), (unsigned long)a);
362 value_print(*v);
363 printf("\n");
364 }
365 #endif
366 }
+0
-99
src/misc/itree.c less more
0 #include <stdlib.h>
1 #include <stdio.h>
2
3 struct tree {
4 struct tree *l;
5 struct tree *r;
6 char c;
7 };
8
9 struct tree *
10 new_tree(struct tree *l, struct tree *r, char c)
11 {
12 struct tree *t;
13
14 t = malloc(sizeof(struct tree));
15 t->l = l;
16 t->r = r;
17 t->c = c;
18 return(t);
19 }
20
21 void
22 dump_tree_r(struct tree *t)
23 {
24 if (t == NULL) return;
25 dump_tree_r(t->l);
26 dump_tree_r(t->r);
27 printf(" %c", t->c);
28 }
29
30 /*-------------------------------------------*/
31
32 #define MOVE 0
33 #define QUERY 1
34
35 struct stack {
36 struct tree *t;
37 int state;
38 } s[256];
39 int sp = 0;
40
41 void
42 push(struct tree *t, int state)
43 {
44 s[sp].t = t;
45 s[sp].state = state;
46 sp++;
47 }
48
49 void
50 pop(struct tree **t, int *state)
51 {
52 --sp;
53 *t = s[sp].t;
54 *state = s[sp].state;
55 }
56
57 void
58 dump_tree_i(struct tree *arg)
59 {
60 struct tree *t;
61 int state;
62
63 push(arg, MOVE);
64
65 while (sp != 0) {
66 pop(&t, &state);
67 if (state == MOVE) {
68 push(t, QUERY);
69 if (t->r != NULL) {
70 push(t->r, MOVE);
71 }
72 if (t->l != NULL) {
73 push(t->l, MOVE);
74 }
75 } else if (state == QUERY) {
76 printf(" %c", t->c);
77 }
78 }
79 }
80
81 int main(int argc, char **argv)
82 {
83 struct tree *t;
84
85 t = new_tree(
86 new_tree(NULL, NULL, 'a'),
87 new_tree(
88 new_tree(NULL, NULL, '2'),
89 new_tree(NULL, NULL, '3'),
90 '+'),
91 '=');
92
93 dump_tree_r(t);
94 printf("\n");
95 dump_tree_i(t);
96 printf("\n");
97 return(0);
98 }
+0
-83
src/misc/pool.c less more
0 #include <assert.h>
1 #include <stdlib.h>
2 #include <stdio.h>
3
4 #include "pool.h"
5
6 static struct value_pool *current_vp = NULL;
7 static struct pooled_value *pv_free = NULL;
8
9 int trace_pool = 1;
10
11 void
12 value_pool_new(void)
13 {
14 struct value_pool *vp;
15 int i;
16
17 #ifdef DEBUG
18 if (trace_pool) {
19 printf("MAKING NEW POOL\n");
20 printf("value size = %4d\n", sizeof(struct value));
21 printf("pooled-value size = %4d\n", sizeof(struct pooled_value));
22 printf("page size = %4d\n", PAGE_SIZE);
23 printf("header size = %4d\n", HEADER_SIZE);
24 printf("value pool size = %4d\n", sizeof(struct value_pool));
25 printf("values per pool = %4d\n", VALUES_PER_POOL);
26 }
27 #endif
28 assert(sizeof(struct value_pool) <= PAGE_SIZE);
29 vp = malloc(PAGE_SIZE);
30
31 /*
32 * Link us up to the parent pool, if any.
33 */
34 vp->prev = current_vp;
35
36 /*
37 * Create an initial freelist within the pool,
38 * and link it into our global freelist pv_free.
39 */
40 vp->pool[0].pv.free = pv_free;
41 for (i = 1; i < VALUES_PER_POOL; i++)
42 vp->pool[i].pv.free = &vp->pool[i-1];
43 pv_free = &vp->pool[VALUES_PER_POOL - 1];
44
45 current_vp = vp;
46 }
47
48 struct value *
49 value_allocate(void)
50 {
51 struct value *r;
52
53 /*
54 * Check to see if this is the last remaining slot in the pool.
55 */
56 if (pv_free->pv.free == NULL) {
57 /*
58 * If so, create a new pool.
59 */
60 value_pool_new();
61 }
62 /*
63 * Find the next pooled value on the freelist,
64 * remove it from the freelist, and return it.
65 */
66 r = &(pv_free->pv.v);
67 pv_free = pv_free->pv.free;
68
69 /*printf("pool: allocate: next free now %08lx\n", pv_free);*/
70 return(r);
71 }
72
73 void
74 value_deallocate(struct value *v)
75 {
76 /*
77 * Tack this value back onto the freelist.
78 */
79 ((struct pooled_value *)v)->pv.free = pv_free;
80 pv_free = (struct pooled_value *)v;
81 printf("pool: deallocate: next free now %08lx\n", (unsigned long)pv_free);
82 }
+0
-22
src/misc/pool.h less more
0 #include "value.h"
1
2 struct pooled_value {
3 union {
4 struct value v;
5 struct pooled_value *free;
6 } pv;
7 };
8
9 #define PAGE_SIZE 16384
10 #define HEADER_SIZE sizeof(struct value_pool *)
11 #define VALUES_PER_POOL (PAGE_SIZE - HEADER_SIZE) / sizeof(struct pooled_value) - 1
12
13 struct value_pool {
14 struct value_pool * prev;
15 struct pooled_value pool[VALUES_PER_POOL];
16 };
17
18 void value_pool_new(void);
19
20 struct value *value_allocate(void);
21 void value_deallocate(struct value *);
5858 /* --- util --- */
5959
6060 /*
61 * Convenience function to create AST for a named function call on 2 arguments.
61 * Convenience function to create AST for a named arity-2 function call.
6262 */
6363 static struct ast *
64 ast_new_nfcall(char *name, struct symbol_table *stab, struct ast *a, struct ast *b)
64 ast_new_call2(char *name, struct symbol_table *stab,
65 struct ast *left, struct ast *right)
6566 {
6667 struct symbol *sym;
67 /*struct ast *l, *r = NULL;*/
68 struct ast *a;
69
70 left = ast_new_arg(left, NULL);
71 right = ast_new_arg(right, NULL);
72 left->u.arg.right = right;
6873
6974 sym = symbol_lookup(stab, name, VAR_GLOBAL);
70 assert(sym->builtin != NULL);
71 a = ast_new_builtin(a, b, sym->builtin);
72 /*
73 } else if (sym->value != NULL) {
74 r = ast_new_arg(a, b);
75 l = ast_new_value(sym->value);
76 a = ast_new_apply(l, r, sym->is_pure);
77 } else {
78 r = ast_new_arg(a, b);
79 l = ast_new_local(sym->index, stab->level - sym->in->level, sym);
80 a = ast_new_apply(l, r, sym->is_pure);
81 }
82 */
75 assert(sym != NULL && sym->builtin != NULL);
76 a = ast_new_builtin(sym->builtin, left);
77
78 return(a);
79 }
80
81 static struct ast *
82 ast_new_call3(char *name, struct symbol_table *stab,
83 struct ast *left, struct ast *index, struct ast *right)
84 {
85 struct symbol *sym;
86 struct ast *a;
87
88 left = ast_new_arg(left, NULL);
89 index = ast_new_arg(index, NULL);
90 right = ast_new_arg(right, NULL);
91 left->u.arg.right = index;
92 index->u.arg.right = right;
93
94 sym = symbol_lookup(stab, name, VAR_GLOBAL);
95 assert(sym != NULL && sym->builtin != NULL);
96 a = ast_new_builtin(sym->builtin, left);
97
8398 return(a);
8499 }
85100
89104 parse_program(struct scan_st *sc, struct symbol_table *stab)
90105 {
91106 struct ast *a = NULL;
92 int cc;
93
94 while (sc->type != TOKEN_EOF) {
107 int cc, retr = 0;
108
109 while (sc->type != TOKEN_EOF && !retr) {
95110 cc = 0;
96 a = ast_new_statement(a, parse_statement(sc, stab, &cc));
111 a = ast_new_statement(a, parse_statement(sc, stab, &retr, &cc));
97112 }
98113
99114 return(a);
108123 struct symbol_table **istab, int *cc)
109124 {
110125 struct ast *a = NULL;
111 /* struct value *v;
112 struct symbol *sym; */
126 int retr = 0;
113127
114128 assert(*istab != NULL);
115129
116130 if (tokeq(sc, "{")) {
117131 scan_expect(sc, "{");
118 while (tokne(sc, "}") && sc->type != TOKEN_EOF) {
119 a = ast_new_statement(a, parse_statement(sc, *istab, cc));
132 while (tokne(sc, "}") && sc->type != TOKEN_EOF && !retr) {
133 a = ast_new_statement(a,
134 parse_statement(sc, *istab, &retr, cc));
120135 }
121136 scan_expect(sc, "}");
122137 } else {
123 a = parse_statement(sc, *istab, cc);
138 a = parse_statement(sc, *istab, &retr, cc);
124139 }
125140
126141 /*
127 * For housekeeping, we place a reference to this symbol table
128 * in an anonymous symbol in the overlying symbol table.
142 * XXX
143 * For housekeeping, it would be nice to place a reference to this
144 * symbol table in the overlying symbol table, so that when it is
145 * dumped, this one is dumped too.
129146 */
130 /*
131 if (!symbol_table_is_empty(*istab) != NULL) {
132 sym = symbol_define(stab, NULL, SYM_KIND_ANONYMOUS);
133 v = value_new_symbol_table(*istab);
134 symbol_set_value(sym, v);
135 value_release(v);
136 }
137 */
138
139 return(a);
140 }
141
142 struct ast *
143 parse_statement(struct scan_st *sc, struct symbol_table *stab, int *cc)
147
148 return(a);
149 }
150
151 struct ast *
152 parse_statement(struct scan_st *sc, struct symbol_table *stab, int *retr, int *cc)
144153 {
145154 struct symbol_table *istab;
146 /*struct symbol *sym;*/
147155 struct ast *a, *l, *r;
148156
149157 if (tokeq(sc, "{")) {
151159 a = parse_block(sc, stab, &istab, cc);
152160 } else if (tokeq(sc, "if")) {
153161 scan(sc);
154 /*
155 * Create a temporary value for this test.
156 */
157 /*
158 sym = symbol_define(stab, NULL, SYM_KIND_ANONYMOUS, NULL);
159 */
160 a = parse_expr(sc, stab, 0, cc);
162 a = parse_expr(sc, stab, 0, NULL, cc);
161163 istab = symbol_table_new(stab, 0);
162164 l = parse_block(sc, stab, &istab, cc);
163165 if (tokeq(sc, "else")) {
167169 } else {
168170 r = NULL;
169171 }
170 /*
171 a = ast_new_conditional(a, l, r, sym->index);
172 */
173172 a = ast_new_conditional(a, l, r);
174173 } else if (tokeq(sc, "while")) {
175174 scan(sc);
176 l = parse_expr(sc, stab, 0, cc);
175 l = parse_expr(sc, stab, 0, NULL, cc);
177176 istab = symbol_table_new(stab, 0);
178177 r = parse_block(sc, stab, &istab, cc);
179178 a = ast_new_while_loop(l, r);
180179 } else if (tokeq(sc, "return")) {
181180 scan(sc);
182 a = parse_expr(sc, stab, 0, cc);
181 a = parse_expr(sc, stab, 0, NULL, cc);
183182 a = ast_new_retr(a);
183 *retr = 1;
184184 } else {
185185 int is_const = 0;
186 int is_assign = 0;
186 int is_def = 0;
187187
188188 while (tokeq(sc, "local") || tokeq(sc, "const")) {
189 is_assign = 1;
189 is_def = 1;
190190 if (tokeq(sc, "local")) {
191191 scan(sc);
192192 /* Not much, mere presence works. */
195195 is_const = 1;
196196 }
197197 }
198 if (is_assign || symbol_lookup(stab, sc->token, VAR_GLOBAL) == NULL) {
198 if (is_def || symbol_lookup(stab, sc->token, VAR_GLOBAL) == NULL) {
199199 /*
200 * Symbol doesn't exist at all - it MUST be
201 * an assignment, and it MUST be local.
200 * Symbol doesn't exist at all, so it
201 * must be a variable definition.
202202 */
203 a = parse_assignment(sc, stab, is_const, cc);
203 a = parse_definition(sc, stab, is_const, cc);
204204 } else {
205 a = parse_command(sc, stab, cc);
205 /*
206 * Symbol already exists, so it could be
207 * either a command or an assignment.
208 */
209 a = parse_command_or_assignment(sc, stab, cc);
206210 }
207211 }
208212 if (tokeq(sc, ";"))
211215 }
212216
213217 struct ast *
214 parse_assignment(struct scan_st *sc, struct symbol_table *stab, int is_const,
218 parse_definition(struct scan_st *sc, struct symbol_table *stab, int is_const,
215219 int *cc)
216220 {
217221 struct symbol *sym;
227231 l = parse_var(sc, stab, &sym, VAR_LOCAL, VAR_MUST_NOT_EXIST, v);
228232 value_release(v);
229233 scan_expect(sc, "=");
230 r = parse_expr(sc, stab, 0, cc);
234 r = parse_expr(sc, stab, 0, sym, cc);
231235 if (is_const) {
232 if (!ast_is_constant(r)) {
236 if (r == NULL || r->type != AST_VALUE) {
233237 scan_error(sc, "Expression must be constant");
234238 } else {
235 /* XXX CONSTANT FOLDING PLEASE */
236 /*
237 ast_eval(r, &v);
238 printf("Constant value = ");
239 value_print(v);
240 printf("\n");
241 symbol_set_value(sym, v);
242
239 symbol_set_value(sym, r->u.value.value);
243240 ast_free(l);
244241 ast_free(r);
245 */
246242 }
247243 return(NULL);
248244 } else {
251247 }
252248
253249 struct ast *
254 parse_command(struct scan_st *sc, struct symbol_table *stab,
255 int *cc)
250 parse_command_or_assignment(struct scan_st *sc, struct symbol_table *stab,
251 int *cc)
256252 {
257253 struct symbol *sym;
258254 struct ast *a, *l, *r, *z;
259255
260256 a = parse_var(sc, stab, &sym, VAR_GLOBAL, VAR_MUST_EXIST, NULL);
257
258 /*
259 * A[I] = J -> Store A, I, J
260 * A[A[I]] = J -> Store A, A[I], J
261 * A[I][J] = K -> Store A[I], J, K
262 * A[I][J][K] = L -> Store A[I][J], K, L
263 */
264 while (tokeq(sc, "[") || tokeq(sc, ".")) {
265 if (tokeq(sc, "[")) {
266 scan(sc);
267 l = parse_expr(sc, stab, 0, NULL, cc);
268 scan_expect(sc, "]");
269 if (tokeq(sc, "=")) {
270 /*
271 * It was the last one; this is an assigment.
272 */
273 scan(sc);
274 r = parse_expr(sc, stab, 0, NULL, cc);
275 a = ast_new_call3("Store", stab, a, l, r);
276 return(a);
277 } else if (tokne(sc, "[") && tokne(sc, ".")) {
278 /*
279 * It was the last one; this is a command.
280 */
281 /* ... */
282 } else {
283 /*
284 * Still more to go.
285 */
286 a = ast_new_call2("Fetch", stab, a, l);
287 }
288 } else if (tokeq(sc, ".")) {
289 scan(sc);
290 r = parse_literal(sc, stab);
291 a = ast_new_call2("Fetch", stab, a, r);
292 }
293 }
294
295 /*
296 * If the variable-expression was followed by an equals sign,
297 * it's an assignment to an already-existing variable.
298 */
261299 if (tokeq(sc, "=")) {
262 /*
263 * Actually... it's an assignment to an already-existing variable.
264 */
265300 if (sym->value != NULL) {
266301 scan_error(sc, "Value not modifiable");
267302 } else {
268303 scan(sc);
269 r = parse_expr(sc, stab, 0, cc);
304 r = parse_expr(sc, stab, 0, NULL, cc);
270305 a = ast_new_assignment(a, r);
271306 }
272307 return(a);
273308 }
274309
310 /*
311 * Otherwise, it's a command.
312 */
313 if (tokne(sc, "}") && tokne(sc, ";") && sc->type != TOKEN_EOF) {
314 l = parse_expr(sc, stab, 0, NULL, cc);
315 l = ast_new_arg(l, NULL);
316 z = l;
317 while (tokeq(sc, ",")) {
318 scan_expect(sc, ",");
319 r = parse_expr(sc, stab, 0, NULL, cc);
320 r = ast_new_arg(r, NULL);
321 z->u.arg.right = r;
322 z = r;
323 }
324 } else {
325 l = NULL;
326 }
275327 if (sym->builtin != NULL) {
276 l = NULL; r = NULL;
277 if (tokne(sc, "}") && tokne(sc, ";") && sc->type != TOKEN_EOF) {
278 l = parse_expr(sc, stab, 0, cc);
279 if (tokeq(sc, ",")) {
280 scan_expect(sc, ",");
281 r = parse_expr(sc, stab, 0, cc);
282 }
283 }
284 a = ast_new_builtin(l, r, sym->builtin);
285 } else {
286 if (tokne(sc, "}") && tokne(sc, ";") && sc->type != TOKEN_EOF) {
287 l = parse_expr(sc, stab, 0, cc);
288 l = ast_new_arg(l, NULL);
289 z = l;
290 while (tokeq(sc, ",")) {
291 scan_expect(sc, ",");
292 r = parse_expr(sc, stab, 0, cc);
293 r = ast_new_arg(r, NULL);
294 z->u.arg.right = r;
295 z = r;
296 }
297 } else {
298 l = NULL;
299 }
328 a = ast_new_builtin(sym->builtin, l);
329 } else {
300330 a = ast_new_apply(a, l, 0);
301331 }
302332
316346
317347 struct ast *
318348 parse_expr(struct scan_st *sc, struct symbol_table *stab, int level,
319 int *cc)
349 struct symbol *excl, int *cc)
320350 {
321351 struct ast *l, *r;
322352 int done = 0, i = 0;
323353 char the_op[256];
324354
325355 if (level > maxlevel) {
326 l = parse_primitive(sc, stab, cc);
356 l = parse_primitive(sc, stab, excl, cc);
327357 return(l);
328358 } else {
329 l = parse_expr(sc, stab, level + 1, cc);
359 l = parse_expr(sc, stab, level + 1, excl, cc);
330360 while (!done) {
331361 done = 1;
332362 for (i = 0; i < 6 && op[level][i][0] != '\0'; i++) {
334364 strlcpy(the_op, sc->token, 256);
335365 scan(sc);
336366 done = 0;
337 r = parse_expr(sc, stab, level + 1, cc);
338 l = ast_new_nfcall(the_op, stab, l, r);
367 r = parse_expr(sc, stab, level + 1, excl, cc);
368 l = ast_new_call2(the_op, stab, l, r);
339369 break;
340370 }
341371 }
345375 }
346376
347377 struct ast *
348 parse_primitive(struct scan_st *sc, struct symbol_table *stab, int *cc)
378 parse_primitive(struct scan_st *sc, struct symbol_table *stab,
379 struct symbol *excl, int *cc)
349380 {
350381 struct ast *a, *l, *r, *z;
351382 struct value *v;
354385
355386 if (tokeq(sc, "(")) {
356387 scan(sc);
357 a = parse_expr(sc, stab, 0, cc);
388 a = parse_expr(sc, stab, 0, excl, cc);
358389 scan_expect(sc, ")");
359390 } else if (tokeq(sc, "^")) {
360391 int my_cc = 0;
392 int my_arity = 0;
361393
362394 /*
363395 * Enclosing block contains a closure:
369401 a = parse_var(sc, istab, &sym,
370402 VAR_LOCAL, VAR_MUST_NOT_EXIST, NULL);
371403 ast_free(a);
404 my_arity++;
372405 if (tokeq(sc, ","))
373406 scan(sc);
374407 }
375408 a = parse_block(sc, stab, &istab, &my_cc);
376 v = value_new_closure(a, NULL, symbol_table_size(istab), my_cc);
409 a = ast_new_routine(my_arity, symbol_table_size(istab) - my_arity, my_cc, a);
410 v = value_new_closure(a, NULL);
377411 a = ast_new_value(v);
378412 value_release(v);
379413 } else if (tokeq(sc, "!")) {
380414 scan(sc);
381 a = parse_primitive(sc, stab, cc);
415 a = parse_primitive(sc, stab, excl, cc);
382416 sym = symbol_lookup(stab, "!", 1);
383417 a = ast_new_apply(ast_new_local(
384418 sym->index,
390424 a = ast_new_value(v);
391425 value_release(v);
392426 if (tokne(sc, "]")) {
393 r = parse_expr(sc, stab, 0, cc);
394 a = ast_new_nfcall("Cons", stab, a, r);
427 ast_free(a);
428 l = parse_expr(sc, stab, 0, excl, cc);
429 r = ast_new_arg(l, NULL);
430 z = r;
395431 while (tokeq(sc, ",")) {
396432 scan(sc);
397 r = parse_expr(sc, stab, 0, cc);
398 a = ast_new_nfcall("Cons", stab, a, r);
433 l = parse_expr(sc, stab, 0, excl, cc);
434 l = ast_new_arg(l, NULL);
435 z->u.arg.right = l;
436 z = l;
399437 }
438 sym = symbol_lookup(stab, "List", VAR_GLOBAL);
439 assert(sym->builtin != NULL);
440 a = ast_new_builtin(sym->builtin, r);
400441 }
401442 scan_expect(sc, "]");
402443 } else if (sc->type == TOKEN_BAREWORD && isupper(sc->token[0])) {
403444 a = parse_var(sc, stab, &sym, VAR_GLOBAL, VAR_MUST_EXIST, NULL);
445 if (sym == excl) {
446 scan_error(sc, "Initializer cannot refer to variable being defined");
447 return(NULL);
448 }
404449 while (tokeq(sc, "(") || tokeq(sc, "[") || tokeq(sc, ".")) {
405450 if (tokeq(sc, "(")) {
406451 scan(sc);
407452 if (tokne(sc, ")")) {
408 l = parse_expr(sc, stab, 0, cc);
453 l = parse_expr(sc, stab, 0, excl, cc);
409454 l = ast_new_arg(l, NULL);
410455 z = l;
411456 while (tokeq(sc, ",")) {
412457 scan(sc);
413 r = parse_expr(sc, stab, 0, cc);
458 r = parse_expr(sc, stab, 0, excl, cc);
414459 r = ast_new_arg(r, NULL);
415460 z->u.arg.right = r;
416461 z = r;
419464 l = NULL;
420465 }
421466 scan_expect(sc, ")");
422 a = ast_new_apply(a, l, sym->is_pure);
467 if (sym->builtin != NULL) {
468 a = ast_new_builtin(sym->builtin, l);
469 } else {
470 a = ast_new_apply(a, l, sym->is_pure);
471 }
423472 } else if (tokeq(sc, "[")) {
424473 scan(sc);
425 r = parse_expr(sc, stab, 0, cc);
474 r = parse_expr(sc, stab, 0, excl, cc);
426475 scan_expect(sc, "]");
427 a = ast_new_nfcall("Index", stab, a, r);
476 a = ast_new_call2("Fetch", stab, a, r);
428477 } else if (tokeq(sc, ".")) {
429478 scan(sc);
430479 r = parse_literal(sc, stab);
431 a = ast_new_nfcall("Index", stab, a, r);
480 a = ast_new_call2("Fetch", stab, a, r);
432481 }
433482 }
434483 } else {
1616 struct ast *parse_block(struct scan_st *, struct symbol_table *,
1717 struct symbol_table **, int *);
1818 struct ast *parse_statement(struct scan_st *, struct symbol_table *,
19 int *, int *);
20 struct ast *parse_definition(struct scan_st *, struct symbol_table *, int,
1921 int *);
20 struct ast *parse_assignment(struct scan_st *, struct symbol_table *, int,
21 int *);
22 struct ast *parse_command(struct scan_st *, struct symbol_table *,
22 struct ast *parse_command_or_assignment(struct scan_st *, struct symbol_table *,
2323 int *);
2424 struct ast *parse_expr(struct scan_st *, struct symbol_table *, int,
25 int *);
25 struct symbol *, int *);
2626 struct ast *parse_primitive(struct scan_st *, struct symbol_table *,
27 int *);
27 struct symbol *, int *);
2828 /*struct ast *parse_list_elem(struct scan_st *, struct symbol_table *);*/
2929 struct ast *parse_literal(struct scan_st *, struct symbol_table *);
3030 struct ast *parse_var(struct scan_st *, struct symbol_table *,
0 #include <assert.h>
1 #include <stdlib.h>
2 #include <stdio.h>
3
4 #include "pool.h"
5
6 static struct value_pool *current_vp = NULL;
7 static struct pooled_value *pv_free = NULL;
8
9 extern int trace_pool;
10
11 void
12 value_pool_new(void)
13 {
14 struct value_pool *vp;
15 int i;
16
17 #ifdef DEBUG
18 if (trace_pool > 0) {
19 printf("MAKING NEW POOL\n");
20 printf("value size = %4d\n", sizeof(struct value));
21 printf("pooled-value size = %4d\n", sizeof(struct pooled_value));
22 printf("page size = %4d\n", PAGE_SIZE);
23 printf("header size = %4d\n", HEADER_SIZE);
24 printf("value pool size = %4d\n", sizeof(struct value_pool));
25 printf("values per pool = %4d\n", VALUES_PER_POOL);
26 }
27 #endif
28 assert(sizeof(struct value_pool) <= PAGE_SIZE);
29 vp = malloc(PAGE_SIZE);
30
31 /*
32 * Link us up to the parent pool, if any.
33 */
34 vp->prev = current_vp;
35
36 /*
37 * Create an initial freelist within the pool,
38 * and link it into our global freelist pv_free.
39 */
40 vp->pool[0].pv.free = pv_free;
41 for (i = 1; i < VALUES_PER_POOL; i++)
42 vp->pool[i].pv.free = &vp->pool[i-1];
43 pv_free = &vp->pool[VALUES_PER_POOL - 1];
44
45 current_vp = vp;
46 }
47
48 struct value *
49 value_allocate(void)
50 {
51 struct value *r;
52
53 /*
54 * Check to see if this is the last remaining slot in the pool.
55 */
56 if (pv_free->pv.free == NULL) {
57 /*
58 * If so, create a new pool.
59 */
60 value_pool_new();
61 }
62 /*
63 * Find the next pooled value on the freelist,
64 * remove it from the freelist, and return it.
65 */
66 r = &(pv_free->pv.v);
67 pv_free = pv_free->pv.free;
68
69 #ifdef DEBUG
70 if (trace_pool > 1) {
71 printf("pool: allocate: next free now %08lx\n",
72 (unsigned long)pv_free);
73 }
74 #endif
75 return(r);
76 }
77
78 void
79 value_deallocate(struct value *v)
80 {
81 /*
82 * Tack this value back onto the freelist.
83 */
84 ((struct pooled_value *)v)->pv.free = pv_free;
85 pv_free = (struct pooled_value *)v;
86 #ifdef DEBUG
87 if (trace_pool > 1) {
88 printf("pool: deallocate: next free now %08lx\n",
89 (unsigned long)pv_free);
90 }
91 #endif
92 }
0 #include "value.h"
1
2 struct pooled_value {
3 union {
4 struct value v;
5 struct pooled_value *free;
6 } pv;
7 };
8
9 #define PAGE_SIZE 16384
10 #define HEADER_SIZE sizeof(struct value_pool *)
11 #define VALUES_PER_POOL (PAGE_SIZE - HEADER_SIZE) / sizeof(struct pooled_value) - 1
12
13 struct value_pool {
14 struct value_pool * prev;
15 struct pooled_value pool[VALUES_PER_POOL];
16 };
17
18 void value_pool_new(void);
19
20 struct value *value_allocate(void);
21 void value_deallocate(struct value *);
126126 #else
127127 v = bhuna_malloc(sizeof(struct value));
128128 #endif
129 bzero(v, sizeof(struct value));
129 /* bzero(v, sizeof(struct value)); */
130130 v->type = type;
131131 v->refcount = 1;
132132
143143 /*** UNCONDITIONAL DUPLICATOR ***/
144144
145145 /*
146 * Returns a copy of the given value.
147 * The copy is not so 'deep' as it could be, but should be OK w/refcounting.
146 * Returns a deep(-ish) copy of the given value.
148147 * New strings (char arrays) are created when copying a string;
149148 * New list spines (struct list *) are created, but values are only grabbed, not dup'ed.
150149 * Some things are not copied, only the pointers to them.
151150 *
152151 * Note that the dup'ed value is 'new', i.e. it has a refcount of 1.
153152 */
154 static struct value *
153 struct value *
155154 value_dup(struct value *v)
156155 {
157156 struct value *n; /* *z; */
170169 for (l = v->v.l; l != NULL; l = l->next) {
171170 value_list_append(&n, l->value);
172171 }
172 /*
173 n = value_new(VALUE_LIST);
174 n->v.l = list_dup(v->v.l);
175 */
173176 return(n);
174177 case VALUE_ERROR:
175178 return(value_new_error(v->v.e));
177180 return(value_new_builtin(v->v.bi));
178181 case VALUE_CLOSURE:
179182 /* XXX depth?? */
180 return(value_new_closure(v->v.k->ast, v->v.k->ar,
181 v->v.k->arity, v->v.k->cc));
183 return(value_new_closure(v->v.k->ast, v->v.k->ar));
182184 case VALUE_DICT:
183 n = value_new_dict();
184 /* XXX for each key in v->v.d, insert into n */
185 n = value_new(VALUE_DICT);
186 n->v.d = dict_dup(v->v.d);
185187 return(n);
186188 default:
187189 return(value_new_error("unknown type"));
289291 {
290292 if (v == NULL)
291293 return;
294 #ifdef DEBUG
295 if (trace_refcounting > 1) {
296 printf("[RC] grabbing ");
297 value_print(v);
298 printf(", refcount now %d\n", v->refcount + 1);
299 }
300 num_vars_grabbed++;
301 #endif
292302 assert(v->refcount > 0);
293303 v->refcount++;
304 }
305
306 void
307 value_release(struct value *v)
308 {
309 if (v == NULL)
310 return;
294311 #ifdef DEBUG
295312 if (trace_refcounting > 1) {
296 printf("[RC] grabbed ");
297 value_print(v);
298 printf(", refcount now %d\n", v->refcount);
299 }
300 num_vars_grabbed++;
301 #endif
302 }
303
304 void
305 value_release(struct value *v)
306 {
307 if (v == NULL)
308 return;
313 printf("[RC] releasing ");
314 value_print(v);
315 printf(", refcount now %d\n", v->refcount - 1);
316 }
317 num_vars_released++;
318 #endif
309319 assert(v->refcount > 0);
310320 v->refcount--;
311 #ifdef DEBUG
312 if (trace_refcounting > 1) {
313 printf("[RC] released ");
314 value_print(v);
315 printf(", refcount now %d\n", v->refcount);
316 }
317 num_vars_released++;
318 #endif
319321 if (v->refcount == 0)
320322 value_free(v);
321323 }
456458 }
457459
458460 struct value *
459 value_new_closure(struct ast *a, struct activation *ar, int arity, int cc)
461 value_new_closure(struct ast *a, struct activation *ar)
460462 {
461463 struct value *v;
462464
463465 v = value_new(VALUE_CLOSURE);
464 v->v.k = closure_new(a, ar, arity, cc);
466 v->v.k = closure_new(a, ar);
465467
466468 #ifdef DEBUG
467469 if (trace_valloc > 1) {
603605 }
604606
605607 void
606 value_set_closure(struct value **v, struct ast *a, struct activation *ar,
607 int arity, int cc)
608 {
609 if (*v == NULL) {
610 *v = value_new_closure(a, ar, arity, cc);
608 value_set_closure(struct value **v, struct ast *a, struct activation *ar)
609 {
610 if (*v == NULL) {
611 *v = value_new_closure(a, ar);
611612 return;
612613 }
613614
615616 value_empty(*v);
616617
617618 (*v)->type = VALUE_CLOSURE;
618 (*v)->v.k = closure_new(a, ar, arity, cc);
619 (*v)->v.k = closure_new(a, ar);
619620 }
620621
621622 void
5353 void value_grab(struct value *);
5454 void value_release(struct value *);
5555
56 struct value *value_dup(struct value *);
57
5658 struct value *value_new_integer(int);
5759 struct value *value_new_boolean(int);
5860 struct value *value_new_atom(int);
6062 struct value *value_new_list(void);
6163 struct value *value_new_error(char *);
6264 struct value *value_new_builtin(struct builtin *);
63 struct value *value_new_closure(struct ast *, struct activation *, int, int);
65 struct value *value_new_closure(struct ast *, struct activation *);
6466 struct value *value_new_dict(void);
6567
6668 void value_set_from_value(struct value **, struct value *);
7274 void value_set_list(struct value **);
7375 void value_set_error(struct value **, char *);
7476 void value_set_builtin(struct value **, struct builtin *);
75 void value_set_closure(struct value **, struct ast *, struct activation *, int, int);
77 void value_set_closure(struct value **, struct ast *, struct activation *);
7678 void value_set_dict(struct value **);
7779
7880 void value_list_append(struct value **, struct value *);
+0
-25
src/vm/ulti_vm.h less more
0 #include <sys/types.h>
1
2 struct value;
3
4 struct vm {
5 void (*pc)(struct vm *);
6 struct value **stack;
7 void (**prog)(struct vm *);
8 int ctr;
9 }
10
11
12 struct vm *vm_new(size_t, size_t);
13 void vm_free(struct vm *);
14 void vm_run(struct vm *);
15
16 void vm_gen(struct vm *, void (*)(struct vm *));
17
18 void op_local(struct vm *);
19 void op_value(struct vm *);
20 void op_apply(struct vm *);
21 void op_assign(struct vm *);
22 void op_jz(struct vm *);
23 void op_jmp(struct vm *);
24 void op_halt(struct vm *);
+0
-87
src/vm/util_vm.c less more
0 #include "mem.h"
1 #include "vm.h"
2
3 struct vm {
4 size_t pc;
5 value **stack;
6 void (**f)(struct vm *);
7 }
8
9
10 struct vm *
11 vm_new(size_t prog_size, size_t stack_size)
12 {
13 struct vm *vm;
14
15 vm = bhuna_malloc(sizeof(struct vm));
16 vm->prog = bhuna_malloc(void (*)(struct vm *) * stack_size);
17 vm->stack = bhuna_malloc(sizeof(struct value *) * stack_size);
18 vm->pc = vm->prog[0];
19 vm->ctr = 0;
20
21 return(vm);
22 }
23
24 void
25 vm_free(struct vm *vm)
26 {
27 bhuna_free(vm->prog);
28 bhuna_free(vm->stack);
29 bhuna_free(vm);
30 }
31
32 void
33 vm_run(struct vm *vm)
34 {
35 while (vm->pc != op_halt) {
36 vm->pc++;
37 }
38 }
39
40 void
41 vm_gen(struct vm *vm, void (*ins)(struct vm *))
42 {
43 vm->prog[vm->cnt++] = ins;
44 }
45
46 void op_local(struct vm *);
47 void op_value(struct vm *);
48
49 void
50 op_apply(struct vm *vm)
51 {
52 struct closure *k;
53 struct activation *ar;
54 struct value *v;
55
56 vm_pop(k);
57 vm_pop(ar);
58 v = f(ar);
59 vm_push(v);
60 }
61
62 void
63 op_assign(struct vm *vm)
64 {
65 vm_pop(v);
66 vm_pop(local);
67 local_poke(local, v);
68 }
69
70 void
71 op_jz(struct vm *vm)
72 {
73 }
74
75 void
76 op_jmp(struct vm *vm)
77 {
78 vm_pop(k);
79 vm->pc = vm->prog[k];
80 }
81
82 void
83 op_halt(struct vm *vm)
84 {
85 /* n/a */
86 }
+0
-119
src/vm/vm.c less more
0 #include "mem.h"
1 #include "vm.h"
2
3 struct vm *
4 vm_new(size_t prog_size, size_t stack_size)
5 {
6 struct vm *vm;
7
8 vm = bhuna_malloc(sizeof(struct vm));
9 vm->pc = 0;
10 vm->sp = 0;
11 vm->prog = bhuna_malloc(sizeof(struct op) * stack_size);
12 vm->stack = bhuna_malloc(sizeof(struct value *) * stack_size);
13
14 return(vm);
15 }