Files
gsc/include/gsc.hrl
T
Peter Harpending 9da6dbf18d wip name cleanups
2026-06-01 18:00:37 -07:00

146 lines
4.1 KiB
Erlang

% This is a header file that contains gsc's record types
%
% This is in order to
% 1. share records across modules; and,
% 2. allow external modules to just use the gsc records
-type tk_shape()
:: 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 tk_pos() :: {Line :: pos_integer(), Col :: pos_integer()}.
-record(tk,
{shape :: tk_shape(),
pos :: tk_pos(),
str :: string()}).
-type tk() :: #tk{}.
% 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(gsc_ast1_block,
% {indent = none :: none | pos_integer(),
% decls = none :: [gsc_ast1_decl()]}).
%
%-type gsc_ast() ::
%
%-type gsc_list_group() :: {'(', [tk()], ')'}
% | {'[', [tk()], ']'}
% | {'{', [tk()], '}'}
% | {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(gsc_err_bcom_unterminated,
{prev_tokens :: [tk()],
break_pos :: gsc_pos(),
rest :: string()}).
-record(gsc_err_no_tokmatch,
{prev_tokens :: [tk()],
break_pos :: gsc_pos(),
rest :: string()}).
-record(gsc_err_delims,
{past :: [tk()],
open_stack :: [tk()],
bad_close :: tk(),
future :: [tk()]}).
% FIXME
-record(gsc_err_nyi, {}).
-record(gsc_err_empty_file, {}).
%-record(src_parse_error,
% {atom = none :: none | atom(),
% string =
%j-record(gsc_err_gulp_ct,
%j {gulped ::
% @doc
% generic placeholder error for now
-record(gsc_err,
{atom :: atom(),
string = none :: none | iolist(),
extra = none :: none | any()}).
% @doc all errors SFC can return conveniently listed in
% one place
-type gsc_err() :: #gsc_err_bcom_unterminated{}
| #gsc_err_no_tokmatch{}
| #gsc_err_nyi{}
| #gsc_err_empty_file{}
| #gsc_err{}.