Generate tokens in scanner from definitions.
This commit is contained in:
parent
161b5a6106
commit
dd1a6a9c3d
1
.gitignore
vendored
1
.gitignore
vendored
@ -10,6 +10,7 @@ rel/example_project
|
||||
.rebar
|
||||
aeb_asm_scan.erl
|
||||
aeb_fate_asm_scan.erl
|
||||
aeb_fate_asm_scan.xrl
|
||||
_build/
|
||||
aefateasm
|
||||
include/aeb_fate_opcodes.hrl
|
||||
|
6
Makefile
6
Makefile
@ -4,10 +4,10 @@ REBAR ?= rebar3
|
||||
|
||||
all: local
|
||||
|
||||
local: src/aeb_fate_opcodes.erl src/aeb_fate_code.erl include/aeb_fate_opcodes.hrl
|
||||
local: src/aeb_fate_opcodes.erl src/aeb_fate_code.erl include/aeb_fate_opcodes.hrl src/aeb_fate_asm_scan.xrl
|
||||
@$(REBAR) as local release
|
||||
|
||||
console: src/aeb_fate_opcodes.erl src/aeb_fate_code.erl include/aeb_fate_opcodes.hrl
|
||||
console: local
|
||||
@$(REBAR) as local shell
|
||||
|
||||
clean:
|
||||
@ -34,7 +34,7 @@ test: local
|
||||
ebin/aeb_fate_generate_ops.beam: src/aeb_fate_generate_ops.erl ebin
|
||||
erlc -o $(dir $@) $<
|
||||
|
||||
src/aeb_fate_opcodes.erl src/aeb_fate_code.erl include/aeb_fate_opcodes.hrl: ebin/aeb_fate_generate_ops.beam
|
||||
src/aeb_fate_opcodes.erl src/aeb_fate_code.erl include/aeb_fate_opcodes.hrl src/aeb_fate_asm_scan.xrl: ebin/aeb_fate_generate_ops.beam
|
||||
erl -pa ebin/ -noshell -s aeb_fate_generate_ops gen_and_halt src/ include/
|
||||
|
||||
ebin:
|
||||
|
99
src/aeb_fate_asm_scan.template
Normal file
99
src/aeb_fate_asm_scan.template
Normal file
@ -0,0 +1,99 @@
|
||||
%%% -*- erlang-indent-level:4; indent-tabs-mode: nil -*-
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% @copyright (C) 2019, aeternity Anstalt
|
||||
%%% @doc
|
||||
%%% Handling FATE code.
|
||||
%%% @end
|
||||
###REPLACEWITHNOTE###
|
||||
%%%-------------------------------------------------------------------
|
||||
|
||||
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}}.
|
||||
|
||||
###REPLACEWITHOPTOKENS###
|
||||
|
||||
FUNCTION : {token, {function, TokenLine, 'FUNCTION' }}.
|
||||
|
||||
{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}}.
|
||||
|
||||
;;.* :
|
||||
{token, {comment, TokenLine, drop_prefix($;, TokenChars)}}.
|
||||
|
||||
\. : skip_token.
|
||||
|
||||
|
||||
%% Whitespace ignore
|
||||
{WS} : skip_token.
|
||||
|
||||
%% Comments (TODO: nested comments)
|
||||
|
||||
|
||||
. : {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/aeb_fate_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).
|
||||
|
||||
drop_prefix(C, [C|Rest]) ->
|
||||
drop_prefix(C, Rest);
|
||||
drop_prefix(_, Tail) -> Tail.
|
@ -1,207 +0,0 @@
|
||||
%%% -*- 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'}}.
|
||||
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_V2 : {token, {mnemonic, TokenLine, 'SWITCH_V2'}}.
|
||||
SWITCH_V3 : {token, {mnemonic, TokenLine, 'SWITCH_V3'}}.
|
||||
SWITCH_VN : {token, {mnemonic, TokenLine, 'SWITCH_VN'}}.
|
||||
|
||||
PUSH : {token, {mnemonic, TokenLine, 'PUSH'}}.
|
||||
DUP : {token, {mnemonic, TokenLine, 'DUP'}}.
|
||||
DUPA : {token, {mnemonic, TokenLine, 'DUPA'}}.
|
||||
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'}}.
|
||||
INCA : {token, {mnemonic, TokenLine, 'INCA'}}.
|
||||
DECA : {token, {mnemonic, TokenLine, 'DECA'}}.
|
||||
|
||||
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_NONEA : {token, {mnemonic, TokenLine, 'BITS_NONEA'}}.
|
||||
BITS_ALL : {token, {mnemonic, TokenLine, 'BITS_ALL'}}.
|
||||
BITS_ALLA : {token, {mnemonic, TokenLine, 'BITS_ALLA'}}.
|
||||
BITS_ALL_N : {token, {mnemonic, TokenLine, 'BITS_ALL_N'}}.
|
||||
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'}}.
|
||||
|
||||
FUNCTION : {token, {function, TokenLine, 'FUNCTION' }}.
|
||||
|
||||
{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}}.
|
||||
|
||||
;;.* :
|
||||
{token, {comment, TokenLine, drop_prefix($;, TokenChars)}}.
|
||||
|
||||
\. : skip_token.
|
||||
|
||||
|
||||
%% Whitespace ignore
|
||||
{WS} : skip_token.
|
||||
|
||||
%% Comments (TODO: nested comments)
|
||||
|
||||
|
||||
. : {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/aeb_fate_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).
|
||||
|
||||
drop_prefix(C, [C|Rest]) ->
|
||||
drop_prefix(C, Rest);
|
||||
drop_prefix(_, Tail) -> Tail.
|
@ -17,19 +17,20 @@ generate(Src, Include) ->
|
||||
HrlFile = Include ++ "aeb_fate_opcodes.hrl",
|
||||
generate_header_file(HrlFile, Ops),
|
||||
generate_opcodes_ops(aeb_fate_opcodes, HrlFile, Src, Ops),
|
||||
generate_code_ops(aeb_fate_code, Src, Ops).
|
||||
generate_code_ops(aeb_fate_code, Src, Ops),
|
||||
generate_scanner("aeb_fate_asm_scan.template", "aeb_fate_asm_scan.xrl", Src, Ops).
|
||||
|
||||
%% TODO: Some real gas numbers...
|
||||
ops_defs() ->
|
||||
%% Opname, Opcode, args, end_bb, gas, format, Constructor, Documentation
|
||||
[ { 'RETURN', 16#00, 0, true, 2, atomic, return, "Return from function call pop stack to arg0."}
|
||||
, { 'RETURNR', 16#01, 1, true, 2, [a], returnr, "Return from function call copy Arg0 to arg0."}
|
||||
, { 'CALL', 16#02, 1, true, 4, [is], call, "Call given function with args on stack."}
|
||||
, { 'CALL_R', 16#03, 2, true, 8, [a,is], call_r, "Remote call to given contract and function."}
|
||||
, { 'CALL_T', 16#04, 1, true, 4, [is], call_t, "Tail call to given function."}
|
||||
, { 'CALL_TR', 16#05, 2, true, 8, [a,is], call_tr, "Remote tail call to given contract and function."}
|
||||
, { 'JUMP', 16#06, 1, true, 3, [ii], jump, "Jump to a basic block."}
|
||||
, { 'JUMPIF', 16#07, 2, true, 4, [a,ii], jumpif, "Conditional jump to a basic block."}
|
||||
[ { 'RETURN', 16#00, 0, true, 2, atomic, return, "Return from function call pop stack to arg0. The type of the retun value has to match the return type of the function."}
|
||||
, { 'RETURNR', 16#01, 1, true, 2, [a], returnr, "Return from function call copy Arg0 to arg0. The type of the retun value has to match the return type of the function."}
|
||||
, { 'CALL', 16#02, 1, true, 4, [is], call, "Call given function with args on stack. The types of the arguments has to match the argument typs of the function."}
|
||||
, { 'CALL_R', 16#03, 2, true, 8, [a,is], call_r, "Remote call to given contract and function. The types of the arguments has to match the argument typs of the function."}
|
||||
, { 'CALL_T', 16#04, 1, true, 4, [is], call_t, "Tail call to given function. The types of the arguments has to match the argument typs of the function. And the return type of the called function has to match the type of the current function."}
|
||||
, { 'CALL_TR', 16#05, 2, true, 8, [a,is], call_tr, "Remote tail call to given contract and function. The types of the arguments has to match the argument typs of the function. And the return type of the called function has to match the type of the current function."}
|
||||
, { 'JUMP', 16#06, 1, true, 3, [ii], jump, "Jump to a basic block. The basic block has to exist in the current function."}
|
||||
, { 'JUMPIF', 16#07, 2, true, 4, [a,ii], jumpif, "Conditional jump to a basic block. If Arg0 then jump to Arg1."}
|
||||
, { 'SWITCH_V2', 16#08, 3, true, 4, [a,ii,ii], switch, "Conditional jump to a basic block on variant tag."}
|
||||
, { 'SWITCH_V3', 16#09, 4, true, 4, [a,ii,ii,ii], switch, "Conditional jump to a basic block on variant tag."}
|
||||
, { 'SWITCH_VN', 16#0a, 2, true, 4, [a,li], switch, "Conditional jump to a basic block on variant tag."}
|
||||
@ -372,3 +373,29 @@ expand_type(ii) -> "fate_arg_immediate(aeb_fate_data:fate_integer())";
|
||||
expand_type(li) -> "[fate_arg_immediate(aeb_fate_data:fate_integer())]";
|
||||
expand_type(t) -> "aeb_fate_data:fate_type_type()".
|
||||
|
||||
generate_scanner(TemplateFile, Outfile, Path, Ops) ->
|
||||
{ok, Template} = file:read_file(filename:join(Path,TemplateFile)),
|
||||
Tokens = lists:flatten([gen_token(Op) || Op <- Ops]),
|
||||
NewFile = insert_tokens_in_template(Template, Tokens),
|
||||
file:write_file(filename:join(Path, Outfile), NewFile).
|
||||
|
||||
gen_token(#{opname := OpName}) ->
|
||||
Name = atom_to_list(OpName),
|
||||
io_lib:format("~-28s: {token, {mnemonic, TokenLine, ~w}}.\n",
|
||||
[Name, OpName]).
|
||||
|
||||
insert_tokens_in_template(<<"###REPLACEWITHOPTOKENS###", Rest/binary >>, Tokens) ->
|
||||
[Tokens, Rest];
|
||||
insert_tokens_in_template(<<"###REPLACEWITHNOTE###", Rest/binary >>, Tokens) ->
|
||||
[
|
||||
"%%%\n"
|
||||
"%%% === === N O T E : This file is generated do not edit. === ===\n"
|
||||
"%%%\n"
|
||||
"%%% Source is in aeb_fate_generate_ops.erl\n"
|
||||
"%%% and aeb_fate_asm_scan.template"
|
||||
| insert_tokens_in_template(Rest, Tokens)];
|
||||
insert_tokens_in_template(<<B,Rest/binary>>, Tokens) ->
|
||||
[B|insert_tokens_in_template(Rest, Tokens)].
|
||||
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user