Skip to content
GitLab
Menu
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
c6e8974d
Commit
c6e8974d
authored
Sep 21, 2015
by
Laszlo Domoszlai
Browse files
use function table for create_thunk functions instead of one big function + switch
parent
4bfb088d
Changes
3
Hide whitespace changes
Inline
Side-by-side
interpreter/code.c
View file @
c6e8974d
...
...
@@ -38,79 +38,83 @@
} \
else \
{ \
push_a(create_thunk(arg, frame_ptr)); \
push_a(create_thunk
_funs[arg->type]
(arg, frame_ptr)); \
} \
argmask <<= 1;
Thunk
*
(
*
create_thunk_funs
[
9
])
(
Code
*
expr
,
int
frame_ptr
);
struct
Thunk
*
create_thunk
(
Code
*
expr
,
int
frame_ptr
)
struct
Thunk
*
create_thunk
_app_static
(
Code
*
expr
,
int
frame_ptr
)
{
assert
(
expr
!=
NULL
);
// TODO: check over application
// TODO: enforce strictness in ADT/Record
// TODO: CAS
switch
(
expr
->
type
)
{
case
CT_APP_PRIM
:
case
CT_APP_FUN
:
case
CT_APP_THUNK
:
{
Thunk
*
thunk
=
createF
(((
AppEntry
*
)
expr
)
->
f
);
Thunk
*
thunk
=
createF
(((
AppEntry
*
)
expr
)
->
f
);
assert
(
thunk
->
desc
->
arity
==
expr
->
nr_args
);
for
(
int
i
=
0
;
i
<
expr
->
nr_args
;
i
++
)
{
thunk
->
_args
[
i
]
=
create_thunk
(((
AppEntry
*
)
expr
)
->
args
[
i
],
frame_ptr
);
}
assert
(
thunk
->
desc
->
arity
==
expr
->
nr_args
);
return
thunk
;
for
(
int
i
=
0
;
i
<
expr
->
nr_args
;
i
++
)
{
thunk
->
_args
[
i
]
=
create_thunk_funs
[((
AppEntry
*
)
expr
)
->
args
[
i
]
->
type
](((
AppEntry
*
)
expr
)
->
args
[
i
],
frame_ptr
);
}
case
CT_APP_DYN
:
{
Thunk
*
basethunk
=
local
(
frame_ptr
,
((
AppEntry
*
)
expr
)
->
var
.
index
);
if
(
!
basethunk
->
desc
->
hnf
)
basethunk
=
eval
(
basethunk
);
Desc
*
slice
=
get_slice
(
basethunk
->
desc
->
type
==
FT_SLICE
?
((
SliceEntry
*
)
basethunk
->
desc
)
->
forward_ptr
:
basethunk
->
desc
,
basethunk
->
desc
->
arity
+
expr
->
nr_args
);
return
thunk
;
}
Thunk
*
thunk
=
createF
(
slice
);
struct
Thunk
*
create_thunk_app_dyn
(
Code
*
expr
,
int
frame_ptr
)
{
Thunk
*
basethunk
=
local
(
frame_ptr
,
((
AppEntry
*
)
expr
)
->
var
.
index
);
if
(
!
basethunk
->
desc
->
hnf
)
basethunk
=
eval
(
basethunk
);
assert
(
thunk
->
desc
->
arity
==
basethunk
->
desc
->
arity
+
expr
->
nr_args
);
Desc
*
slice
=
get_slice
(
basethunk
->
desc
->
type
==
FT_SLICE
?
((
SliceEntry
*
)
basethunk
->
desc
)
->
forward_ptr
:
basethunk
->
desc
,
basethunk
->
desc
->
arity
+
expr
->
nr_args
);
memcpy
(
&
thunk
->
_args
,
&
basethunk
->
_args
,
sizeof
(
Thunk
*
)
*
basethunk
->
desc
->
arity
);
for
(
int
i
=
0
;
i
<
expr
->
nr_args
;
i
++
)
{
thunk
->
_args
[
basethunk
->
desc
->
arity
+
i
]
=
create_thunk
(((
AppEntry
*
)
expr
)
->
args
[
i
],
frame_ptr
);
}
Thunk
*
thunk
=
createF
(
slice
);
return
thunk
;
assert
(
thunk
->
desc
->
arity
==
basethunk
->
desc
->
arity
+
expr
->
nr_args
);
memcpy
(
&
thunk
->
_args
,
&
basethunk
->
_args
,
sizeof
(
Thunk
*
)
*
basethunk
->
desc
->
arity
);
for
(
int
i
=
0
;
i
<
expr
->
nr_args
;
i
++
)
{
thunk
->
_args
[
basethunk
->
desc
->
arity
+
i
]
=
create_thunk_funs
[((
AppEntry
*
)
expr
)
->
args
[
i
]
->
type
](((
AppEntry
*
)
expr
)
->
args
[
i
],
frame_ptr
);
}
return
thunk
;
}
struct
Thunk
*
create_thunk_var
(
Code
*
expr
,
int
frame_ptr
)
{
return
local
(
frame_ptr
,
((
VarEntry
*
)
expr
)
->
index
);
}
struct
Thunk
*
create_thunk_var_strict
(
Code
*
expr
,
int
frame_ptr
)
{
Thunk
*
arg
=
local
(
frame_ptr
,
((
VarEntry
*
)
expr
)
->
index
);
if
(
arg
->
desc
->
unboxable
)
{
return
createT
(
arg
);
}
case
CT_VAR
:
return
local
(
frame_ptr
,
((
VarEntry
*
)
expr
)
->
index
);
case
CT_VAR_STRICT
:
else
{
Thunk
*
arg
=
local
(
frame_ptr
,
((
VarEntry
*
)
expr
)
->
index
);
if
(
arg
->
desc
->
unboxable
)
{
return
createT
(
arg
);
}
else
{
return
arg
;
}
return
arg
;
}
case
CT_THUNK
:
return
&
((
ThunkEntry
*
)
expr
)
->
thunk
;
case
CT_SELECT
:
case
CT_IF
:
// Only here to avoid intervalum check at switch
abort
(
"Unexpected code type"
);
return
NULL
;
}
}
struct
Thunk
*
create_thunk_thunk
(
Code
*
expr
,
int
frame_ptr
)
{
return
&
((
ThunkEntry
*
)
expr
)
->
thunk
;
}
void
init_code
()
{
create_thunk_funs
[
CT_VAR
]
=
create_thunk_var
;
create_thunk_funs
[
CT_VAR_STRICT
]
=
create_thunk_var_strict
;
create_thunk_funs
[
CT_APP_THUNK
]
=
create_thunk_app_static
;
create_thunk_funs
[
CT_APP_PRIM
]
=
create_thunk_app_static
;
create_thunk_funs
[
CT_APP_FUN
]
=
create_thunk_app_static
;
create_thunk_funs
[
CT_APP_DYN
]
=
create_thunk_app_dyn
;
create_thunk_funs
[
CT_SELECT
]
=
NULL
;
create_thunk_funs
[
CT_IF
]
=
NULL
;
create_thunk_funs
[
CT_THUNK
]
=
create_thunk_thunk
;
}
void
exec
(
Code
*
expr
,
int
frame_ptr
,
int
root_frame_ptr
)
...
...
@@ -128,7 +132,7 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr)
switch
(
expr
->
type
)
{
case
CT_APP_PRIM
:
{
{
Desc
*
slice
=
((
AppEntry
*
)
expr
)
->
f
;
for
(
int
i
=
0
;
i
<
expr
->
nr_args
;
i
++
)
{
...
...
@@ -142,7 +146,7 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr)
return
;
}
case
CT_APP_FUN
:
{
{
Desc
*
slice
=
((
AppEntry
*
)
expr
)
->
f
;
int
new_frame_ptr
=
stack_top_a
;
...
...
@@ -166,7 +170,7 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr)
for
(
int
i
=
0
;
i
<
expr
->
nr_args
;
i
++
)
{
thunk
->
_args
[
i
]
=
create_thunk
(((
AppEntry
*
)
expr
)
->
args
[
i
],
frame_ptr
);
=
create_thunk
_funs
[((
AppEntry
*
)
expr
)
->
args
[
i
]
->
type
]
(((
AppEntry
*
)
expr
)
->
args
[
i
],
frame_ptr
);
}
set_return
(
root_frame_ptr
,
thunk
);
...
...
@@ -236,7 +240,7 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr)
for
(
int
i
=
0
;
i
<
expr
->
nr_args
;
i
++
)
{
thunk
->
_args
[
basethunk
->
desc
->
arity
+
i
]
=
create_thunk
(((
AppEntry
*
)
expr
)
->
args
[
i
],
frame_ptr
);
=
create_thunk
_funs
[((
AppEntry
*
)
expr
)
->
args
[
i
]
->
type
]
(((
AppEntry
*
)
expr
)
->
args
[
i
],
frame_ptr
);
}
set_return
(
root_frame_ptr
,
thunk
);
...
...
@@ -395,7 +399,7 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr)
struct
Thunk
*
eval
(
Thunk
*
thunk
)
{
assert
(
thunk
!=
NULL
);
follow_thunk
(
thunk
);
switch
(
thunk
->
desc
->
type
)
{
...
...
interpreter/code.h
View file @
c6e8974d
...
...
@@ -63,6 +63,8 @@ struct IfEntry {
struct
Code
*
fexpr
;
};
void
init_code
();
void
exec
(
Code
*
expr
,
int
frame_ptr
,
int
root_frame_ptr
);
struct
Thunk
*
eval
(
Thunk
*
thunk
);
...
...
interpreter/main.c
View file @
c6e8974d
...
...
@@ -28,6 +28,7 @@ int main ( int argc, char *argv[] )
init_mem
();
init_desc
();
init_prim
();
init_code
();
char
*
input
=
"..
\\
tests
\\
Braun.bsapl"
;
...
...
@@ -100,7 +101,7 @@ int main ( int argc, char *argv[] )
// compute and print the elapsed time in millisec
double
elapsedTime
=
(
t2
.
tv_sec
-
t1
.
tv_sec
)
*
1000
.
0
;
// sec to ms
elapsedTime
+=
(
t2
.
tv_usec
-
t1
.
tv_usec
)
/
1000
.
0
;
// us to ms
printf
(
"
\n\n
e
xecution time: %G ms
\n
"
,
elapsedTime
);
printf
(
"
\n\n
E
xecution time: %G ms
\n
"
,
elapsedTime
);
#endif
#ifdef DEBUG
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a 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