code.c 5.97 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 "desc.h"
8
#include "thunk.h"
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
9
#include "mem.h"
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
10
    
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
11
void exec(Code* expr, int frame_ptr, int root_frame_ptr, Thunk* target, bool force)
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
12
{
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
13
14
    assert(expr != NULL);

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
15
16
17
18
    while(1)
    {
        switch (expr->type) {
        case CT_LIT:
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
19
            stack_top_a = root_frame_ptr; 
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
20
            
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
21
22
23
24
25
26
27
28
29
30
31
32
33
34
            switch (expr->local_type) {
            case LIT_INT:
                push_a(updateI(target, ((LitEntry*) expr)->_int));
                return;
            case LIT_BOOL:
                push_a(updateB(target, ((LitEntry*) expr)->_bool));
                return;
            default:
                printf("Exec: Unhandled LIT type");
                exit(-1);
            }
            break;
        case CT_VAR:
            stack_top_a = root_frame_ptr;     
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
35
            
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
36
37
38
39
40
41
            if (expr->local_type == VAR_LOCAL) {
                push_a(forward_to(target, local(frame_ptr, ((VarEntry*) expr)->index)));
                return;
            }else{
                push_a(updateF(target, get_slice(((VarEntry*) expr)->f, 0)));
                return;
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
42
            }
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
43
44
            break;
        case CT_APP:
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
45
        {
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
46
47
            // TODO: check over application
            // TODO: enforce strictness in ADT/Record
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
48

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

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

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

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
60
                thunk = updateF(target, slice);
61

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

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

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

                stack_top_a = root_frame_ptr;
                push_a(thunk);
                return;
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
76
            }
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
            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
95

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
96
                    int new_frame_ptr = stack_top_a;
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
97

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
98
99
100
                    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
101

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
                    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
119
                }
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
120
121
            }
            break;
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
122
        }
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
123
124
125
126
        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
127

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
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
153
154
            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
155
156
            }

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

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

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