162 lines
4.5 KiB
Erlang
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().
|
|
|
|
|