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
59f9fa25
Commit
59f9fa25
authored
Jan 25, 2016
by
Laszlo Domoszlai
Browse files
"case" works with string constants
parent
0bd8c17d
Changes
8
Hide whitespace changes
Inline
Side-by-side
interpreter/code.c
View file @
59f9fa25
...
...
@@ -139,6 +139,7 @@ void set_create_thunk_fun(Code* code)
break
;
case
CT_SELECT_ADT
:
case
CT_SELECT_LIT
:
case
CT_SELECT_STR
:
case
CT_IF
:
case
CT_LET
:
code
->
create_thunk
=
NULL
;
...
...
@@ -587,8 +588,9 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr)
if
(
caseEntry
->
lit
!=
NULL
)
{
assert
(
caseEntry
->
lit
->
thunk
.
desc
==
(
Desc
*
)
__INT__
||
caseEntry
->
lit
->
thunk
.
desc
==
(
Desc
*
)
__BOOL__
);
caseEntry
->
lit
->
thunk
.
desc
==
(
Desc
*
)
__BOOL__
||
caseEntry
->
lit
->
thunk
.
desc
==
(
Desc
*
)
__CHAR__
);
if
(
caseEntry
->
lit
->
thunk
.
_int
!=
lit
->
_int
)
continue
;
}
...
...
@@ -610,6 +612,67 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr)
abort
(
"no match"
);
}
case
CT_SELECT_STR
:
{
SelectEntry
*
select
=
(
SelectEntry
*
)
expr
;
push_a
(
NULL
);
exec
(
select
->
expr
,
frame_ptr
,
stack_top_a
);
Thunk
*
str
=
pop_a
();
int
length
;
char
*
chars
;
if
(
str
->
desc
==
(
Desc
*
)
__STRING_PTR__
)
{
chars
=
str
->
_string_ptr
->
chars
;
length
=
str
->
_string_ptr
->
length
;
}
else
{
chars
=
str
->
_array
.
_chars
;
length
=
str
->
_array
.
length
;
}
bool
handled
=
false
;
for
(
int
i
=
0
;
i
<
expr
->
nr_cases
;
i
++
)
{
SelectLitCaseEntry
*
caseEntry
=
&
((
SelectEntry
*
)
expr
)
->
cases
[
i
];
// NULL means "default", we accept it anyway
if
(
caseEntry
->
lit
!=
NULL
)
{
assert
(
caseEntry
->
lit
->
thunk
.
desc
==
(
Desc
*
)
__STRING_PTR__
);
int
eq
=
length
==
caseEntry
->
lit
->
thunk
.
_string_ptr
->
length
;
int
i
=
0
;
while
(
i
<
length
&&
eq
)
{
eq
=
chars
[
i
]
==
caseEntry
->
lit
->
thunk
.
_string_ptr
->
chars
[
i
];
i
++
;
}
if
(
!
eq
)
continue
;
}
// must be SC_DEFAULT now
handled
=
true
;
expr
=
caseEntry
->
body
;
break
;
}
if
(
handled
)
continue
;
if
(((
SelectEntry
*
)
expr
)
->
fallback
!=
NULL
)
{
stack_top_a
-=
((
SelectEntry
*
)
expr
)
->
fallback_nrargs
;
expr
=
((
SelectEntry
*
)
expr
)
->
fallback
;
continue
;
}
abort
(
"no match"
);
}
case
CT_SELECT_ADT
:
{
SelectEntry
*
select
=
(
SelectEntry
*
)
expr
;
...
...
interpreter/code.h
View file @
59f9fa25
...
...
@@ -18,6 +18,7 @@ enum CodeType {
CT_APP_FUN_TR
,
// tail recursive
CT_SELECT_ADT
,
CT_SELECT_LIT
,
CT_SELECT_STR
,
CT_IF
,
CT_LET
,
CT_THUNK
// constant, always fits the B stack
...
...
interpreter/parse.c
View file @
59f9fa25
...
...
@@ -251,7 +251,7 @@ ThunkEntry* parseLit(char **ptr) {
case
'C'
:
// Char
{
entry
->
thunk
.
desc
=
(
Desc
*
)
__CHAR__
;
entry
->
thunk
.
_
char
=
*
(
*
ptr
)
++
;
entry
->
thunk
.
_
int
=
*
(
*
ptr
)
++
;
break
;
}
...
...
@@ -266,7 +266,7 @@ ThunkEntry* parseLit(char **ptr) {
case
'1'
:
{
entry
->
thunk
.
desc
=
(
Desc
*
)
__BOOL__
;
entry
->
thunk
.
_
bool
=
type
==
'1'
;
entry
->
thunk
.
_
int
=
type
==
'1'
;
break
;
}
...
...
@@ -583,6 +583,13 @@ SelectEntry* parseSelect(char **ptr, Code* fallback, int fallback_nrargs) {
for
(
int
i
=
0
;
i
<
nrCases
;
i
++
)
{
(
*
ptr
)
++
;
// skip type
entry
->
cases
[
i
].
lit
=
parseLit
(
ptr
);
// String literal is the third case for efficiency reasons
if
(
i
==
0
&&
entry
->
cases
[
i
].
lit
->
thunk
.
desc
==
(
Desc
*
)
__STRING_PTR__
)
{
entry
->
base
.
type
=
CT_SELECT_STR
;
}
entry
->
cases
[
i
].
body
=
(
Code
*
)
parseSelectBody
(
ptr
,
child_fallback
,
child_fallback_base_nrargs
);
}
}
...
...
interpreter/prim.c
View file @
59f9fa25
...
...
@@ -34,67 +34,67 @@ void __divI(int dst_idx) {
void
__gtI
(
int
dst_idx
)
{
Thunk
*
target
=
get_dst
(
dst_idx
);
target
->
desc
=
(
Desc
*
)
__BOOL__
;
target
->
_
bool
=
readI
(
arg
(
2
))
>
readI
(
arg
(
1
));
target
->
_
int
=
readI
(
arg
(
2
))
>
readI
(
arg
(
1
));
}
void
__geI
(
int
dst_idx
)
{
Thunk
*
target
=
get_dst
(
dst_idx
);
target
->
desc
=
(
Desc
*
)
__BOOL__
;
target
->
_
bool
=
readI
(
arg
(
2
))
>=
readI
(
arg
(
1
));
target
->
_
int
=
readI
(
arg
(
2
))
>=
readI
(
arg
(
1
));
}
void
__ltI
(
int
dst_idx
)
{
Thunk
*
target
=
get_dst
(
dst_idx
);
target
->
desc
=
(
Desc
*
)
__BOOL__
;
target
->
_
bool
=
readI
(
arg
(
2
))
<
readI
(
arg
(
1
));
target
->
_
int
=
readI
(
arg
(
2
))
<
readI
(
arg
(
1
));
}
void
__geC
(
int
dst_idx
)
{
Thunk
*
target
=
get_dst
(
dst_idx
);
target
->
desc
=
(
Desc
*
)
__BOOL__
;
target
->
_
bool
=
readC
(
arg
(
2
))
>=
readC
(
arg
(
1
));
target
->
_
int
=
readC
(
arg
(
2
))
>=
readC
(
arg
(
1
));
}
void
__eqI
(
int
dst_idx
)
{
Thunk
*
target
=
get_dst
(
dst_idx
);
target
->
desc
=
(
Desc
*
)
__BOOL__
;
target
->
_
bool
=
readI
(
arg
(
2
))
==
readI
(
arg
(
1
));
target
->
_
int
=
readI
(
arg
(
2
))
==
readI
(
arg
(
1
));
}
void
__neqI
(
int
dst_idx
)
{
Thunk
*
target
=
get_dst
(
dst_idx
);
target
->
desc
=
(
Desc
*
)
__BOOL__
;
target
->
_
bool
=
readI
(
arg
(
2
))
!=
readI
(
arg
(
1
));
target
->
_
int
=
readI
(
arg
(
2
))
!=
readI
(
arg
(
1
));
}
void
__eqB
(
int
dst_idx
)
{
Thunk
*
target
=
get_dst
(
dst_idx
);
target
->
desc
=
(
Desc
*
)
__BOOL__
;
target
->
_
bool
=
readB
(
arg
(
2
))
==
readB
(
arg
(
1
));
target
->
_
int
=
readB
(
arg
(
2
))
==
readB
(
arg
(
1
));
}
void
__eqC
(
int
dst_idx
)
{
Thunk
*
target
=
get_dst
(
dst_idx
);
target
->
desc
=
(
Desc
*
)
__CHAR__
;
target
->
_
bool
=
readC
(
arg
(
2
))
==
readC
(
arg
(
1
));
target
->
_
int
=
readC
(
arg
(
2
))
==
readC
(
arg
(
1
));
}
void
__not
(
int
dst_idx
)
{
Thunk
*
target
=
get_dst
(
dst_idx
);
target
->
desc
=
(
Desc
*
)
__BOOL__
;
target
->
_
bool
=
!
readB
(
arg
(
1
));
target
->
_
int
=
!
readB
(
arg
(
1
));
}
void
__and
(
int
dst_idx
)
{
Thunk
*
target
=
get_dst
(
dst_idx
);
target
->
desc
=
(
Desc
*
)
__BOOL__
;
target
->
_
bool
=
readB
(
arg
(
2
))
&&
readB
(
arg
(
1
));
target
->
_
int
=
readB
(
arg
(
2
))
&&
readB
(
arg
(
1
));
}
void
__or
(
int
dst_idx
)
{
Thunk
*
target
=
get_dst
(
dst_idx
);
target
->
desc
=
(
Desc
*
)
__BOOL__
;
target
->
_
bool
=
readB
(
arg
(
2
))
||
readB
(
arg
(
1
));
target
->
_
int
=
readB
(
arg
(
2
))
||
readB
(
arg
(
1
));
}
void
__mod
(
int
dst_idx
)
{
...
...
@@ -147,7 +147,7 @@ void __string_select(int dst_idx)
}
target
->
desc
=
(
Desc
*
)
__CHAR__
;
target
->
_char
=
chars
[
pos
->
_int
];
target
->
_
int
=
(
char
)
chars
[
pos
->
_int
];
}
Thunk
*
string_create
(
Thunk
*
target
,
int
len
)
...
...
@@ -191,7 +191,7 @@ void __string_create2(int dst_idx)
target
=
string_create
(
target
,
len
->
_int
);
for
(
int
i
=
0
;
i
<
len
->
_int
;
i
++
)
{
target
->
_array
.
_chars
[
i
]
=
ch
->
_
char
;
target
->
_array
.
_chars
[
i
]
=
(
char
)
ch
->
_
int
;
}
set_return
(
dst_idx
,
target
);
...
...
@@ -221,7 +221,7 @@ void __string_update(int dst_idx)
target
=
string_create
(
target
,
length
);
memcpy
(
target
->
_array
.
_chars
,
chars
,
length
);
target
->
_array
.
_chars
[
idx
->
_int
]
=
ch
->
_
char
;
target
->
_array
.
_chars
[
idx
->
_int
]
=
(
char
)
ch
->
_
int
;
set_return
(
dst_idx
,
target
);
}
...
...
@@ -330,18 +330,15 @@ void __eqS(int dst_idx)
int
eq
=
length1
==
length2
;
if
(
eq
)
int
i
=
0
;
while
(
i
<
length1
&&
eq
)
{
int
i
=
0
;
while
(
i
<
length1
&&
eq
)
{
eq
=
chars1
[
i
]
==
chars2
[
i
];
i
++
;
}
eq
=
chars1
[
i
]
==
chars2
[
i
];
i
++
;
}
target
->
desc
=
(
Desc
*
)
__BOOL__
;
target
->
_
bool
=
eq
;
target
->
_
int
=
eq
;
}
void
add_prim
(
int
arity
,
int
boxingMap
,
char
*
name
,
void
(
*
exec
)(
int
))
{
...
...
interpreter/thunk.c
View file @
59f9fa25
...
...
@@ -30,7 +30,7 @@ int readB(Thunk* thunk) {
exit
(
-
1
);
}
return
thunk
->
_
bool
;
return
thunk
->
_
int
;
}
char
readC
(
Thunk
*
thunk
)
{
...
...
@@ -42,7 +42,7 @@ char readC(Thunk* thunk) {
exit
(
-
1
);
}
return
thunk
->
_
char
;
return
(
char
)
thunk
->
_
int
;
}
#endif
...
...
@@ -64,13 +64,13 @@ void print(bool force) {
if
((
FunEntry
*
)
thunk
->
desc
==
__INT__
)
{
printf
(
"%d"
,
thunk
->
_int
);
}
else
if
((
FunEntry
*
)
thunk
->
desc
==
__BOOL__
)
{
if
(
thunk
->
_
bool
)
{
if
(
thunk
->
_
int
)
{
printf
(
"True"
);
}
else
{
printf
(
"False"
);
}
}
else
if
((
FunEntry
*
)
thunk
->
desc
==
__CHAR__
)
{
printf
(
"%c"
,
thunk
->
_
char
);
printf
(
"%c"
,
(
char
)
thunk
->
_
int
);
}
else
if
((
FunEntry
*
)
thunk
->
desc
==
__STRING_PTR__
)
{
for
(
int
i
=
0
;
i
<
thunk
->
_string_ptr
->
length
;
i
++
)
{
...
...
interpreter/thunk.h
View file @
59f9fa25
...
...
@@ -37,10 +37,8 @@ typedef struct __attribute__((packed)) Thunk {
union
{
Thunk
*
_forward_ptr
;
int
_int
;
double
_real
;
// TODO: move "real" out of here, too long (at least on 32 bits)
char
_char
;
int
_bool
;
int
_int
;
// also char and bool
double
_real
;
// TODO: move "real" out of here, too long (at least on 32 bits)
struct
CleanString
*
_string_ptr
;
// For CT_THUNK
struct
Array
_array
;
Thunk
*
_args
[];
...
...
@@ -60,8 +58,8 @@ char readC(Thunk* thunk);
#else
#define readI(thunk) thunk->_int
#define readB(thunk) thunk->_
bool
#define readC(thunk) thunk->_
char
#define readB(thunk) thunk->_
int
#define readC(thunk) thunk->_
int
#endif
...
...
tests/string_case.exp
0 → 100644
View file @
59f9fa25
[B]
\ No newline at end of file
tests/string_case.sapl
0 → 100644
View file @
59f9fa25
main = string.Start
string.Start = <{string._c;16;9_2}> string.str
string.str = "Hello World!"
<{string._c;16;9_2}> !_x_0 = select _x_0 ("" -> "A") ("Hello World!" -> "B")
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