Packages

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

Current section

Files

Jump to
gwr src gwr@execution@stack.erl
Raw

src/gwr@execution@stack.erl

-module(gwr@execution@stack).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([create/0, length/1, push/2, peek/1, pop/1, pop_repeat/2]).
-export_type([stack/0, stack_entry/0, label/0, activation_frame/0, frame_state/0]).
-type stack() :: {stack, list(stack_entry())}.
-type stack_entry() :: {value_entry, gwr@execution@runtime:value()} |
{label_entry, label()} |
{activation_entry, activation_frame()}.
-type label() :: {label, integer(), list(gwr@syntax@instruction:instruction())}.
-type activation_frame() :: {activation_frame, integer(), frame_state()}.
-type frame_state() :: {frame_state,
list(gwr@execution@runtime:value()),
gwr@execution@runtime:module_instance()}.
-spec create() -> stack().
create() ->
{stack, []}.
-spec length(stack()) -> integer().
length(Stack) ->
erlang:length(erlang:element(2, Stack)).
-spec push(stack(), stack_entry()) -> stack().
push(Stack, New_entry) ->
{stack, lists:append(erlang:element(2, Stack), [New_entry])}.
-spec peek(stack()) -> gleam@option:option(stack_entry()).
peek(Stack) ->
gleam@option:from_result(gleam@list:last(erlang:element(2, Stack))).
-spec pop(stack()) -> {stack(), gleam@option:option(stack_entry())}.
pop(Stack) ->
{{stack, gleam@list:take(erlang:element(2, Stack), length(Stack) - 1)},
peek(Stack)}.
-spec pop_repeat(stack(), integer()) -> {stack(),
list(gleam@option:option(stack_entry()))}.
pop_repeat(Stack, Count) ->
gleam@iterator:fold(
gleam@iterator:range(1, Count),
{Stack, []},
fun(State, _) ->
{Stack@1, Results} = pop(erlang:element(1, State)),
{Stack@1, lists:append(erlang:element(2, State), [Results])}
end
).