From fe5a05ba971190e29637390fb98ec8179885e60c Mon Sep 17 00:00:00 2001 From: Erik Stenman Date: Fri, 15 Feb 2019 08:57:46 +0100 Subject: [PATCH] Handle tuple instructions. --- src/aefa_asm.erl | 25 +++++++++++++++++++++++++ src/aefa_opcodes.erl | 8 ++++++++ test/asm_code/tuple.fate | 31 +++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+) create mode 100644 test/asm_code/tuple.fate diff --git a/src/aefa_asm.erl b/src/aefa_asm.erl index 0553af1..8ea5c9f 100644 --- a/src/aefa_asm.erl +++ b/src/aefa_asm.erl @@ -168,6 +168,21 @@ deserialize(<<>>, #{ function := F , code => #{} , functions => Funs#{F => FunctionCode}}. +deserialize_op(?ELEMENT, Rest, Code) -> + {Type, Rest2} = deserialize_type(Rest), + <> = 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) -> OpName = aefa_opcodes:mnemonic(Op), case aefa_opcodes:args(Op) of @@ -278,6 +293,12 @@ serialize_code([ {Arg0Type, Arg0} | Rest]) -> [ArgSpec , serialize_data(Arg0Type, Arg0) | serialize_code(Rest)]; +serialize_code([ ?ELEMENT + , ResType + | Rest]) -> + [?ELEMENT, + serialize_type(ResType) + | serialize_code(Rest)]; serialize_code([B|Rest]) -> [B | serialize_code(Rest)]; serialize_code([]) -> []. @@ -352,6 +373,10 @@ to_bytecode([{function,_line, 'FUNCTION'}|Rest], Address, Env, Code, Opts) -> Env2 = insert_fun(Address, Code, Env), {Fun, Rest2} = to_fun_def(Rest), 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) -> OpCode = aefa_opcodes:m_to_op(Op), to_bytecode(Rest, Address, Env, [OpCode|Code], Opts); diff --git a/src/aefa_opcodes.erl b/src/aefa_opcodes.erl index 0d4cc56..47730ee 100644 --- a/src/aefa_opcodes.erl +++ b/src/aefa_opcodes.erl @@ -51,6 +51,8 @@ mnemonic(?ELT) -> 'ELT' ; mnemonic(?EQ) -> 'EQ' ; mnemonic(?NEQ) -> 'NEQ' ; mnemonic(?STORE) -> 'STORE' ; +mnemonic(?TUPLE) -> 'TUPLE' ; +mnemonic(?ELEMENT) -> 'ELEMENT' ; mnemonic(OP) -> {OP, nothandled}. m_to_op('NOP') -> ?NOP ; @@ -77,6 +79,8 @@ m_to_op('EGT') -> ?EGT ; m_to_op('EQ') -> ?EQ ; m_to_op('NEQ') -> ?NEQ ; m_to_op('STORE') -> ?STORE ; +m_to_op('TUPLE') -> ?TUPLE ; +m_to_op('ELEMENT') -> ?ELEMENT ; m_to_op('CALL') -> ?CALL ; m_to_op('CALL_T') -> ?CALL_T ; m_to_op('CALL_R') -> ?CALL_R ; @@ -91,6 +95,7 @@ args(?PUSH) -> 1; args(?JUMP) -> 1; args(?CALL) -> 1; args(?CALL_T) -> 1; +args(?TUPLE) -> 1; args(?JUMPIF) -> 2; args(?CALL_R) -> 2; @@ -112,6 +117,9 @@ args(?EGT) -> 3; args(?ELT) -> 3; args(?EQ) -> 3; args(?NEQ) -> 3; + +args(?ELEMENT) -> 4; + args(_) -> 0. %% TODO do not allow this end_bb(?RETURN) -> true; diff --git a/test/asm_code/tuple.fate b/test/asm_code/tuple.fate new file mode 100644 index 0000000..573166b --- /dev/null +++ b/test/asm_code/tuple.fate @@ -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