moving sfc over here

This commit is contained in:
Peter Harpending
2026-06-01 16:44:33 -07:00
parent 177978d184
commit f548c7d88d
15 changed files with 3534 additions and 19 deletions
+140 -19
View File
@@ -1,23 +1,144 @@
%%% @doc
%%% Gajumaru Sophia Compiler: gsc
%%%
%%% This module is currently named `gsc', but you may want to change that.
%%% Remember that changing the name in `-module()' below requires renaming
%%% this file, and it is recommended to run `zx update .app` in the main
%%% project directory to make sure the ebin/gsc.app file stays in
%%% sync with the project whenever you add, remove or rename a module.
%%% @end
% @doc bikeshed proctrastination head into vim warmup thing
% sophia compiler from scratch by PRH
%
% based on original sophia compiler
%
% parse layers:
% 1. sfc_tokenizer: SrcStr -> (Tokens | SigTokens)
%
% SigTokens = not comment/whitespace
%
% layers:
% a. sfc_strmatch : matches string shapes
% b. sfc_so_scan : converts to so_scan shapes
%
% 2. sfc_ast: SigTokens -> AST
%
% terminology:
%
% - `slurp`/`barf` borrowed from emacs paredit mode:
%
% slurp : (a b) c -> (a b c)
% barf : (a b c) -> a (b c)
%
% * `slurp` usually involves *transforming* input
% into a new type (e.g. slurp a token from src
% string); think of slurp as a verb meaning to
% consume and then digest
% * `barf` basically means blindly splitting off
% input
%
% @end
-module(gsc).
-vsn("0.1.0").
-author("Peter Harpending <peterharpending@qpq.swiss>").
-copyright("Peter Harpending <peterharpending@qpq.swiss>").
-license("GPL-3.0-only").
-export([hello/0]).
% TODO:
% - barf for outputs, slurp for inputs
% - architecture needs more careful thought but only after something works
% - too fuzzy right now
% - possibly:
% - rename parser layers sequentially:
% - sfc_
-module(sfc).
-spec hello() -> ok.
-export_type([
token/0
]).
hello() ->
io:format("~p (~p) says \"Hello!\"~n", [self(), ?MODULE]).
-export([
sigtokens_from_file/1,
sigtokens_from_string/1,
tokens_from_file/1,
tokens_from_string/1,
ast_from_file/1,
ast_from_string/1,
ast_from_tokens/1
]).
-include("$sfc_include/sfc.hrl").
%-----------------------------------------
% types
%-----------------------------------------
-type token() :: sfc_token().
%-----------------------------------------
% functions
%-----------------------------------------
sigtokens_from_file(X) ->
case tokens_from_file(X) of
{ok, Y} -> {ok, sfc_tokens:filter_significant(Y)};
Err -> Err
end.
sigtokens_from_string(X) ->
case tokens_from_string(X) of
{ok, Y} -> {ok, sfc_tokens:filter_significant(Y)};
Err -> Err
end.
-spec tokens_from_file(FilePath) -> Perhaps
when FilePath :: string(),
Perhaps :: {ok, Tokens}
| {error, sfc_err() | any()},
Tokens :: [sfc_token()].
tokens_from_file(FilePath) ->
case file:read_file(FilePath) of
{ok, FBytes} -> tokens_from_string(FBytes);
Error -> Error
end.
-spec tokens_from_string(SrcStr) -> Result
when SrcStr :: string(),
Result :: {ok, Tokens}
| {error, sfc_err()},
Tokens :: [sfc_token()].
tokens_from_string(SrcStr) ->
sfc_tokens:tokens(SrcStr).
-spec ast_from_file(FilePath) -> Perhaps
when FilePath :: string(),
Perhaps :: {ok, AST} | {error, sfc_err()},
AST :: sfc_ast().
ast_from_file(FilePath) ->
case file:read_file(FilePath) of
{ok, FileBytes} -> ast_from_string(FileBytes);
Error -> Error
end.
-spec ast_from_string(SrcStr) -> Perhaps
when SrcStr :: string(),
Perhaps :: {ok, AST} | {error, sfc_err()},
AST :: sfc_ast().
ast_from_string(SrcStr) ->
case sfc_tokens:significant_tokens(SrcStr) of
{ok, SigTks} -> ast_from_tokens(SigTks);
Error -> Error
end.
-spec ast_from_tokens(SrcTokens) -> Perhaps
when SrcTokens :: [sfc_token()],
Perhaps :: {ok, AST} | {error, sfc_err()},
AST :: sfc_ast().
ast_from_tokens(Tks) ->
SigTks = sfc_tokens:filter_significant(Tks),
case sfc_ast:gulp_file(SigTks) of
{gulp, AST} -> {ok, AST};
Error -> Error
end.