Compare commits
2 Commits
947e05cdc8
...
0beab4e11d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0beab4e11d | ||
|
|
2dc0de78b5 |
5
arl.org
5
arl.org
@@ -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
|
This also simplifies type checking to just verifying each little
|
||||||
binding and operation.
|
binding and operation.
|
||||||
|
|
||||||
*** Examples
|
*** Examples
|
||||||
**** Basic example
|
**** Basic example
|
||||||
Consider the following ARL code:
|
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
|
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
|
figure out the type of whatever is pushed onto the stack by the
|
||||||
callable.
|
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
|
** TODO Code generator
|
||||||
[[file:src/arl/target-c/]]
|
[[file:src/arl/target-c/]]
|
||||||
|
|
||||||
|
|||||||
@@ -15,23 +15,23 @@
|
|||||||
/// Types the AST can encode
|
/// Types the AST can encode
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
AST_NODE_TYPE_PRIMITIVE = 0,
|
AST_NODE_TYPE_KNOWN = 0,
|
||||||
AST_NODE_TYPE_SYMBOL,
|
AST_NODE_TYPE_SYMBOL,
|
||||||
AST_NODE_TYPE_STRING,
|
AST_NODE_TYPE_STRING,
|
||||||
|
|
||||||
NUM_AST_NODE_TYPES,
|
NUM_AST_NODE_TYPES,
|
||||||
} ast_node_type_t;
|
} ast_node_type_t;
|
||||||
|
|
||||||
/// Primitives (values, callables, etc) as symbols
|
/// Known symbols - may reference callables or values.
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
AST_PRIM_NIL = 0,
|
AST_KNOWN_NIL = 0,
|
||||||
AST_PRIM_PUTSTR,
|
AST_KNOWN_PUTSTR,
|
||||||
|
|
||||||
NUM_AST_PRIMS,
|
NUM_AST_KNOWNS,
|
||||||
} ast_prim_t;
|
} 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
|
/// Node of the AST as a tagged union
|
||||||
typedef struct
|
typedef struct
|
||||||
@@ -40,13 +40,13 @@ typedef struct
|
|||||||
ast_node_type_t type;
|
ast_node_type_t type;
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
ast_prim_t as_prim;
|
ast_known_t as_known;
|
||||||
sv_t as_symbol;
|
sv_t as_symbol;
|
||||||
sv_t as_string;
|
sv_t as_string;
|
||||||
} value;
|
} value;
|
||||||
} ast_node_t;
|
} 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_symbol(u64 byte, sv_t symbol);
|
||||||
ast_node_t ast_node_string(u64 byte, sv_t string);
|
ast_node_t ast_node_string(u64 byte, sv_t string);
|
||||||
void ast_node_print(FILE *fp, ast_node_t *node);
|
void ast_node_print(FILE *fp, ast_node_t *node);
|
||||||
|
|||||||
@@ -18,7 +18,6 @@
|
|||||||
#include <arl/parser/ast.h>
|
#include <arl/parser/ast.h>
|
||||||
#include <arl/parser/parser.h>
|
#include <arl/parser/parser.h>
|
||||||
|
|
||||||
/// Parser
|
|
||||||
sv_t read_file(const char *filename)
|
sv_t read_file(const char *filename)
|
||||||
{
|
{
|
||||||
FILE *fp = fopen(filename, "rb");
|
FILE *fp = fopen(filename, "rb");
|
||||||
|
|||||||
@@ -9,25 +9,25 @@
|
|||||||
#include <arl/lib/vec.h>
|
#include <arl/lib/vec.h>
|
||||||
#include <arl/parser/ast.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";
|
return "nil";
|
||||||
case AST_PRIM_PUTSTR:
|
case AST_KNOWN_PUTSTR:
|
||||||
return "putstr";
|
return "putstr";
|
||||||
default:
|
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){
|
return (ast_node_t){
|
||||||
.byte_location = byte,
|
.byte_location = byte,
|
||||||
.type = AST_NODE_TYPE_PRIMITIVE,
|
.type = AST_NODE_TYPE_KNOWN,
|
||||||
.value = {.as_prim = primitive},
|
.value = {.as_known = known},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,8 +58,8 @@ void ast_node_print(FILE *fp, ast_node_t *node)
|
|||||||
}
|
}
|
||||||
switch (node->type)
|
switch (node->type)
|
||||||
{
|
{
|
||||||
case AST_NODE_TYPE_PRIMITIVE:
|
case AST_NODE_TYPE_KNOWN:
|
||||||
fprintf(fp, "PRIMITIVE(%s)", ast_prim_to_cstr(node->value.as_prim));
|
fprintf(fp, "KNOWN(%s)", ast_known_to_cstr(node->value.as_known));
|
||||||
break;
|
break;
|
||||||
case AST_NODE_TYPE_SYMBOL:
|
case AST_NODE_TYPE_SYMBOL:
|
||||||
fprintf(fp, "SYMBOL(" PR_SV ")", SV_FMT(node->value.as_symbol));
|
fprintf(fp, "SYMBOL(" PR_SV ")", SV_FMT(node->value.as_symbol));
|
||||||
|
|||||||
@@ -123,16 +123,16 @@ parse_err_t parse_symbol(parse_stream_t *stream, ast_node_t *ret)
|
|||||||
sv_t symbol =
|
sv_t symbol =
|
||||||
SV(current_contents.data, sv_while(current_contents, SYMBOL_CHARS));
|
SV(current_contents.data, sv_while(current_contents, SYMBOL_CHARS));
|
||||||
|
|
||||||
// see if symbol is one of the AST primitives we can parse AOT
|
// see if symbol is one of the already known symbols
|
||||||
static_assert(NUM_AST_PRIMS == 2, "Expected number of AST primitives");
|
static_assert(NUM_AST_KNOWNS == 2, "Expected number of AST KNOWN");
|
||||||
for (ast_prim_t i = 0; i < NUM_AST_PRIMS; ++i)
|
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 &&
|
if (strlen(possible_prim) == symbol.size &&
|
||||||
strncmp(possible_prim, symbol.data, symbol.size) == 0)
|
strncmp(possible_prim, symbol.data, symbol.size) == 0)
|
||||||
{
|
{
|
||||||
// Found a matching primitive
|
// Found a matching known symbol
|
||||||
*ret = ast_node_prim(stream->byte, i);
|
*ret = ast_node_known(stream->byte, i);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user