Handle tuple instructions.
This commit is contained in:
parent
65a806ed90
commit
fe5a05ba97
@ -168,6 +168,21 @@ deserialize(<<>>, #{ function := F
|
|||||||
, code => #{}
|
, code => #{}
|
||||||
, functions => Funs#{F => FunctionCode}}.
|
, functions => Funs#{F => FunctionCode}}.
|
||||||
|
|
||||||
|
deserialize_op(?ELEMENT, Rest, Code) ->
|
||||||
|
{Type, Rest2} = deserialize_type(Rest),
|
||||||
|
<<ArgType:8, Rest3/binary>> = Rest2,
|
||||||
|
{Arg0, Rest4} = aefa_encoding:deserialize_one(Rest3),
|
||||||
|
{Arg1, Rest5} = aefa_encoding:deserialize_one(Rest4),
|
||||||
|
{Arg2, Rest6} = aefa_encoding:deserialize_one(Rest5),
|
||||||
|
Modifier0 = bits_to_modifier(ArgType band 2#11),
|
||||||
|
Modifier1 = bits_to_modifier((ArgType bsr 2) band 2#11),
|
||||||
|
Modifier2 = bits_to_modifier((ArgType bsr 4) band 2#11),
|
||||||
|
{Rest6, [{ aefa_opcodes:mnemonic(?ELEMENT)
|
||||||
|
, Type
|
||||||
|
, {Modifier0, Arg0}
|
||||||
|
, {Modifier1, Arg1}
|
||||||
|
, {Modifier2, Arg2}}
|
||||||
|
| Code]};
|
||||||
deserialize_op(Op, Rest, Code) ->
|
deserialize_op(Op, Rest, Code) ->
|
||||||
OpName = aefa_opcodes:mnemonic(Op),
|
OpName = aefa_opcodes:mnemonic(Op),
|
||||||
case aefa_opcodes:args(Op) of
|
case aefa_opcodes:args(Op) of
|
||||||
@ -278,6 +293,12 @@ serialize_code([ {Arg0Type, Arg0} | Rest]) ->
|
|||||||
[ArgSpec
|
[ArgSpec
|
||||||
, serialize_data(Arg0Type, Arg0)
|
, serialize_data(Arg0Type, Arg0)
|
||||||
| serialize_code(Rest)];
|
| serialize_code(Rest)];
|
||||||
|
serialize_code([ ?ELEMENT
|
||||||
|
, ResType
|
||||||
|
| Rest]) ->
|
||||||
|
[?ELEMENT,
|
||||||
|
serialize_type(ResType)
|
||||||
|
| serialize_code(Rest)];
|
||||||
serialize_code([B|Rest]) ->
|
serialize_code([B|Rest]) ->
|
||||||
[B | serialize_code(Rest)];
|
[B | serialize_code(Rest)];
|
||||||
serialize_code([]) -> [].
|
serialize_code([]) -> [].
|
||||||
@ -352,6 +373,10 @@ to_bytecode([{function,_line, 'FUNCTION'}|Rest], Address, Env, Code, Opts) ->
|
|||||||
Env2 = insert_fun(Address, Code, Env),
|
Env2 = insert_fun(Address, Code, Env),
|
||||||
{Fun, Rest2} = to_fun_def(Rest),
|
{Fun, Rest2} = to_fun_def(Rest),
|
||||||
to_bytecode(Rest2, Fun, Env2, [], Opts);
|
to_bytecode(Rest2, Fun, Env2, [], Opts);
|
||||||
|
to_bytecode([{mnemonic,_line, 'ELEMENT'}|Rest], Address, Env, Code, Opts) ->
|
||||||
|
OpCode = aefa_opcodes:m_to_op('ELEMENT'),
|
||||||
|
{RetType, Rest2} = to_type(Rest),
|
||||||
|
to_bytecode(Rest2, Address, Env, [RetType, OpCode|Code], Opts);
|
||||||
to_bytecode([{mnemonic,_line, Op}|Rest], Address, Env, Code, Opts) ->
|
to_bytecode([{mnemonic,_line, Op}|Rest], Address, Env, Code, Opts) ->
|
||||||
OpCode = aefa_opcodes:m_to_op(Op),
|
OpCode = aefa_opcodes:m_to_op(Op),
|
||||||
to_bytecode(Rest, Address, Env, [OpCode|Code], Opts);
|
to_bytecode(Rest, Address, Env, [OpCode|Code], Opts);
|
||||||
|
@ -51,6 +51,8 @@ mnemonic(?ELT) -> 'ELT' ;
|
|||||||
mnemonic(?EQ) -> 'EQ' ;
|
mnemonic(?EQ) -> 'EQ' ;
|
||||||
mnemonic(?NEQ) -> 'NEQ' ;
|
mnemonic(?NEQ) -> 'NEQ' ;
|
||||||
mnemonic(?STORE) -> 'STORE' ;
|
mnemonic(?STORE) -> 'STORE' ;
|
||||||
|
mnemonic(?TUPLE) -> 'TUPLE' ;
|
||||||
|
mnemonic(?ELEMENT) -> 'ELEMENT' ;
|
||||||
mnemonic(OP) -> {OP, nothandled}.
|
mnemonic(OP) -> {OP, nothandled}.
|
||||||
|
|
||||||
m_to_op('NOP') -> ?NOP ;
|
m_to_op('NOP') -> ?NOP ;
|
||||||
@ -77,6 +79,8 @@ m_to_op('EGT') -> ?EGT ;
|
|||||||
m_to_op('EQ') -> ?EQ ;
|
m_to_op('EQ') -> ?EQ ;
|
||||||
m_to_op('NEQ') -> ?NEQ ;
|
m_to_op('NEQ') -> ?NEQ ;
|
||||||
m_to_op('STORE') -> ?STORE ;
|
m_to_op('STORE') -> ?STORE ;
|
||||||
|
m_to_op('TUPLE') -> ?TUPLE ;
|
||||||
|
m_to_op('ELEMENT') -> ?ELEMENT ;
|
||||||
m_to_op('CALL') -> ?CALL ;
|
m_to_op('CALL') -> ?CALL ;
|
||||||
m_to_op('CALL_T') -> ?CALL_T ;
|
m_to_op('CALL_T') -> ?CALL_T ;
|
||||||
m_to_op('CALL_R') -> ?CALL_R ;
|
m_to_op('CALL_R') -> ?CALL_R ;
|
||||||
@ -91,6 +95,7 @@ args(?PUSH) -> 1;
|
|||||||
args(?JUMP) -> 1;
|
args(?JUMP) -> 1;
|
||||||
args(?CALL) -> 1;
|
args(?CALL) -> 1;
|
||||||
args(?CALL_T) -> 1;
|
args(?CALL_T) -> 1;
|
||||||
|
args(?TUPLE) -> 1;
|
||||||
|
|
||||||
args(?JUMPIF) -> 2;
|
args(?JUMPIF) -> 2;
|
||||||
args(?CALL_R) -> 2;
|
args(?CALL_R) -> 2;
|
||||||
@ -112,6 +117,9 @@ args(?EGT) -> 3;
|
|||||||
args(?ELT) -> 3;
|
args(?ELT) -> 3;
|
||||||
args(?EQ) -> 3;
|
args(?EQ) -> 3;
|
||||||
args(?NEQ) -> 3;
|
args(?NEQ) -> 3;
|
||||||
|
|
||||||
|
args(?ELEMENT) -> 4;
|
||||||
|
|
||||||
args(_) -> 0. %% TODO do not allow this
|
args(_) -> 0. %% TODO do not allow this
|
||||||
|
|
||||||
end_bb(?RETURN) -> true;
|
end_bb(?RETURN) -> true;
|
||||||
|
31
test/asm_code/tuple.fate
Normal file
31
test/asm_code/tuple.fate
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
;;CONTRACT tuple
|
||||||
|
FUNCTION make_0tuple():{tuple, []}
|
||||||
|
TUPLE 0
|
||||||
|
RETURN
|
||||||
|
|
||||||
|
FUNCTION make_2tuple(integer, integer):{tuple, [integer, integer]}
|
||||||
|
PUSH arg0
|
||||||
|
PUSH arg1
|
||||||
|
TUPLE 2
|
||||||
|
RETURN
|
||||||
|
|
||||||
|
FUNCTION make_5tuple(integer, integer, integer, integer, integer):
|
||||||
|
{tuple, [integer, integer, integer, integer, integer]}
|
||||||
|
PUSH arg0
|
||||||
|
PUSH arg1
|
||||||
|
PUSH arg2
|
||||||
|
PUSH arg3
|
||||||
|
PUSH arg4
|
||||||
|
TUPLE 5
|
||||||
|
RETURN
|
||||||
|
|
||||||
|
FUNCTION element1(integer, integer): integer
|
||||||
|
PUSH arg0
|
||||||
|
PUSH arg1
|
||||||
|
TUPLE 2
|
||||||
|
ELEMENT integer a 1 a
|
||||||
|
RETURN
|
||||||
|
|
||||||
|
FUNCTION element({tuple, [integer, integer]}, integer): integer
|
||||||
|
ELEMENT integer a arg1 arg0
|
||||||
|
RETURN
|
Loading…
x
Reference in New Issue
Block a user