Files
gsc/include/gsc.hrl
T
Peter Harpending f548c7d88d moving sfc over here
2026-06-01 16:44:33 -07:00

162 lines
4.5 KiB
Erlang

% This is a header file that contains sfc's record types
%
% This is in order to
% 1. share records across modules; and,
% 2. allow external modules to just use the sfc records
%-------------------------------------------------------
% API Types: sfc internal token representation
%
% -export_type([
% sf_token_type/0
% sf_token/0
% ]).
%-------------------------------------------------------
%
-type sfc_token_type()
:: bcom % /* ... */
| lcom % //
| ws % whitespace
% literals
| char % 'a'
| string % "foo"
| int10 % 69_420
| int16 % 0xDEAD_BEEF
| bytes % #DEAD_BEEF
| ak % ak_ABC
| ct % ct_ABC
| sg % sg_ABC
% kwds/variables/etc
| id % foo, foo_bar, foo_bar'baz' _'foo'
| con % Foo, Foo_Bar, FooBar
| qid % Foo.Bar.baz
| qcon % Foo.Bar.Baz
| tvar % 'foo, 'foo_bar, '_'foo'_'bar'''
% kwds ops and punct are all collapsed by
% so_scan:scan down to eg {'contract', {420, 69}}
% where {420, 69} is the source location
% these are three different parsers
| kwd % contract, interface, payable, etc
| op % "=!<>+-*/:&|?~@^"
| punct % ".." | oneof(",.;()[]{}")
% kwds and punct are kind of the same thing
% but i'll keep them separate now for my own sanity. ok
% i guess op or symbol or whatever is fine.
%
% not going to overthink. if having them separate
% becomes an issue it's easy enough to collapse. harder
% to separate afterward if collapsing is wrong.
.
-type sfc_pos() :: {Line :: pos_integer(), Col :: pos_integer()}.
-record(sfc_token,
{type :: sfc_token_type(),
pos :: sfc_pos(),
string :: string()}).
-type sfc_token() :: #sfc_token{}.
% tokens are in essence the "chunk boundaries" of
% the file
%
% because we have semantic whitespace, we have to be
% careful about block declarations, because we don't
% have an explicit open/close block token. blocks can
% be closed in one of two ways:
%
% 1. a new block at a previous indent level:
% switch(foo)
% // block starts here
% Bar => bar()
% Baz => baz()
% quux() // ends because indent level
% 2. it's part of some type of list:
%
% [switch(foo)
% // block starts here
% Bar => bar()
% Baz => baz(), // ends here
% switch(bizz)
% // block starts here
% Bar => bar()
% Baz => baz()]
%
% in order to avoid speculatively inserting virtual
% close tokens, at least on first write-out, we're
% going to disambiguate list notions right away
% token groups
% lists = (_, _, _)
% | [_, _, _]
% | {_, _, _}
%-record(sfc_ast1_block,
% {indent = none :: none | pos_integer(),
% decls = none :: [sfc_ast1_decl()]}).
%
%-type sfc_ast() ::
%
%-type sfc_list_group() :: {'(', [sfc_token()], ')'}
% | {'[', [sfc_token()], ']'}
% | {'{', [sfc_token()], '}'}
% | {proof,
% .
% @doc
% this one is very specific so it deserves its own
% record type: unterminated block comments at the end
% of files. these are ok in legacy sophia, so we have to
% specifically account for this error
-record(sfc_err_bcom_unterminated,
{prev_tokens :: [sfc_token()],
break_pos :: sfc_pos(),
rest :: string()}).
-record(sfc_err_no_tokmatch,
{prev_tokens :: [sfc_token()],
break_pos :: sfc_pos(),
rest :: string()}).
-record(sfc_err_delims,
{past :: [sfc_token()],
open_stack :: [sfc_token()],
bad_close :: sfc_token(),
future :: [sfc_token()]}).
% FIXME
-record(sfc_err_nyi, {}).
-record(sfc_err_empty_file, {}).
%-record(src_parse_error,
% {atom = none :: none | atom(),
% string =
%j-record(sfc_err_gulp_ct,
%j {gulped ::
% @doc
% generic placeholder error for now
-record(sfc_err,
{atom :: atom(),
string = none :: none | iolist(),
extra = none :: none | any()}).
% @doc all errors SFC can return conveniently listed in
% one place
-type sfc_err() :: #sfc_err_bcom_unterminated{}
| #sfc_err_no_tokmatch{}
| #sfc_err_nyi{}
| #sfc_err_empty_file{}
| #sfc_err{}.
%% FIXME
-type sfc_ast() :: any().