Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
clean-and-itasks
sapl-interpreter
Commits
016c82fe
Commit
016c82fe
authored
Aug 28, 2015
by
Laszlo Domoszlai
Browse files
remove force variable from exec, split it into exec and create_thunk
parent
d745f3d0
Changes
4
Hide whitespace changes
Inline
Side-by-side
interpreter/code.c
View file @
016c82fe
...
...
@@ -7,12 +7,87 @@
#include
"mem.h"
#include
"desc.h"
void
exec
(
Code
*
expr
,
int
frame_ptr
,
int
root_frame_ptr
,
bool
force
)
void
create_thunk
(
Code
*
expr
,
int
frame_ptr
,
int
root_frame_ptr
)
{
assert
(
expr
!=
NULL
);
switch
(
expr
->
type
)
{
case
CT_LIT
:
set_return
(
root_frame_ptr
,
updateT
(
get_dst
(
root_frame_ptr
),
&
((
LitEntry
*
)
expr
)
->
thunk
));
destroy_stack_frame
(
root_frame_ptr
);
return
;
case
CT_VAR
:
if
(
expr
->
local_type
==
VAR_LOCAL
)
{
Thunk
*
thunk
=
forward_to
(
get_dst
(
root_frame_ptr
),
local
(
frame_ptr
,
((
VarEntry
*
)
expr
)
->
index
));
destroy_stack_frame
(
root_frame_ptr
);
set_return
(
root_frame_ptr
,
thunk
);
return
;
}
else
{
destroy_stack_frame
(
root_frame_ptr
);
set_return
(
root_frame_ptr
,
updateF
(
get_dst
(
root_frame_ptr
),
get_slice
(((
VarEntry
*
)
expr
)
->
f
,
0
)));
return
;
}
case
CT_APP
:
{
// TODO: check over application
// TODO: enforce strictness in ADT/Record
VarEntry
*
var
=
&
((
AppEntry
*
)
expr
)
->
var
;
if
(
var
->
base
.
local_type
==
VAR_LOCAL
)
{
// TODO: force
Thunk
*
basethunk
=
eval
(
local
(
frame_ptr
,
var
->
index
));
Desc
*
slice
=
get_slice
(
basethunk
->
desc
->
type
==
FT_SLICE
?
((
SliceEntry
*
)
basethunk
->
desc
)
->
forward_ptr
:
basethunk
->
desc
,
basethunk
->
desc
->
arity
+
expr
->
nr_args
);
Thunk
*
thunk
=
updateF
(
get_dst
(
root_frame_ptr
),
slice
);
assert
(
thunk
->
desc
->
arity
==
basethunk
->
desc
->
arity
+
expr
->
nr_args
);
for
(
int
i
=
0
;
i
<
basethunk
->
desc
->
arity
;
i
++
)
{
thunk
->
_args
[
i
]
=
basethunk
->
_args
[
i
];
}
for
(
int
i
=
0
;
i
<
expr
->
nr_args
;
i
++
)
{
push_a
(
NULL
);
create_thunk
(((
AppEntry
*
)
expr
)
->
args
[
i
],
frame_ptr
,
stack_top_a
);
thunk
->
_args
[
basethunk
->
desc
->
arity
+
i
]
=
pop_a
();
}
set_return
(
root_frame_ptr
,
thunk
);
destroy_stack_frame
(
root_frame_ptr
);
return
;
}
else
{
Thunk
*
thunk
=
updateF
(
get_dst
(
root_frame_ptr
),
get_slice
(
var
->
f
,
expr
->
nr_args
));
assert
(
thunk
->
desc
->
arity
==
expr
->
nr_args
);
for
(
int
i
=
0
;
i
<
expr
->
nr_args
;
i
++
)
{
push_a
(
NULL
);
create_thunk
(((
AppEntry
*
)
expr
)
->
args
[
i
],
frame_ptr
,
stack_top_a
);
thunk
->
_args
[
i
]
=
pop_a
();
}
set_return
(
root_frame_ptr
,
thunk
);
destroy_stack_frame
(
root_frame_ptr
);
return
;
}
break
;
}
}
}
void
exec
(
Code
*
expr
,
int
frame_ptr
,
int
root_frame_ptr
)
{
while
(
1
)
{
assert
(
expr
!=
NULL
);
assert
(
stack_top_a
<
STACK_SIZE_A
);
switch
(
expr
->
type
)
{
...
...
@@ -26,12 +101,8 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr, bool force)
// Destroy stack frame before eval, it is not needed any more
// Greatly reduces stack usage
destroy_stack_frame
(
root_frame_ptr
);
// TODO: inline eval
if
(
force
)
thunk
=
eval
(
thunk
);
set_return
(
root_frame_ptr
,
thunk
);
destroy_stack_frame
(
root_frame_ptr
);
set_return
(
root_frame_ptr
,
eval
(
thunk
));
return
;
}
else
{
// Safe to destroy, the next call has no arguments
...
...
@@ -39,7 +110,7 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr, bool force)
Desc
*
slice
=
get_slice
(((
VarEntry
*
)
expr
)
->
f
,
0
);
if
(
force
&&
slice
->
type
==
FT_FUN
)
if
(
slice
->
type
==
FT_FUN
)
{
expr
=
((
FunEntry
*
)
slice
)
->
body
;
continue
;
...
...
@@ -77,7 +148,7 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr, bool force)
for
(
int
i
=
0
;
i
<
expr
->
nr_args
;
i
++
)
{
push_a
(
NULL
);
exec
(((
AppEntry
*
)
expr
)
->
args
[
i
],
frame_ptr
,
stack_top_a
,
false
);
create_thunk
(((
AppEntry
*
)
expr
)
->
args
[
i
],
frame_ptr
,
stack_top_a
);
thunk
->
_args
[
basethunk
->
desc
->
arity
+
i
]
=
pop_a
();
}
...
...
@@ -89,25 +160,32 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr, bool force)
{
Desc
*
slice
=
get_slice
(
var
->
f
,
expr
->
nr_args
);
if
(
force
&&
slice
->
type
==
FT_PRIM
)
{
if
(
slice
->
type
==
FT_PRIM
)
{
Thunk
args
[
expr
->
nr_args
];
for
(
int
i
=
0
;
i
<
expr
->
nr_args
;
i
++
)
{
push_a
(
&
args
[
i
]);
exec
(((
AppEntry
*
)
expr
)
->
args
[
i
],
frame_ptr
,
stack_top_a
,
true
);
exec
(((
AppEntry
*
)
expr
)
->
args
[
i
],
frame_ptr
,
stack_top_a
);
}
((
PrimEntry
*
)
slice
)
->
exec
(
root_frame_ptr
);
destroy_stack_frame
(
root_frame_ptr
);
return
;
}
else
if
(
force
&&
slice
->
type
==
FT_FUN
)
{
else
if
(
slice
->
type
==
FT_FUN
)
{
int
new_frame_ptr
=
stack_top_a
;
for
(
int
i
=
0
;
i
<
expr
->
nr_args
;
i
++
)
{
push_a
(
NULL
);
exec
(((
AppEntry
*
)
expr
)
->
args
[
i
],
frame_ptr
,
stack_top_a
,
is_strict_fun_arg
((
FunEntry
*
)
slice
,
i
));
if
(
is_strict_fun_arg
((
FunEntry
*
)
slice
,
i
))
{
exec
(((
AppEntry
*
)
expr
)
->
args
[
i
],
frame_ptr
,
stack_top_a
);
}
else
{
create_thunk
(((
AppEntry
*
)
expr
)
->
args
[
i
],
frame_ptr
,
stack_top_a
);
}
}
expr
=
((
FunEntry
*
)
slice
)
->
body
;
...
...
@@ -121,7 +199,7 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr, bool force)
for
(
int
i
=
0
;
i
<
expr
->
nr_args
;
i
++
)
{
push_a
(
NULL
);
exec
(((
AppEntry
*
)
expr
)
->
args
[
i
],
frame_ptr
,
stack_top_a
,
false
);
create_thunk
(((
AppEntry
*
)
expr
)
->
args
[
i
],
frame_ptr
,
stack_top_a
);
thunk
->
_args
[
i
]
=
pop_a
();
}
...
...
@@ -135,7 +213,7 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr, bool force)
case
CT_SELECT
:
{
push_a
(
NULL
);
exec
(((
SelectEntry
*
)
expr
)
->
expr
,
frame_ptr
,
stack_top_a
,
true
);
exec
(((
SelectEntry
*
)
expr
)
->
expr
,
frame_ptr
,
stack_top_a
);
Thunk
*
pattern
=
eval
(
pop_a
());
bool
handled
=
false
;
...
...
@@ -177,7 +255,7 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr, bool force)
tmp
.
desc
=
(
Desc
*
)
__BOOL__
;
push_a
(
&
tmp
);
exec
(((
IfEntry
*
)
expr
)
->
cond
,
frame_ptr
,
stack_top_a
,
true
);
exec
(((
IfEntry
*
)
expr
)
->
cond
,
frame_ptr
,
stack_top_a
);
Thunk
*
cond
=
eval
(
pop_a
());
if
(
readB
(
cond
))
{
...
...
interpreter/code.h
View file @
016c82fe
...
...
@@ -72,6 +72,6 @@ struct IfEntry {
struct
Code
*
fexpr
;
};
void
exec
(
Code
*
expr
,
int
frame_ptr
,
int
root_frame_ptr
,
bool
force
);
void
exec
(
Code
*
expr
,
int
frame_ptr
,
int
root_frame_ptr
);
#endif // __CODE_H
\ No newline at end of file
interpreter/main.c
View file @
016c82fe
...
...
@@ -85,7 +85,7 @@ int main ( int argc, char *argv[] )
#endif
push_a
(
NULL
);
exec
(
expr
,
stack_top_a
,
stack_top_a
,
true
);
exec
(
expr
,
stack_top_a
,
stack_top_a
);
Thunk
*
res
=
eval
(
pop_a
());
#ifdef DEBUG
...
...
interpreter/thunk.c
View file @
016c82fe
...
...
@@ -129,7 +129,7 @@ struct Thunk* eval(Thunk* thunk) {
// TODO: handle strictness
push_a
(
thunk
->
_args
[
i
]);
}
exec
(((
FunEntry
*
)
thunk
->
desc
)
->
body
,
frame_ptr
,
frame_ptr
,
true
);
exec
(((
FunEntry
*
)
thunk
->
desc
)
->
body
,
frame_ptr
,
frame_ptr
);
thunk
=
pop_a
();
}
else
if
(
thunk
->
desc
->
type
==
FT_PRIM
)
{
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment