gmbytecode/src/aefa_asm_scan.xrl
2019-02-15 09:28:04 +01:00

192 lines
7.1 KiB
Erlang

%%% -*- erlang-indent-level:4; indent-tabs-mode: nil -*-
%%%-------------------------------------------------------------------
%%% @copyright (C) 2019, aeternity Anstalt
%%% @doc
%%% Handling FATE code.
%%% @end
%%% Created : 9 Jan 2019
%%%-------------------------------------------------------------------
Definitions.
DIGIT = [0-9]
HEXDIGIT = [0-9a-fA-F]
LOWER = [a-z_]
UPPER = [A-Z]
INT = {DIGIT}+
HEX = 0x{HEXDIGIT}+
HASH = #{HEXDIGIT}+
WS = [\000-\s]
ID = {LOWER}[a-zA-Z0-9_]*
Rules.
arg{INT} : {token, {arg, TokenLine, parse_arg(TokenChars)}}.
var{INT} : {token, {var, TokenLine, parse_var(TokenChars)}}.
a : {token, {stack, TokenLine, 0}}.
a{INT} : {token, {stack, TokenLine, parse_acc(TokenChars)}}.
true : {token, {boolean, TokenLine, true}}.
false : {token, {boolean, TokenLine, false}}.
RETURN : {token, {mnemonic, TokenLine, 'RETURN'}}.
RETURNR : {token, {mnemonic, TokenLine, 'RETURNR'}}.
CALL : {token, {mnemonic, TokenLine, 'CALL'}}.
FUNCTION : {token, {function, TokenLine, 'FUNCTION' }}.
NOP : {token, {mnemonic, TokenLine, 'NOP'}}.
CALL_R : {token, {mnemonic, TokenLine, 'CALL_R'}}.
CALL_T : {token, {mnemonic, TokenLine, 'CALL_T'}}.
CALL_TR : {token, {mnemonic, TokenLine, 'CALL_TR'}}.
JUMP : {token, {mnemonic, TokenLine, 'JUMP'}}.
JUMPIF : {token, {mnemonic, TokenLine, 'JUMPIF'}}.
SWITCH : {token, {mnemonic, TokenLine, 'SWITCH'}}.
PUSH : {token, {mnemonic, TokenLine, 'PUSH'}}.
DUP : {token, {mnemonic, TokenLine, 'DUP'}}.
POP : {token, {mnemonic, TokenLine, 'POP'}}.
STORE : {token, {mnemonic, TokenLine, 'STORE'}}.
ADD : {token, {mnemonic, TokenLine, 'ADD'}}.
MUL : {token, {mnemonic, TokenLine, 'MUL'}}.
SUB : {token, {mnemonic, TokenLine, 'SUB'}}.
DIV : {token, {mnemonic, TokenLine, 'DIV'}}.
MOD : {token, {mnemonic, TokenLine, 'MOD'}}.
POW : {token, {mnemonic, TokenLine, 'POW'}}.
INC : {token, {mnemonic, TokenLine, 'INC'}}.
DEC : {token, {mnemonic, TokenLine, 'DEC'}}.
LT : {token, {mnemonic, TokenLine, 'LT'}}.
GT : {token, {mnemonic, TokenLine, 'GT'}}.
EQ : {token, {mnemonic, TokenLine, 'EQ'}}.
ELT : {token, {mnemonic, TokenLine, 'ELT'}}.
EGT : {token, {mnemonic, TokenLine, 'EGT'}}.
NEQ : {token, {mnemonic, TokenLine, 'NEQ'}}.
AND : {token, {mnemonic, TokenLine, 'AND'}}.
OR : {token, {mnemonic, TokenLine, 'OR'}}.
NOT : {token, {mnemonic, TokenLine, 'NOT'}}.
TUPLE : {token, {mnemonic, TokenLine, 'TUPLE'}}.
ELEMENT : {token, {mnemonic, TokenLine, 'ELEMENT'}}.
MAP_EMPTY : {token, {mnemonic, TokenLine, 'MAP_EMPTY'}}.
MAP_LOOKUP : {token, {mnemonic, TokenLine, 'MAP_LOOKUP'}}.
MAP_LOOKUPD : {token, {mnemonic, TokenLine, 'MAP_LOOKUPD'}}.
MAP_UPDATE : {token, {mnemonic, TokenLine, 'MAP_UPDATE'}}.
MAP_MEMBER : {token, {mnemonic, TokenLine, 'MAP_MEMBER'}}.
MAP_DELETE : {token, {mnemonic, TokenLine, 'MAP_DELETE'}}.
MAP_FROM_LIST : {token, {mnemonic, TokenLine, 'MAP_FROM_LIST'}}.
NIL : {token, {mnemonic, TokenLine, 'NIL'}}.
IS_NIL : {token, {mnemonic, TokenLine, 'IS_NIL'}}.
CONS : {token, {mnemonic, TokenLine, 'CONS'}}.
HD : {token, {mnemonic, TokenLine, 'HD'}}.
TL : {token, {mnemonic, TokenLine, 'TL'}}.
LENGTH : {token, {mnemonic, TokenLine, 'LENGTH'}}.
STR_EQ : {token, {mnemonic, TokenLine, 'STR_EQ'}}.
STR_JOIN : {token, {mnemonic, TokenLine, 'STR_JOIN'}}.
INT_TO_STR : {token, {mnemonic, TokenLine, 'INT_TO_STR'}}.
ADDR_TO_STR : {token, {mnemonic, TokenLine, 'ADDR_TO_STR'}}.
STR_REVERSE : {token, {mnemonic, TokenLine, 'STR_REVERSE'}}.
INT_TO_ADDR : {token, {mnemonic, TokenLine, 'INT_TO_ADDR'}}.
VARIANT : {token, {mnemonic, TokenLine, 'VARIANT'}}.
VARIANT_TEST : {token, {mnemonic, TokenLine, 'VARIANT_TEST'}}.
VARIANT_ELEMENT : {token, {mnemonic, TokenLine, 'VARIANT_ELEMENT'}}.
BITS_NONE : {token, {mnemonic, TokenLine, 'BITS_NONE'}}.
BITS_ALL : {token, {mnemonic, TokenLine, 'BITS_ALL'}}.
BITS_SET : {token, {mnemonic, TokenLine, 'BITS_SET'}}.
BITS_CLEAR : {token, {mnemonic, TokenLine, 'BITS_CLEAR'}}.
BITS_TEST : {token, {mnemonic, TokenLine, 'BITS_TEST'}}.
BITS_SUM : {token, {mnemonic, TokenLine, 'BITS_SUM'}}.
BITS_OR : {token, {mnemonic, TokenLine, 'BITS_OR'}}.
BITS_AND : {token, {mnemonic, TokenLine, 'BITS_AND'}}.
BITS_DIFF : {token, {mnemonic, TokenLine, 'BITS_DIFF'}}.
ADDRESS : {token, {mnemonic, TokenLine, 'ADDRESS'}}.
BALANCE : {token, {mnemonic, TokenLine, 'BALANCE'}}.
ORIGIN : {token, {mnemonic, TokenLine, 'ORIGIN'}}.
CALLER : {token, {mnemonic, TokenLine, 'CALLER'}}.
GASPRICE : {token, {mnemonic, TokenLine, 'GASPRICE'}}.
BLOCKHASH : {token, {mnemonic, TokenLine, 'BLOCKHASH'}}.
BENEFICIARY : {token, {mnemonic, TokenLine, 'BENEFICIARY'}}.
TIMESTAMP : {token, {mnemonic, TokenLine, 'TIMESTAMP'}}.
NUMBER : {token, {mnemonic, TokenLine, 'NUMBER'}}.
DIFFICULTY : {token, {mnemonic, TokenLine, 'DIFFICULTY'}}.
GASLIMIT : {token, {mnemonic, TokenLine, 'GASLIMIT'}}.
GAS : {token, {mnemonic, TokenLine, 'GAS'}}.
LOG0 : {token, {mnemonic, TokenLine, 'LOG0'}}.
LOG1 : {token, {mnemonic, TokenLine, 'LOG1'}}.
LOG2 : {token, {mnemonic, TokenLine, 'LOG2'}}.
LOG3 : {token, {mnemonic, TokenLine, 'LOG3'}}.
LOG4 : {token, {mnemonic, TokenLine, 'LOG4'}}.
ABORT : {token, {mnemonic, TokenLine, 'ABORT'}}.
EXIT : {token, {mnemonic, TokenLine, 'EXIT'}}.
DEACTIVATE : {token, {mnemonic, TokenLine, 'DEACTIVATE'}}.
COMMENT : {token, {mnemonic, TokenLine, 'COMMENT'}}.
{ID} :
{token, {id, TokenLine, TokenChars}}.
{HEX} :
{token, {int, TokenLine, parse_hex(TokenChars)}}.
{INT} :
{token, {int, TokenLine, parse_int(TokenChars)}}.
{HASH} :
{token, {hash, TokenLine, parse_hash(TokenChars)}}.
%% Symbols
\-\> : {token, {'to', TokenLine}}.
\: : {token, {'to', TokenLine}}.
, : {token, {',', TokenLine}}.
\( : {token, {'(', TokenLine}}.
\) : {token, {')', TokenLine}}.
\[ : {token, {'[', TokenLine}}.
\] : {token, {']', TokenLine}}.
\{ : {token, {'{', TokenLine}}.
\} : {token, {'}', TokenLine}}.
\. : skip_token.
%% Whitespace ignore
{WS} : skip_token.
%% Comments (TODO: nested comments)
;;.* : skip_token.
. : {error, "Unexpected token: " ++ TokenChars}.
Erlang code.
-export([scan/1]).
-dialyzer({nowarn_function, yyrev/2}).
-ignore_xref([format_error/1, string/2, token/2, token/3, tokens/2, tokens/3]).
-include_lib("aebytecode/include/aefa_opcodes.hrl").
parse_hex("0x" ++ Chars) -> list_to_integer(Chars, 16).
parse_int(Chars) -> list_to_integer(Chars).
parse_arg("arg" ++ N) -> list_to_integer(N).
parse_var("var" ++ N) -> list_to_integer(N).
parse_acc("a" ++ N) -> list_to_integer(N).
parse_hash("#" ++ Chars) ->
N = list_to_integer(Chars, 16),
<<N:256>>.
scan(S) ->
string(S).