code.c 5.96 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
19
    while(1)
    {
        switch (expr->type) {
        case CT_LIT:
            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
50
51
            VarEntry* var;
            var = ((AppEntry*) expr)->var;
            Thunk* thunk;
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
52

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

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

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

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

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

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

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

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

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

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