code.c 6.75 KB
Newer Older
1
2
#include <stdio.h>
#include <stdlib.h>
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
3
#include <stdbool.h>
4

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
5
#include "debug.h"
6
#include "code.h"
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
7
#include "mem.h"
8
9
#include "desc.h"

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
10
void exec(Code* expr, int frame_ptr, int root_frame_ptr, Thunk* target, bool force)
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
11
{
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
12
13
    assert(expr != NULL);

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
14
15
    while(1)
    {
16
17
        assert(stack_top_a < STACK_SIZE_A);
        
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
18
19
        switch (expr->type) {
        case CT_LIT:
20
21
            set_return(root_frame_ptr, updateT(target, &((LitEntry*) expr)->thunk));
            destroy_stack_frame(root_frame_ptr);
22
            return;
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
23
24
        case CT_VAR:
            if (expr->local_type == VAR_LOCAL) {
25
                Thunk* thunk = forward_to(target, local(frame_ptr, ((VarEntry*) expr)->index));
26
27
28
29
30
31
                
                // Destroy stack frame before eval, it is not needed any more
                // Greatly reduces stack usage
                destroy_stack_frame(root_frame_ptr);                        
                
                // TODO: inline eval
32
                if(force) thunk = eval(thunk);
33
34
                
                set_return(root_frame_ptr, thunk);
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
35
36
                return;
            }else{
37
38
39
                // Safe to destroy, the next call has no arguments
                destroy_stack_frame(root_frame_ptr);
                
40
41
                Desc* slice = get_slice(((VarEntry*) expr)->f, 0);
                
42
                if(force && slice->type == FT_FUN)
43
44
45
46
47
                {
                    expr = ((FunEntry*)slice)->body;
                    continue;
                }
                else
48
                {                    
49
                    set_return(root_frame_ptr, updateF(target, slice));
50
51
                    return;
                }
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
52
            }
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
53
        case CT_APP:
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
54
        {
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
55
56
            // TODO: check over application
            // TODO: enforce strictness in ADT/Record
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
57

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
58
            VarEntry* var = &((AppEntry*) expr)->var;
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
59

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
60
61
            if (var->base.local_type == VAR_LOCAL) 
            {
62
63
                // TODO: force
                
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
64
                Thunk* basethunk = eval(local(frame_ptr, var->index));
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
65

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
66
67
68
                Desc* slice =
                        get_slice(basethunk->desc->type == FT_SLICE ?
                                  ((SliceEntry*) basethunk->desc)->forward_ptr : basethunk->desc, basethunk->desc->arity + expr->nr_args);
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
69

70
                Thunk* thunk = updateF(target, slice);
71

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
72
                assert(thunk->desc->arity == basethunk->desc->arity + expr->nr_args);            
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
73

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
74
75
76
                for (int i = 0; i < basethunk->desc->arity; i++) {
                    thunk->_args[i] = basethunk->_args[i];
                }
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
77
78

                for (int i = 0; i < expr->nr_args; i++) {
79
                    push_a(NULL);
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
80
81
                    exec(((AppEntry*) expr)->args[i], frame_ptr, stack_top_a, NULL, false);
                    thunk->_args[basethunk->desc->arity + i] = pop_a();
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
82
                }
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
83

84
85
                set_return(root_frame_ptr, thunk);
                destroy_stack_frame(root_frame_ptr);
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
86
                return;
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
87
            }
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
88
89
90
            else
            {
                Desc* slice = get_slice(var->f, expr->nr_args);
91
                
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
92
93
94
95
                if (force && slice->type == FT_PRIM) {
                    Thunk args[expr->nr_args];

                    for (int i = 0; i < expr->nr_args; i++) {
96
                        push_a(&args[i]);                        
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
97
98
99
                        exec(((AppEntry*) expr)->args[i], frame_ptr, stack_top_a, &args[i], true);
                    }

100
                    set_return(root_frame_ptr, 
101
                            ((PrimEntry*) slice)->exec(target));
102
                    destroy_stack_frame(root_frame_ptr);
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
103
104
105
                    return;
                }
                else if (force && slice->type == FT_FUN) {
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
106

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
107
                    int new_frame_ptr = stack_top_a;
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
108

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
109
                    for (int i = 0; i < expr->nr_args; i++) {
110
                        push_a(NULL);
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
111
112
                        exec(((AppEntry*) expr)->args[i], frame_ptr, stack_top_a, NULL, is_strict_fun_arg((FunEntry*) slice, i));
                    }
113
                    
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
114
115
116
117
118
                    expr = ((FunEntry*) slice)->body;
                    frame_ptr = new_frame_ptr;
                    continue;
                }
                else {
119
                    Thunk* thunk = updateF(target, slice);
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
120
121
122
123

                    assert(thunk->desc->arity == expr->nr_args);

                    for (int i = 0; i < expr->nr_args; i++) {
124
                        push_a(NULL);
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
125
126
127
128
                        exec(((AppEntry*) expr)->args[i], frame_ptr, stack_top_a, NULL, false);
                        thunk->_args[i] = pop_a();
                    }
                    
129
130
                    set_return(root_frame_ptr, thunk);
                    destroy_stack_frame(root_frame_ptr);
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
131
                    return;                    
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
132
                }
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
133
134
            }
            break;
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
135
        }
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
136
137
        case CT_SELECT:
        {
138
            push_a(NULL);
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
139
140
            exec(((SelectEntry*) expr)->expr, frame_ptr, stack_top_a, NULL, true);
            Thunk* pattern = eval(pop_a());
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
141

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
142
143
144
145
146
            bool handled = false;
            
            for (int i = 0; i < expr->nr_cases; i++) {
                SelectCaseEntry* caseEntry = &((SelectEntry*) expr)->cases[i];

147
148
                assert(pattern->desc->type == FT_ADT);
                
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
149
150
151
152
153
154
155
                if (caseEntry->type == SC_CONS) {
                    // Pattern match
                    if ((Desc*) caseEntry->cons != pattern->desc) continue;

                    // Put the constructor arguments to the stack if matches
                    for (int i = 0; i < pattern->desc->arity; i++) {
                        push_a(pattern->_args[i]);
156
                    }                  
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
157
158
159
160
161
162
163
164
165
166
                }
                else if (caseEntry->type == SC_LIT) {
                    printf("Exec: Unhandled entry type in CT_SELECT (SC_LIT)");
                    exit(-1);
                }
                
                // must be SC_DEFAULT now
                handled = true;
                expr = caseEntry->body;
                break;
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
167
168
            }

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
169
170
171
172
173
174
175
176
177
178
            if(handled) continue;
            
            printf("Exec: no select cases matches");
            print(pattern, false);
            exit(-1);
        }
        case CT_IF:
        {        
            Thunk tmp;
            tmp.desc = (Desc*) __BOOL__;
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
179

180
            push_a(&tmp);
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
181
182
            exec(((IfEntry*) expr)->cond, frame_ptr, stack_top_a, &tmp, true);
            Thunk* cond = eval(pop_a());
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
183

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
184
185
186
187
188
189
190
191
            if (readB(cond)) {
                expr = ((IfEntry*) expr)->texpr;
                continue;                
            }
            else {
                expr = ((IfEntry*) expr)->fexpr;
                continue;     
            }
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
192
        }
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
193
194
195
        default:
            printf("Exec: Unhandled CODE type");
            exit(-1);
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
196
        }
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
197
    
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
198
    }
199
}