Packages

An experimental work-in-progress (WIP) WebAssembly runtime written in Gleam.

Current section

Files

Jump to
gwr src gwr@parser@instruction_parser.erl
Raw

src/gwr@parser@instruction_parser.erl

-module(gwr@parser@instruction_parser).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([parse_instruction/1, parse_expression/1]).
-spec parse_instruction(gwr@parser@binary_reader:binary_reader()) -> {ok,
{gwr@parser@binary_reader:binary_reader(),
gwr@syntax@instruction:instruction()}} |
{error, binary()}.
parse_instruction(Reader) ->
gleam@result:'try'(case gwr@parser@binary_reader:read(Reader, 1) of
{ok, {Reader@1, <<Opcode>>}} ->
{ok, {Reader@1, Opcode}};
{error, Reason} ->
{error,
<<"gwr/parser/instruction_parser.parse_instruction: couldn't read opcode: "/utf8,
Reason/binary>>};
_ ->
{error,
<<"gwr/parser/instruction_parser.parse_instruction: unknown error reading opcode"/utf8>>}
end, fun(_use0) ->
{Reader@2, Opcode@1} = _use0,
gleam@result:'try'(case Opcode@1 of
16#00 ->
{ok, {Reader@2, unreachable}};
16#01 ->
{ok, {Reader@2, no_op}};
16#20 ->
gleam@result:'try'(
gwr@parser@value_parser:parse_unsigned_leb128_integer(
Reader@2
),
fun(_use0@1) ->
{Reader@3, Local_index} = _use0@1,
{ok, {Reader@3, {local_get, Local_index}}}
end
);
16#6a ->
{ok, {Reader@2, i32_add}};
16#41 ->
gleam@result:'try'(
gwr@parser@value_parser:parse_uninterpreted_leb128_integer(
Reader@2
),
fun(_use0@2) ->
{Reader@4, Value} = _use0@2,
{ok, {Reader@4, {i32_const, Value}}}
end
);
16#0b ->
{ok, {Reader@2, 'end'}};
Unknown ->
{error,
<<<<"gwr/parser/instruction_parser.parse_instruction: unknown opcode \"0x"/utf8,
(gleam@int:to_base16(Unknown))/binary>>/binary,
"\""/utf8>>}
end, fun(_use0@3) ->
{Reader@5, Instruction} = _use0@3,
{ok, {Reader@5, Instruction}}
end)
end).
-spec parse_expression(gwr@parser@binary_reader:binary_reader()) -> {ok,
{gwr@parser@binary_reader:binary_reader(),
list(gwr@syntax@instruction:instruction())}} |
{error, binary()}.
parse_expression(Reader) ->
gleam@result:'try'(
gwr@parser@binary_reader:get_remaining(Reader),
fun(Data) ->
Data_length = erlang:byte_size(Data),
gleam@result:'try'(
gleam@iterator:fold(
gleam@iterator:range(1, Data_length),
{ok, {Reader, []}},
fun(State, _) ->
gleam@result:'try'(
State,
fun(_use0) ->
{Reader@1, Current_expression} = _use0,
gleam@bool:guard(
gleam@list:last(Current_expression) =:= {ok,
'end'},
State,
fun() ->
gleam@bool:guard(
not gwr@parser@binary_reader:can_read(
Reader@1
)
andalso (gleam@list:last(
Current_expression
)
/= {ok, 'end'}),
{error,
<<"gwr/parser/instruction_parser.parse_expression: an expression must terminate with a End instruction"/utf8>>},
fun() ->
gleam@result:'try'(
parse_instruction(Reader@1),
fun(_use0@1) ->
{Reader@2, Instruction} = _use0@1,
{ok,
{Reader@2,
lists:append(
Current_expression,
[Instruction]
)}}
end
)
end
)
end
)
end
)
end
),
fun(_use0@2) ->
{Reader@3, Expression} = _use0@2,
{ok, {Reader@3, Expression}}
end
)
end
).