Compare commits

..

2 Commits

Author SHA1 Message Date
Aryadev Chavali
0beab4e11d *: small changes 2026-01-28 07:35:45 +00:00
Aryadev Chavali
2dc0de78b5 parser/ast|parser: PRIMITIVE -> KNOWN
Primitive is a bit of a word conflict here; primitives are what we'd
expect our callables to be named eventually.  However, these parser
"primitives" are just well known symbols that we want to optimise the
representation of for later stages.  Thus, KNOWN is a bit better for
signalling intent then PRIMITIVE is.
2026-01-28 07:35:39 +00:00
5 changed files with 30 additions and 26 deletions

View File

@@ -48,6 +48,7 @@ bindings, with the final expression being a reference to some binding.
This also simplifies type checking to just verifying each little
binding and operation.
*** Examples
**** Basic example
Consider the following ARL code:
@@ -145,6 +146,10 @@ Define how we can type check arguments on the stack against the types
a callable expects for its inputs. In the same vein, we also need to
figure out the type of whatever is pushed onto the stack by the
callable.
*** TODO Use SSA for user level bindings
[[https://en.wikipedia.org/wiki/Static_single-assignment_form][Static
single-assignment form]] is something we should use when we introduce
for user level bindings.
** TODO Code generator
[[file:src/arl/target-c/]]

View File

@@ -15,23 +15,23 @@
/// Types the AST can encode
typedef enum
{
AST_NODE_TYPE_PRIMITIVE = 0,
AST_NODE_TYPE_KNOWN = 0,
AST_NODE_TYPE_SYMBOL,
AST_NODE_TYPE_STRING,
NUM_AST_NODE_TYPES,
} ast_node_type_t;
/// Primitives (values, callables, etc) as symbols
/// Known symbols - may reference callables or values.
typedef enum
{
AST_PRIM_NIL = 0,
AST_PRIM_PUTSTR,
AST_KNOWN_NIL = 0,
AST_KNOWN_PUTSTR,
NUM_AST_PRIMS,
} ast_prim_t;
NUM_AST_KNOWNS,
} ast_known_t;
const char *ast_prim_to_cstr(ast_prim_t);
const char *ast_known_to_cstr(ast_known_t);
/// Node of the AST as a tagged union
typedef struct
@@ -40,13 +40,13 @@ typedef struct
ast_node_type_t type;
union
{
ast_prim_t as_prim;
ast_known_t as_known;
sv_t as_symbol;
sv_t as_string;
} value;
} ast_node_t;
ast_node_t ast_node_prim(u64 byte, ast_prim_t primitive);
ast_node_t ast_node_known(u64 byte, ast_known_t known);
ast_node_t ast_node_symbol(u64 byte, sv_t symbol);
ast_node_t ast_node_string(u64 byte, sv_t string);
void ast_node_print(FILE *fp, ast_node_t *node);

View File

@@ -18,7 +18,6 @@
#include <arl/parser/ast.h>
#include <arl/parser/parser.h>
/// Parser
sv_t read_file(const char *filename)
{
FILE *fp = fopen(filename, "rb");

View File

@@ -9,25 +9,25 @@
#include <arl/lib/vec.h>
#include <arl/parser/ast.h>
const char *ast_prim_to_cstr(ast_prim_t prim)
const char *ast_known_to_cstr(ast_known_t known)
{
switch (prim)
switch (known)
{
case AST_PRIM_NIL:
case AST_KNOWN_NIL:
return "nil";
case AST_PRIM_PUTSTR:
case AST_KNOWN_PUTSTR:
return "putstr";
default:
FAIL("Unexpected AST primitive value: %d\n", prim);
FAIL("Unexpected AST_KNOWN value: %d\n", known);
}
}
ast_node_t ast_node_prim(u64 byte, ast_prim_t primitive)
ast_node_t ast_node_known(u64 byte, ast_known_t known)
{
return (ast_node_t){
.byte_location = byte,
.type = AST_NODE_TYPE_PRIMITIVE,
.value = {.as_prim = primitive},
.type = AST_NODE_TYPE_KNOWN,
.value = {.as_known = known},
};
}
@@ -58,8 +58,8 @@ void ast_node_print(FILE *fp, ast_node_t *node)
}
switch (node->type)
{
case AST_NODE_TYPE_PRIMITIVE:
fprintf(fp, "PRIMITIVE(%s)", ast_prim_to_cstr(node->value.as_prim));
case AST_NODE_TYPE_KNOWN:
fprintf(fp, "KNOWN(%s)", ast_known_to_cstr(node->value.as_known));
break;
case AST_NODE_TYPE_SYMBOL:
fprintf(fp, "SYMBOL(" PR_SV ")", SV_FMT(node->value.as_symbol));

View File

@@ -123,16 +123,16 @@ parse_err_t parse_symbol(parse_stream_t *stream, ast_node_t *ret)
sv_t symbol =
SV(current_contents.data, sv_while(current_contents, SYMBOL_CHARS));
// see if symbol is one of the AST primitives we can parse AOT
static_assert(NUM_AST_PRIMS == 2, "Expected number of AST primitives");
for (ast_prim_t i = 0; i < NUM_AST_PRIMS; ++i)
// see if symbol is one of the already known symbols
static_assert(NUM_AST_KNOWNS == 2, "Expected number of AST KNOWN");
for (ast_known_t i = 0; i < NUM_AST_KNOWNS; ++i)
{
const char *possible_prim = ast_prim_to_cstr(i);
const char *possible_prim = ast_known_to_cstr(i);
if (strlen(possible_prim) == symbol.size &&
strncmp(possible_prim, symbol.data, symbol.size) == 0)
{
// Found a matching primitive
*ret = ast_node_prim(stream->byte, i);
// Found a matching known symbol
*ret = ast_node_known(stream->byte, i);
goto end;
}
}