code.c 5.98 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
16
17
    while(1)
    {
        switch (expr->type) {
        case CT_LIT:
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
18
            stack_top_a = root_frame_ptr; 
19
20
            push_a(updateT(target, &((LitEntry*) expr)->thunk));
            return;
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
21
22
        case CT_VAR:
            stack_top_a = root_frame_ptr;     
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
23
            
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
24
            if (expr->local_type == VAR_LOCAL) {
25
26
                Thunk* thunk = forward_to(target, local(frame_ptr, ((VarEntry*) expr)->index));
                if(force) push_a(eval(thunk)); else push_a(thunk);
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
27
28
                return;
            }else{
29
30
31
32
33
34
35
36
37
38
39
40
                Desc* slice = get_slice(((VarEntry*) expr)->f, 0);
                
                if(force &&  slice->type == FT_FUN)
                {
                    expr = ((FunEntry*)slice)->body;
                    continue;
                }
                else
                {
                    push_a(updateF(target, get_slice(((VarEntry*) expr)->f, 0)));
                    return;
                }
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
41
            }
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
42
        case CT_APP:
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
43
        {
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
44
45
            // TODO: check over application
            // TODO: enforce strictness in ADT/Record
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
46

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
47
            VarEntry* var = &((AppEntry*) expr)->var;
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
48
            Thunk* thunk;
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
49

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
50
51
52
            if (var->base.local_type == VAR_LOCAL) 
            {
                Thunk* basethunk = eval(local(frame_ptr, var->index));
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
53

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
54
55
56
                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
57

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
58
                thunk = updateF(target, slice);
59

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

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
62
63
64
                for (int i = 0; i < basethunk->desc->arity; i++) {
                    thunk->_args[i] = basethunk->_args[i];
                }
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
65
66

                for (int i = 0; i < expr->nr_args; i++) {
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
67
68
                    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
69
                }
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
70
71
72
73

                stack_top_a = root_frame_ptr;
                push_a(thunk);
                return;
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
74
            }
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
            else
            {
                Desc* slice = get_slice(var->f, expr->nr_args);

                if (force && slice->type == FT_PRIM) {
                    Thunk args[expr->nr_args];

                    for (int i = 0; i < expr->nr_args; i++) {
                        exec(((AppEntry*) expr)->args[i], frame_ptr, stack_top_a, &args[i], true);
                    }

                    thunk = ((PrimEntry*) slice)->exec(target);
                    
                    stack_top_a = root_frame_ptr;
                    push_a(thunk);
                    return;
                }
                else if (force && slice->type == FT_FUN) {
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
93

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
94
                    int new_frame_ptr = stack_top_a;
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
95

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

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
                    expr = ((FunEntry*) slice)->body;
                    frame_ptr = new_frame_ptr;
                    continue;
                }
                else {
                    thunk = updateF(target, slice);

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

                    for (int i = 0; i < expr->nr_args; i++) {
                        exec(((AppEntry*) expr)->args[i], frame_ptr, stack_top_a, NULL, false);
                        thunk->_args[i] = pop_a();
                    }
                    
                    stack_top_a = root_frame_ptr;
                    push_a(thunk);
                    return;                    
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
117
                }
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
118
119
            }
            break;
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
120
        }
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
121
122
123
124
        case CT_SELECT:
        {
            exec(((SelectEntry*) expr)->expr, frame_ptr, stack_top_a, NULL, true);
            Thunk* pattern = eval(pop_a());
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
125

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
            bool handled = false;
            
            for (int i = 0; i < expr->nr_cases; i++) {
                SelectCaseEntry* caseEntry = &((SelectEntry*) expr)->cases[i];

                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]);
                    }
                    
                    handled = true;
                    expr = caseEntry->body;
                    break;                    
                }
                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
153
154
            }

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
155
156
157
158
159
160
161
162
163
164
            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
165

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
166
167
            exec(((IfEntry*) expr)->cond, frame_ptr, stack_top_a, &tmp, true);
            Thunk* cond = eval(pop_a());
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
168

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
169
170
171
172
173
174
175
176
            if (readB(cond)) {
                expr = ((IfEntry*) expr)->texpr;
                continue;                
            }
            else {
                expr = ((IfEntry*) expr)->fexpr;
                continue;     
            }
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
177
        }
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
178
179
180
        default:
            printf("Exec: Unhandled CODE type");
            exit(-1);
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
181
        }
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
182
    
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
183
    }
184
}