Add Core compiler interface
This commit is contained in:
73
base.cpp
73
base.cpp
@@ -138,6 +138,7 @@ typedef double F64;
|
|||||||
#define JOIN(X,Y) JOIN1(X,Y)
|
#define JOIN(X,Y) JOIN1(X,Y)
|
||||||
#define string_expand(x) (int)x.len, x.str
|
#define string_expand(x) (int)x.len, x.str
|
||||||
|
|
||||||
|
#define CORE_STRINGS
|
||||||
struct String{
|
struct String{
|
||||||
U8 *str;
|
U8 *str;
|
||||||
S64 len;
|
S64 len;
|
||||||
@@ -154,78 +155,6 @@ global String string_null = {(U8 *)"null", 4};
|
|||||||
#include "stb_sprintf.h"
|
#include "stb_sprintf.h"
|
||||||
#define snprintf stbsp_snprintf
|
#define snprintf stbsp_snprintf
|
||||||
|
|
||||||
|
|
||||||
union Vec2 {
|
|
||||||
struct { F32 x, y; };
|
|
||||||
struct { F32 width, height; };
|
|
||||||
F32 p[2];
|
|
||||||
};
|
|
||||||
|
|
||||||
union Vec3 {
|
|
||||||
struct{ F32 x, y, z; };
|
|
||||||
struct{ F32 r, g, b; };
|
|
||||||
struct{ Vec2 xy; F32 z_; };
|
|
||||||
struct{ F32 x_; Vec2 yz; };
|
|
||||||
F32 p[3];
|
|
||||||
};
|
|
||||||
|
|
||||||
union Vec4 {
|
|
||||||
struct{ F32 x, y, z, w; };
|
|
||||||
struct{ F32 r, g, b, a; };
|
|
||||||
struct{ Vec2 xy; Vec2 zw; };
|
|
||||||
struct{ Vec2 xy_; F32 width, height; };
|
|
||||||
struct{ Vec3 xyz; F32 w_; };
|
|
||||||
struct{ F32 x_; Vec3 yzw; };
|
|
||||||
struct{ Vec3 rgb; F32 a_; };
|
|
||||||
F32 p[4];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Mat4 {
|
|
||||||
F32 p[4][4];
|
|
||||||
};
|
|
||||||
|
|
||||||
union Vec1I {
|
|
||||||
S32 x;
|
|
||||||
S32 p[1];
|
|
||||||
};
|
|
||||||
|
|
||||||
union Vec2I {
|
|
||||||
struct { S32 x, y; };
|
|
||||||
struct { S32 width, height; };
|
|
||||||
S32 p[2];
|
|
||||||
};
|
|
||||||
|
|
||||||
union Vec3I {
|
|
||||||
struct { S32 x, y, z; };
|
|
||||||
struct { S32 r, g, b; };
|
|
||||||
struct { Vec2I xy; S32 z_; };
|
|
||||||
struct { S32 x_; Vec2I yz; };
|
|
||||||
S32 p[3];
|
|
||||||
};
|
|
||||||
|
|
||||||
union Vec4I {
|
|
||||||
struct { S32 x, y, z, w; };
|
|
||||||
struct { S32 r, g, b, a; };
|
|
||||||
struct { Vec2I xy; Vec2I zw; };
|
|
||||||
struct { Vec2I xy_; S32 width, height; };
|
|
||||||
struct { Vec3I xyz; S32 w_; };
|
|
||||||
struct { S32 x_; Vec3I yzw; };
|
|
||||||
struct { Vec3I rgb; S32 a_; };
|
|
||||||
S32 p[4];
|
|
||||||
};
|
|
||||||
|
|
||||||
union Rect2 {
|
|
||||||
struct {F32 min_x, min_y, max_x, max_y;};
|
|
||||||
struct { Vec2 min; Vec2 max; };
|
|
||||||
F32 p[4];
|
|
||||||
};
|
|
||||||
|
|
||||||
union Rect2I {
|
|
||||||
struct { S32 min_x, min_y, max_x, max_y;};
|
|
||||||
struct { Vec2I min; Vec2I max; };
|
|
||||||
S32 p[4];
|
|
||||||
};
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Utilities
|
// Utilities
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|||||||
1714
base_math.cpp
1714
base_math.cpp
File diff suppressed because it is too large
Load Diff
@@ -5,7 +5,7 @@ rem cl main.cpp -I.. user32.lib
|
|||||||
clang core_main.cpp -O0 -Wall -Wno-unused-function -fno-exceptions -fdiagnostics-absolute-paths -g -o main.exe -Wl,user32.lib
|
clang core_main.cpp -O0 -Wall -Wno-unused-function -fno-exceptions -fdiagnostics-absolute-paths -g -o main.exe -Wl,user32.lib
|
||||||
rem ubuntu run clang core_main.cpp -O0 -Wall -Wno-unused-function -fno-exceptions -fdiagnostics-absolute-paths -g -o core.out
|
rem ubuntu run clang core_main.cpp -O0 -Wall -Wno-unused-function -fno-exceptions -fdiagnostics-absolute-paths -g -o core.out
|
||||||
|
|
||||||
main.exe -testing
|
rem main.exe -testing
|
||||||
|
|
||||||
rem echo Building arms race
|
rem echo Building arms race
|
||||||
rem call examples/arms_race/build_arms_race.bat
|
rem call examples/arms_race/build_arms_race.bat
|
||||||
|
|||||||
@@ -1,13 +1,4 @@
|
|||||||
struct Token;
|
struct Token;
|
||||||
struct BigInt
|
|
||||||
{
|
|
||||||
unsigned digit_count;
|
|
||||||
bool is_negative;
|
|
||||||
union {
|
|
||||||
uint64_t digit;
|
|
||||||
uint64_t *digits;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
enum CmpRes
|
enum CmpRes
|
||||||
|
|||||||
327
core_ast.cpp
327
core_ast.cpp
@@ -1,332 +1,5 @@
|
|||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// AST
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
enum Ast_Kind: U32{
|
|
||||||
AST_NONE,
|
|
||||||
|
|
||||||
AST_NAMESPACE,
|
|
||||||
|
|
||||||
AST_MODULE,
|
|
||||||
AST_FILE,
|
|
||||||
AST_SCOPE,
|
|
||||||
AST_VALUE,
|
|
||||||
AST_CAST,
|
|
||||||
AST_IDENT,
|
|
||||||
AST_INDEX,
|
|
||||||
AST_UNARY,
|
|
||||||
AST_BINARY,
|
|
||||||
AST_CALL_ITEM,
|
|
||||||
AST_CALL,
|
|
||||||
|
|
||||||
AST_CONSTANT_ASSERT,
|
|
||||||
AST_RUNTIME_ASSERT,
|
|
||||||
AST_SIZE_OF,
|
|
||||||
AST_LENGTH_OF,
|
|
||||||
AST_ALIGN_OF,
|
|
||||||
AST_TYPE_OF,
|
|
||||||
|
|
||||||
AST_SWITCH,
|
|
||||||
AST_SWITCH_CASE,
|
|
||||||
AST_VAR_UNPACK,
|
|
||||||
AST_BREAK,
|
|
||||||
AST_COMPOUND,
|
|
||||||
AST_TYPE,
|
|
||||||
AST_VAR,
|
|
||||||
AST_CONST,
|
|
||||||
AST_POINTER,
|
|
||||||
AST_ARRAY,
|
|
||||||
AST_FOR,
|
|
||||||
AST_IF,
|
|
||||||
AST_IF_NODE,
|
|
||||||
AST_RETURN,
|
|
||||||
AST_BLOCK,
|
|
||||||
AST_PASS,
|
|
||||||
AST_LAMBDA,
|
|
||||||
AST_LAMBDA_EXPR,
|
|
||||||
AST_LAMBDA_ARG,
|
|
||||||
AST_ENUM,
|
|
||||||
AST_ENUM_MEMBER,
|
|
||||||
AST_STRUCT,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef U32 Ast_Flag;
|
|
||||||
enum{
|
|
||||||
AST_EXPR = bit_flag(1),
|
|
||||||
AST_STMT = bit_flag(2),
|
|
||||||
AST_STRICT = bit_flag(3),
|
|
||||||
AST_AGGREGATE = bit_flag(4),
|
|
||||||
AST_AGGREGATE_CHILD = bit_flag(5),
|
|
||||||
AST_ATOM = bit_flag(7),
|
|
||||||
AST_FOREIGN = bit_flag(8),
|
|
||||||
AST_DECL = bit_flag(9),
|
|
||||||
AST_GLOBAL = bit_flag(10),
|
|
||||||
AST_FLAG = bit_flag(11),
|
|
||||||
AST_VAR_IS_CONST = bit_flag(12),
|
|
||||||
AST_OPERATOR_OVERLOAD = bit_flag(13),
|
|
||||||
AST_IS_LVALUE = bit_flag(14),
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Ast{
|
|
||||||
U64 di; // Debug id, shouldn't ever be used in the program
|
|
||||||
Token *pos;
|
|
||||||
|
|
||||||
Ast_Kind kind;
|
|
||||||
Ast_Scope *parent_scope;
|
|
||||||
Ast_Flag flags;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Ast_Type;
|
|
||||||
struct Ast_Expr:Ast{
|
|
||||||
Ast_Type *resolved_type;
|
|
||||||
Ast_Decl *resolved_operator_overload;
|
|
||||||
union{
|
|
||||||
Ast_Type *index_original_type;
|
|
||||||
Ast_Type *cast_after_type;
|
|
||||||
Ast_Type *dot_access_step_resolution;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Ast_Atom: Ast_Expr{
|
|
||||||
// We have a field type here
|
|
||||||
// it has a different purpose from the
|
|
||||||
// resolved_type of Ast_Expr, it describes
|
|
||||||
// the inherent type of a value
|
|
||||||
//
|
|
||||||
// resolved_type is a solid type that
|
|
||||||
// can be use during code generation
|
|
||||||
// it cannot be untyped. (or at least thats the hope :)
|
|
||||||
/*#import meta
|
|
||||||
meta.inline_value_fields()
|
|
||||||
*/
|
|
||||||
union {
|
|
||||||
Value value;
|
|
||||||
struct {
|
|
||||||
Ast_Type *type;
|
|
||||||
Ast_Decl *resolved_decl;
|
|
||||||
union {
|
|
||||||
bool bool_val;
|
|
||||||
F64 f64_val;
|
|
||||||
Intern_String intern_val;
|
|
||||||
BigInt big_int_val;
|
|
||||||
Ast_Type *type_val;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
/*END*/
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef U32 Ast_Call_Item_Flag;
|
|
||||||
enum{
|
|
||||||
CALL_INDEX = bit_flag(1),
|
|
||||||
CALL_NAME = bit_flag(2),
|
|
||||||
CALL_INCLUDED= bit_flag(4),
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Ast_Call_Item: Ast_Expr{
|
|
||||||
Ast_Call_Item_Flag call_flags;
|
|
||||||
S32 resolved_index;
|
|
||||||
Ast_Expr *item;
|
|
||||||
union {
|
|
||||||
Ast_Atom *name;
|
|
||||||
Ast_Expr *index;
|
|
||||||
};
|
|
||||||
Intern_String resolved_name;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Ast_Lambda;
|
|
||||||
struct Ast_Call: Ast_Expr{
|
|
||||||
union{
|
|
||||||
Ast_Expr *name;
|
|
||||||
Ast_Expr *typespec;
|
|
||||||
};
|
|
||||||
Array<Ast_Call_Item *> exprs;
|
|
||||||
Ast_Decl *resolved_decl;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Ast_Var_Unpack: Ast_Expr{
|
|
||||||
Array<Ast_Decl *> vars;
|
|
||||||
Ast_Expr *expr;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Ast_Unary: Ast_Expr{
|
|
||||||
Token_Kind op;
|
|
||||||
Ast_Expr *expr;
|
|
||||||
U64 padding[2]; // For folding constants into atoms
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Ast_Index: Ast_Expr{
|
|
||||||
Ast_Expr *expr;
|
|
||||||
Ast_Expr *index;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Ast_Binary: Ast_Expr{
|
|
||||||
Token_Kind op;
|
|
||||||
Ast_Expr *left;
|
|
||||||
Ast_Expr *right;
|
|
||||||
Ast_Type *before_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Ast_Builtin: Ast_Expr{
|
|
||||||
Ast_Expr *expr;
|
|
||||||
Intern_String assert_message;
|
|
||||||
U64 padding[1]; // For folding constants into atoms
|
|
||||||
};
|
|
||||||
|
|
||||||
// Problem: We are parsing out of order, in the middle of parsing a function
|
|
||||||
// we can jump down a different function, we cant therfore use global map.
|
|
||||||
// Each scope needs to have it's checked locals list. To lookup syms we need to
|
|
||||||
// look into global scope and to the locals list.
|
|
||||||
//
|
|
||||||
|
|
||||||
struct Ast_Return: Ast{
|
|
||||||
Ast_Type *resolved_type;
|
|
||||||
Array<Ast_Expr *> expr;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Ast_If_Node: Ast{
|
|
||||||
Ast_Expr *expr ;
|
|
||||||
Ast_Scope *scope;
|
|
||||||
Ast_Binary*init;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Ast_If: Ast{
|
|
||||||
Array<Ast_If_Node *> ifs;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Ast_Pass: Ast{};
|
|
||||||
struct Ast_Break: Ast{};
|
|
||||||
|
|
||||||
struct Ast_For: Ast{
|
|
||||||
Ast_Expr *init;
|
|
||||||
Ast_Expr *cond;
|
|
||||||
Ast_Expr *iter;
|
|
||||||
Ast_Scope *scope;
|
|
||||||
|
|
||||||
Ast_Decl *array_traversal_var;
|
|
||||||
bool is_array_traversal;
|
|
||||||
bool is_also_slice_traversal;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Ast_Lambda : Ast_Expr {
|
|
||||||
Array<Ast_Decl *> args;
|
|
||||||
Array<Ast_Expr *> ret;
|
|
||||||
Ast_Scope *scope;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Ast_Array: Ast_Expr{
|
|
||||||
Ast_Expr *base;
|
|
||||||
Ast_Expr *expr;
|
|
||||||
U64 padding[2];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Ast_Switch_Case: Ast{
|
|
||||||
Array<Ast_Expr *> labels;
|
|
||||||
Ast_Scope *scope;
|
|
||||||
B32 fallthrough;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Ast_Switch: Ast{
|
|
||||||
Ast_Expr *value;
|
|
||||||
Array<Ast_Switch_Case *> cases;
|
|
||||||
Ast_Scope *default_scope;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
How does current declaration order resolver works:
|
|
||||||
* First we put all the global declarations into the global scope (when parsing) all unresolved
|
|
||||||
* All the types are declared INCOMPLETE and RESOLVED
|
|
||||||
* We descent the tree by resolving each of the named declarations, we resolve by their name
|
|
||||||
When we start resolving we set RESOLVING flag and when we complete RESOLVED flag
|
|
||||||
and put into ordered list
|
|
||||||
* When we meet a symbol (named declaration) while descending the tree,
|
|
||||||
we resolve that symbol instead before resolving current declaration.
|
|
||||||
* When we meet a declaration that requires size of a type - field access, var assignment,
|
|
||||||
we need to call "complete_type", it sets COMPLETING flag.
|
|
||||||
This call resolves all the dependencies of that type,
|
|
||||||
sets size of type and marks it as COMPLETE and puts into ordered list.
|
|
||||||
If it detects COMPLETING while
|
|
||||||
resolving, we got a circular dependency. That might happen when we have
|
|
||||||
that struct without pointer inside itself.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct Ast_Scope: Ast{
|
|
||||||
String debug_name; // Dont use
|
|
||||||
List<Ast_Scope *> implicit_imports;
|
|
||||||
List<Ast_Decl *> decls;
|
|
||||||
Array<Ast *> stmts;
|
|
||||||
|
|
||||||
U32 visit_id;
|
|
||||||
U32 scope_id;
|
|
||||||
Ast_Scope *file; // Self referential for file and module
|
|
||||||
Ast_Module *module;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum Ast_Module_State{
|
|
||||||
MODULE_REGISTERED,
|
|
||||||
MODULE_PARSED,
|
|
||||||
MODULE_RESOLVED,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Ast_Module: Ast_Scope{
|
|
||||||
Ast_Module_State state;
|
|
||||||
String absolute_base_folder;
|
|
||||||
String absolute_file_path;
|
|
||||||
List<Ast_File *> all_loaded_files;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Ast_File: Ast_Scope{
|
|
||||||
String absolute_base_folder;
|
|
||||||
String absolute_file_path;
|
|
||||||
String filecontent;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum Ast_Decl_State{
|
|
||||||
DECL_NOT_RESOLVED,
|
|
||||||
DECL_RESOLVED,
|
|
||||||
DECL_RESOLVED_TYPE,
|
|
||||||
DECL_RESOLVING,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Ast_Decl: Ast{
|
|
||||||
Ast_Decl_State state;
|
|
||||||
Intern_String name;
|
|
||||||
Intern_String unique_name; // For code generation, currently only present on lambdas
|
|
||||||
|
|
||||||
U64 operator_overload_arguments_hash;
|
|
||||||
Operator_Info *overload_op_info;
|
|
||||||
|
|
||||||
Ast_Scope *scope;
|
|
||||||
Ast_Expr *typespec;
|
|
||||||
union{
|
|
||||||
Ast_Expr *expr;
|
|
||||||
Ast_Lambda *lambda;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*#import meta
|
|
||||||
meta.inline_value_fields()
|
|
||||||
*/
|
|
||||||
union {
|
|
||||||
Value value;
|
|
||||||
struct {
|
|
||||||
Ast_Type *type;
|
|
||||||
Ast_Decl *resolved_decl;
|
|
||||||
union {
|
|
||||||
bool bool_val;
|
|
||||||
F64 f64_val;
|
|
||||||
Intern_String intern_val;
|
|
||||||
BigInt big_int_val;
|
|
||||||
Ast_Type *type_val;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
/*END*/
|
|
||||||
};
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// AST Constructors beginning with expressions
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
#define AST_NEW(T,ikind,ipos,iflags) \
|
#define AST_NEW(T,ikind,ipos,iflags) \
|
||||||
Ast_##T *result = arena_push_type(pctx->perm, Ast_##T, AF_ZeroMemory);\
|
Ast_##T *result = arena_push_type(pctx->perm, Ast_##T, AF_ZeroMemory);\
|
||||||
result->flags = iflags; \
|
result->flags = iflags; \
|
||||||
|
|||||||
122
core_compiler.h
122
core_compiler.h
@@ -1,127 +1,5 @@
|
|||||||
struct Ast_Scope;
|
|
||||||
struct Ast_Decl;
|
|
||||||
struct Ast_File_Namespace;
|
|
||||||
struct Ast_File;
|
|
||||||
struct Ast_Module;
|
|
||||||
struct Ast_Type;
|
|
||||||
struct Ast;
|
|
||||||
struct Ast_Expr;
|
|
||||||
|
|
||||||
|
|
||||||
enum Token_Kind{
|
|
||||||
TK_End,
|
|
||||||
|
|
||||||
/*#
|
|
||||||
import meta
|
|
||||||
for i in meta.token_kinds:
|
|
||||||
print(" TK_" + i[0] + ",")
|
|
||||||
*/
|
|
||||||
TK_Mul,
|
|
||||||
TK_Div,
|
|
||||||
TK_Mod,
|
|
||||||
TK_LeftShift,
|
|
||||||
TK_RightShift,
|
|
||||||
TK_FirstMul = TK_Mul,
|
|
||||||
TK_LastMul = TK_RightShift,
|
|
||||||
TK_Add,
|
|
||||||
TK_Sub,
|
|
||||||
TK_FirstAdd = TK_Add,
|
|
||||||
TK_LastAdd = TK_Sub,
|
|
||||||
TK_Equals,
|
|
||||||
TK_LesserThenOrEqual,
|
|
||||||
TK_GreaterThenOrEqual,
|
|
||||||
TK_LesserThen,
|
|
||||||
TK_GreaterThen,
|
|
||||||
TK_NotEquals,
|
|
||||||
TK_FirstCompare = TK_Equals,
|
|
||||||
TK_LastCompare = TK_NotEquals,
|
|
||||||
TK_BitAnd,
|
|
||||||
TK_BitOr,
|
|
||||||
TK_BitXor,
|
|
||||||
TK_And,
|
|
||||||
TK_Or,
|
|
||||||
TK_FirstLogical = TK_BitAnd,
|
|
||||||
TK_LastLogical = TK_Or,
|
|
||||||
TK_Neg,
|
|
||||||
TK_Not,
|
|
||||||
TK_Decrement,
|
|
||||||
TK_Increment,
|
|
||||||
TK_PostDecrement,
|
|
||||||
TK_PostIncrement,
|
|
||||||
TK_Assign,
|
|
||||||
TK_ColonAssign,
|
|
||||||
TK_DivAssign,
|
|
||||||
TK_MulAssign,
|
|
||||||
TK_ModAssign,
|
|
||||||
TK_SubAssign,
|
|
||||||
TK_AddAssign,
|
|
||||||
TK_AndAssign,
|
|
||||||
TK_OrAssign,
|
|
||||||
TK_XorAssign,
|
|
||||||
TK_LeftShiftAssign,
|
|
||||||
TK_RightShiftAssign,
|
|
||||||
TK_FirstAssign = TK_Assign,
|
|
||||||
TK_LastAssign = TK_RightShiftAssign,
|
|
||||||
TK_OpenParen,
|
|
||||||
TK_CloseParen,
|
|
||||||
TK_OpenBrace,
|
|
||||||
TK_CloseBrace,
|
|
||||||
TK_OpenBracket,
|
|
||||||
TK_CloseBracket,
|
|
||||||
TK_Comma,
|
|
||||||
TK_Pound,
|
|
||||||
TK_Question,
|
|
||||||
TK_ThreeDots,
|
|
||||||
TK_Semicolon,
|
|
||||||
TK_Dot,
|
|
||||||
TK_TwoDots,
|
|
||||||
TK_NewLine,
|
|
||||||
TK_Colon,
|
|
||||||
TK_DoubleColon,
|
|
||||||
TK_At,
|
|
||||||
TK_Arrow,
|
|
||||||
TK_ExprSizeof,
|
|
||||||
TK_DocComment,
|
|
||||||
TK_Comment,
|
|
||||||
TK_Identifier,
|
|
||||||
TK_UnicodeLit,
|
|
||||||
TK_StringLit,
|
|
||||||
TK_Error,
|
|
||||||
TK_Float,
|
|
||||||
TK_Integer,
|
|
||||||
TK_Keyword,
|
|
||||||
/*END*/
|
|
||||||
|
|
||||||
TK_Pointer = TK_Mul,
|
|
||||||
TK_Dereference = TK_BitAnd,
|
|
||||||
|
|
||||||
OPEN_SCOPE = 128,
|
|
||||||
CLOSE_SCOPE,
|
|
||||||
SAME_SCOPE,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Token{
|
|
||||||
Token_Kind kind;
|
|
||||||
U32 di; // debug_id
|
|
||||||
union{
|
|
||||||
String string;
|
|
||||||
struct{U8 *str; S64 len;};
|
|
||||||
};
|
|
||||||
|
|
||||||
union {
|
|
||||||
U32 unicode;
|
|
||||||
BigInt int_val;
|
|
||||||
F64 f64_val;
|
|
||||||
String error_val;
|
|
||||||
Intern_String intern_val;
|
|
||||||
S64 indent;
|
|
||||||
};
|
|
||||||
|
|
||||||
Intern_String file;
|
|
||||||
S32 line;
|
|
||||||
U8 *line_begin;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Lex_Stream{
|
struct Lex_Stream{
|
||||||
String stream;
|
String stream;
|
||||||
S64 iter;
|
S64 iter;
|
||||||
|
|||||||
597
core_compiler_interface.hpp
Normal file
597
core_compiler_interface.hpp
Normal file
@@ -0,0 +1,597 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
struct Ast;
|
||||||
|
struct Ast_Scope;
|
||||||
|
struct Ast_Decl;
|
||||||
|
struct Ast_File_Namespace;
|
||||||
|
struct Ast_File;
|
||||||
|
struct Ast_Module;
|
||||||
|
struct Ast_Lambda;
|
||||||
|
struct Ast_Type;
|
||||||
|
struct Ast_Expr;
|
||||||
|
|
||||||
|
#ifndef CORE_STRINGS
|
||||||
|
#define CORE_STRINGS
|
||||||
|
struct String{
|
||||||
|
uint8_t *str;
|
||||||
|
int64_t len;
|
||||||
|
};
|
||||||
|
|
||||||
|
union Intern_String{ // Basically just String
|
||||||
|
String s;
|
||||||
|
struct{
|
||||||
|
uint8_t *str;
|
||||||
|
int64_t len;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum Token_Kind{
|
||||||
|
TK_End,
|
||||||
|
|
||||||
|
/*#
|
||||||
|
import meta
|
||||||
|
for i in meta.token_kinds:
|
||||||
|
print(" TK_" + i[0] + ",")
|
||||||
|
*/
|
||||||
|
TK_Mul,
|
||||||
|
TK_Div,
|
||||||
|
TK_Mod,
|
||||||
|
TK_LeftShift,
|
||||||
|
TK_RightShift,
|
||||||
|
TK_FirstMul = TK_Mul,
|
||||||
|
TK_LastMul = TK_RightShift,
|
||||||
|
TK_Add,
|
||||||
|
TK_Sub,
|
||||||
|
TK_FirstAdd = TK_Add,
|
||||||
|
TK_LastAdd = TK_Sub,
|
||||||
|
TK_Equals,
|
||||||
|
TK_LesserThenOrEqual,
|
||||||
|
TK_GreaterThenOrEqual,
|
||||||
|
TK_LesserThen,
|
||||||
|
TK_GreaterThen,
|
||||||
|
TK_NotEquals,
|
||||||
|
TK_FirstCompare = TK_Equals,
|
||||||
|
TK_LastCompare = TK_NotEquals,
|
||||||
|
TK_BitAnd,
|
||||||
|
TK_BitOr,
|
||||||
|
TK_BitXor,
|
||||||
|
TK_And,
|
||||||
|
TK_Or,
|
||||||
|
TK_FirstLogical = TK_BitAnd,
|
||||||
|
TK_LastLogical = TK_Or,
|
||||||
|
TK_Neg,
|
||||||
|
TK_Not,
|
||||||
|
TK_Decrement,
|
||||||
|
TK_Increment,
|
||||||
|
TK_PostDecrement,
|
||||||
|
TK_PostIncrement,
|
||||||
|
TK_Assign,
|
||||||
|
TK_ColonAssign,
|
||||||
|
TK_DivAssign,
|
||||||
|
TK_MulAssign,
|
||||||
|
TK_ModAssign,
|
||||||
|
TK_SubAssign,
|
||||||
|
TK_AddAssign,
|
||||||
|
TK_AndAssign,
|
||||||
|
TK_OrAssign,
|
||||||
|
TK_XorAssign,
|
||||||
|
TK_LeftShiftAssign,
|
||||||
|
TK_RightShiftAssign,
|
||||||
|
TK_FirstAssign = TK_Assign,
|
||||||
|
TK_LastAssign = TK_RightShiftAssign,
|
||||||
|
TK_OpenParen,
|
||||||
|
TK_CloseParen,
|
||||||
|
TK_OpenBrace,
|
||||||
|
TK_CloseBrace,
|
||||||
|
TK_OpenBracket,
|
||||||
|
TK_CloseBracket,
|
||||||
|
TK_Comma,
|
||||||
|
TK_Pound,
|
||||||
|
TK_Question,
|
||||||
|
TK_ThreeDots,
|
||||||
|
TK_Semicolon,
|
||||||
|
TK_Dot,
|
||||||
|
TK_TwoDots,
|
||||||
|
TK_NewLine,
|
||||||
|
TK_Colon,
|
||||||
|
TK_DoubleColon,
|
||||||
|
TK_At,
|
||||||
|
TK_Arrow,
|
||||||
|
TK_ExprSizeof,
|
||||||
|
TK_DocComment,
|
||||||
|
TK_Comment,
|
||||||
|
TK_Identifier,
|
||||||
|
TK_UnicodeLit,
|
||||||
|
TK_StringLit,
|
||||||
|
TK_Error,
|
||||||
|
TK_Float,
|
||||||
|
TK_Integer,
|
||||||
|
TK_Keyword,
|
||||||
|
/*END*/
|
||||||
|
|
||||||
|
TK_Pointer = TK_Mul,
|
||||||
|
TK_Dereference = TK_BitAnd,
|
||||||
|
|
||||||
|
OPEN_SCOPE = 128,
|
||||||
|
CLOSE_SCOPE,
|
||||||
|
SAME_SCOPE,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BigInt {
|
||||||
|
unsigned digit_count;
|
||||||
|
bool is_negative;
|
||||||
|
union {
|
||||||
|
uint64_t digit;
|
||||||
|
uint64_t *digits;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Token{
|
||||||
|
Token_Kind kind;
|
||||||
|
uint32_t di; // debug_id
|
||||||
|
union{
|
||||||
|
String string;
|
||||||
|
struct{
|
||||||
|
uint8_t *str;
|
||||||
|
int64_t len;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
union {
|
||||||
|
uint32_t unicode;
|
||||||
|
BigInt int_val;
|
||||||
|
double f64_val;
|
||||||
|
String error_val;
|
||||||
|
Intern_String intern_val;
|
||||||
|
int64_t indent;
|
||||||
|
};
|
||||||
|
|
||||||
|
Intern_String file;
|
||||||
|
int32_t line;
|
||||||
|
uint8_t *line_begin;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Ast_Type_Kind{
|
||||||
|
TYPE_NONE,
|
||||||
|
TYPE_S64, // FIRST_NUMERIC
|
||||||
|
TYPE_S32,
|
||||||
|
TYPE_S16,
|
||||||
|
TYPE_S8 ,
|
||||||
|
TYPE_INT,
|
||||||
|
TYPE_CHAR,
|
||||||
|
TYPE_U64,
|
||||||
|
TYPE_U32,
|
||||||
|
TYPE_U16,
|
||||||
|
TYPE_U8 ,
|
||||||
|
TYPE_F32,
|
||||||
|
TYPE_F64,
|
||||||
|
TYPE_POINTER,
|
||||||
|
TYPE_BOOL, // LAST_NUMERIC
|
||||||
|
TYPE_STRING,
|
||||||
|
TYPE_VOID,
|
||||||
|
TYPE_ARRAY,
|
||||||
|
TYPE_LAMBDA,
|
||||||
|
TYPE_STRUCT,
|
||||||
|
TYPE_UNION,
|
||||||
|
TYPE_ENUM,
|
||||||
|
TYPE_TYPE,
|
||||||
|
TYPE_SLICE,
|
||||||
|
TYPE_TUPLE,
|
||||||
|
|
||||||
|
TYPE_COMPLETING,
|
||||||
|
TYPE_INCOMPLETE,
|
||||||
|
TYPE_UNTYPED_BOOL, // FIRST_TYPED_NUMERIC, FIRST_NUMERIC
|
||||||
|
TYPE_UNTYPED_INT,
|
||||||
|
TYPE_UNTYPED_FLOAT, // LAST_TYPED_NUMERIC
|
||||||
|
TYPE_UNTYPED_STRING,
|
||||||
|
|
||||||
|
TYPE_UNTYPED_FIRST = TYPE_UNTYPED_BOOL,
|
||||||
|
TYPE_UNTYPED_LAST = TYPE_UNTYPED_STRING,
|
||||||
|
|
||||||
|
TYPE_UNTYPED_FIRST_NUMERIC = TYPE_UNTYPED_BOOL,
|
||||||
|
TYPE_UNTYPED_LAST_NUMERIC = TYPE_UNTYPED_FLOAT,
|
||||||
|
|
||||||
|
TYPE_FIRST_NUMERIC = TYPE_S64,
|
||||||
|
TYPE_LAST_NUMERIC = TYPE_BOOL,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Value {
|
||||||
|
/*#import meta
|
||||||
|
print(meta.value_struct_content)
|
||||||
|
*/
|
||||||
|
Ast_Type *type;
|
||||||
|
Ast_Decl *resolved_decl;
|
||||||
|
union {
|
||||||
|
bool bool_val;
|
||||||
|
double f64_val;
|
||||||
|
Intern_String intern_val;
|
||||||
|
BigInt big_int_val;
|
||||||
|
Ast_Type *type_val;
|
||||||
|
};
|
||||||
|
/*END*/
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Ast_Resolved_Member{
|
||||||
|
Intern_String name;
|
||||||
|
int32_t offset;
|
||||||
|
bool visited;
|
||||||
|
/*#import meta
|
||||||
|
meta.inline_value_fields()
|
||||||
|
*/
|
||||||
|
union {
|
||||||
|
Value value;
|
||||||
|
struct {
|
||||||
|
Ast_Type *type;
|
||||||
|
Ast_Decl *resolved_decl;
|
||||||
|
union {
|
||||||
|
bool bool_val;
|
||||||
|
double f64_val;
|
||||||
|
Intern_String intern_val;
|
||||||
|
BigInt big_int_val;
|
||||||
|
Ast_Type *type_val;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
/*END*/
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Ast_Type{
|
||||||
|
Ast_Type_Kind kind;
|
||||||
|
int32_t size;
|
||||||
|
int32_t align;
|
||||||
|
int32_t is_unsigned;
|
||||||
|
int32_t type_id;
|
||||||
|
int32_t padding;
|
||||||
|
|
||||||
|
Ast *ast;
|
||||||
|
union{
|
||||||
|
Ast_Type *base;
|
||||||
|
struct{
|
||||||
|
Ast_Type *base;
|
||||||
|
int32_t size;
|
||||||
|
// @note: if you have array with size "[32]"
|
||||||
|
// you still want to pass that array into
|
||||||
|
// a function that expects an array of size "[]"
|
||||||
|
// so we want also should check this
|
||||||
|
uint64_t slice_hash;
|
||||||
|
}arr;
|
||||||
|
struct{
|
||||||
|
Array<Ast_Resolved_Member> members;
|
||||||
|
}agg;
|
||||||
|
struct{
|
||||||
|
Ast_Type * ret;
|
||||||
|
Array<Ast_Type *> args;
|
||||||
|
uint64_t hash_without_ret;
|
||||||
|
}func;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Ast_Kind: uint32_t{
|
||||||
|
AST_NONE,
|
||||||
|
|
||||||
|
AST_NAMESPACE,
|
||||||
|
|
||||||
|
AST_MODULE,
|
||||||
|
AST_FILE,
|
||||||
|
AST_SCOPE,
|
||||||
|
AST_VALUE,
|
||||||
|
AST_CAST,
|
||||||
|
AST_IDENT,
|
||||||
|
AST_INDEX,
|
||||||
|
AST_UNARY,
|
||||||
|
AST_BINARY,
|
||||||
|
AST_CALL_ITEM,
|
||||||
|
AST_CALL,
|
||||||
|
|
||||||
|
AST_CONSTANT_ASSERT,
|
||||||
|
AST_RUNTIME_ASSERT,
|
||||||
|
AST_SIZE_OF,
|
||||||
|
AST_LENGTH_OF,
|
||||||
|
AST_ALIGN_OF,
|
||||||
|
AST_TYPE_OF,
|
||||||
|
|
||||||
|
AST_SWITCH,
|
||||||
|
AST_SWITCH_CASE,
|
||||||
|
AST_VAR_UNPACK,
|
||||||
|
AST_BREAK,
|
||||||
|
AST_COMPOUND,
|
||||||
|
AST_TYPE,
|
||||||
|
AST_VAR,
|
||||||
|
AST_CONST,
|
||||||
|
AST_POINTER,
|
||||||
|
AST_ARRAY,
|
||||||
|
AST_FOR,
|
||||||
|
AST_IF,
|
||||||
|
AST_IF_NODE,
|
||||||
|
AST_RETURN,
|
||||||
|
AST_BLOCK,
|
||||||
|
AST_PASS,
|
||||||
|
AST_LAMBDA,
|
||||||
|
AST_LAMBDA_EXPR,
|
||||||
|
AST_LAMBDA_ARG,
|
||||||
|
AST_ENUM,
|
||||||
|
AST_ENUM_MEMBER,
|
||||||
|
AST_STRUCT,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef uint32_t Ast_Flag;
|
||||||
|
enum{
|
||||||
|
AST_EXPR = 1ull << 1,
|
||||||
|
AST_STMT = 1ull << 2,
|
||||||
|
AST_STRICT = 1ull << 3,
|
||||||
|
AST_AGGREGATE = 1ull << 4,
|
||||||
|
AST_AGGREGATE_CHILD = 1ull << 5,
|
||||||
|
AST_ATOM = 1ull << 7,
|
||||||
|
AST_FOREIGN = 1ull << 8,
|
||||||
|
AST_DECL = 1ull << 9,
|
||||||
|
AST_GLOBAL = 1ull << 10,
|
||||||
|
AST_FLAG = 1ull << 11,
|
||||||
|
AST_VAR_IS_CONST = 1ull << 12,
|
||||||
|
AST_OPERATOR_OVERLOAD = 1ull << 13,
|
||||||
|
AST_IS_LVALUE = 1ull << 14,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Ast{
|
||||||
|
uint64_t di; // Debug id, shouldn't ever be used in the program
|
||||||
|
Token *pos;
|
||||||
|
|
||||||
|
Ast_Kind kind;
|
||||||
|
Ast_Scope *parent_scope;
|
||||||
|
Ast_Flag flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Ast_Expr:Ast{
|
||||||
|
Ast_Type *resolved_type;
|
||||||
|
Ast_Decl *resolved_operator_overload;
|
||||||
|
union{
|
||||||
|
Ast_Type *index_original_type;
|
||||||
|
Ast_Type *cast_after_type;
|
||||||
|
Ast_Type *dot_access_step_resolution;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Ast_Atom: Ast_Expr{
|
||||||
|
// We have a field type here
|
||||||
|
// it has a different purpose from the
|
||||||
|
// resolved_type of Ast_Expr, it describes
|
||||||
|
// the inherent type of a value
|
||||||
|
//
|
||||||
|
// resolved_type is a solid type that
|
||||||
|
// can be use during code generation
|
||||||
|
// it cannot be untyped. (or at least thats the hope :)
|
||||||
|
/*#import meta
|
||||||
|
meta.inline_value_fields()
|
||||||
|
*/
|
||||||
|
union {
|
||||||
|
Value value;
|
||||||
|
struct {
|
||||||
|
Ast_Type *type;
|
||||||
|
Ast_Decl *resolved_decl;
|
||||||
|
union {
|
||||||
|
bool bool_val;
|
||||||
|
double f64_val;
|
||||||
|
Intern_String intern_val;
|
||||||
|
BigInt big_int_val;
|
||||||
|
Ast_Type *type_val;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
/*END*/
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef uint32_t Ast_Call_Item_Flag;
|
||||||
|
enum{
|
||||||
|
CALL_INDEX = 1ull << 1,
|
||||||
|
CALL_NAME = 1ull << 2,
|
||||||
|
CALL_INCLUDED= 1ull << 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Ast_Call_Item: Ast_Expr{
|
||||||
|
Ast_Call_Item_Flag call_flags;
|
||||||
|
int32_t resolved_index;
|
||||||
|
Ast_Expr *item;
|
||||||
|
union {
|
||||||
|
Ast_Atom *name;
|
||||||
|
Ast_Expr *index;
|
||||||
|
};
|
||||||
|
Intern_String resolved_name;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Ast_Call: Ast_Expr{
|
||||||
|
union{
|
||||||
|
Ast_Expr *name;
|
||||||
|
Ast_Expr *typespec;
|
||||||
|
};
|
||||||
|
Array<Ast_Call_Item *> exprs;
|
||||||
|
Ast_Decl *resolved_decl;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Ast_Var_Unpack: Ast_Expr{
|
||||||
|
Array<Ast_Decl *> vars;
|
||||||
|
Ast_Expr *expr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Ast_Unary: Ast_Expr{
|
||||||
|
Token_Kind op;
|
||||||
|
Ast_Expr *expr;
|
||||||
|
uint64_t padding[2]; // For folding constants into atoms
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Ast_Index: Ast_Expr{
|
||||||
|
Ast_Expr *expr;
|
||||||
|
Ast_Expr *index;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Ast_Binary: Ast_Expr{
|
||||||
|
Token_Kind op;
|
||||||
|
Ast_Expr *left;
|
||||||
|
Ast_Expr *right;
|
||||||
|
Ast_Type *before_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Ast_Builtin: Ast_Expr{
|
||||||
|
Ast_Expr *expr;
|
||||||
|
Intern_String assert_message;
|
||||||
|
uint64_t padding[1]; // For folding constants into atoms
|
||||||
|
};
|
||||||
|
|
||||||
|
// Problem: We are parsing out of order, in the middle of parsing a function
|
||||||
|
// we can jump down a different function, we cant therfore use global map.
|
||||||
|
// Each scope needs to have it's checked locals list. To lookup syms we need to
|
||||||
|
// look into global scope and to the locals list.
|
||||||
|
//
|
||||||
|
|
||||||
|
struct Ast_Return: Ast{
|
||||||
|
Ast_Type *resolved_type;
|
||||||
|
Array<Ast_Expr *> expr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Ast_If_Node: Ast{
|
||||||
|
Ast_Expr *expr ;
|
||||||
|
Ast_Scope *scope;
|
||||||
|
Ast_Binary*init;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Ast_If: Ast{
|
||||||
|
Array<Ast_If_Node *> ifs;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Ast_Pass: Ast{};
|
||||||
|
struct Ast_Break: Ast{};
|
||||||
|
|
||||||
|
struct Ast_For: Ast{
|
||||||
|
Ast_Expr *init;
|
||||||
|
Ast_Expr *cond;
|
||||||
|
Ast_Expr *iter;
|
||||||
|
Ast_Scope *scope;
|
||||||
|
|
||||||
|
Ast_Decl *array_traversal_var;
|
||||||
|
bool is_array_traversal;
|
||||||
|
bool is_also_slice_traversal;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Ast_Lambda : Ast_Expr {
|
||||||
|
Array<Ast_Decl *> args;
|
||||||
|
Array<Ast_Expr *> ret;
|
||||||
|
Ast_Scope *scope;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Ast_Array: Ast_Expr{
|
||||||
|
Ast_Expr *base;
|
||||||
|
Ast_Expr *expr;
|
||||||
|
uint64_t padding[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Ast_Switch_Case: Ast{
|
||||||
|
Array<Ast_Expr *> labels;
|
||||||
|
Ast_Scope *scope;
|
||||||
|
bool fallthrough;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Ast_Switch: Ast{
|
||||||
|
Ast_Expr *value;
|
||||||
|
Array<Ast_Switch_Case *> cases;
|
||||||
|
Ast_Scope *default_scope;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
How does current declaration order resolver works:
|
||||||
|
* First we put all the global declarations into the global scope (when parsing) all unresolved
|
||||||
|
* All the types are declared INCOMPLETE and RESOLVED
|
||||||
|
* We descent the tree by resolving each of the named declarations, we resolve by their name
|
||||||
|
When we start resolving we set RESOLVING flag and when we complete RESOLVED flag
|
||||||
|
and put into ordered list
|
||||||
|
* When we meet a symbol (named declaration) while descending the tree,
|
||||||
|
we resolve that symbol instead before resolving current declaration.
|
||||||
|
* When we meet a declaration that requires size of a type - field access, var assignment,
|
||||||
|
we need to call "complete_type", it sets COMPLETING flag.
|
||||||
|
This call resolves all the dependencies of that type,
|
||||||
|
sets size of type and marks it as COMPLETE and puts into ordered list.
|
||||||
|
If it detects COMPLETING while
|
||||||
|
resolving, we got a circular dependency. That might happen when we have
|
||||||
|
that struct without pointer inside itself.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct Ast_Scope: Ast{
|
||||||
|
String debug_name; // Dont use
|
||||||
|
List<Ast_Scope *> implicit_imports;
|
||||||
|
List<Ast_Decl *> decls;
|
||||||
|
Array<Ast *> stmts;
|
||||||
|
|
||||||
|
uint32_t visit_id;
|
||||||
|
uint32_t scope_id;
|
||||||
|
Ast_Scope *file; // Self referential for file and module
|
||||||
|
Ast_Module *module;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Ast_Module_State{
|
||||||
|
MODULE_REGISTERED,
|
||||||
|
MODULE_PARSED,
|
||||||
|
MODULE_RESOLVED,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Ast_Module: Ast_Scope{
|
||||||
|
Ast_Module_State state;
|
||||||
|
String absolute_base_folder;
|
||||||
|
String absolute_file_path;
|
||||||
|
List<Ast_File *> all_loaded_files;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Ast_File: Ast_Scope{
|
||||||
|
String absolute_base_folder;
|
||||||
|
String absolute_file_path;
|
||||||
|
String filecontent;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Ast_Decl_State{
|
||||||
|
DECL_NOT_RESOLVED,
|
||||||
|
DECL_RESOLVED,
|
||||||
|
DECL_RESOLVED_TYPE,
|
||||||
|
DECL_RESOLVING,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Ast_Operator_Info{
|
||||||
|
Intern_String op;
|
||||||
|
String name;
|
||||||
|
Token_Kind op_kind;
|
||||||
|
bool valid_binary_expr;
|
||||||
|
bool valid_unary_expr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Ast_Decl: Ast{
|
||||||
|
Ast_Decl_State state;
|
||||||
|
Intern_String name;
|
||||||
|
Intern_String unique_name; // For code generation, currently only present on lambdas
|
||||||
|
|
||||||
|
uint64_t operator_overload_arguments_hash;
|
||||||
|
Ast_Operator_Info *overload_op_info;
|
||||||
|
|
||||||
|
Ast_Scope *scope;
|
||||||
|
Ast_Expr *typespec;
|
||||||
|
union{
|
||||||
|
Ast_Expr *expr;
|
||||||
|
Ast_Lambda *lambda;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*#import meta
|
||||||
|
meta.inline_value_fields()
|
||||||
|
*/
|
||||||
|
union {
|
||||||
|
Value value;
|
||||||
|
struct {
|
||||||
|
Ast_Type *type;
|
||||||
|
Ast_Decl *resolved_decl;
|
||||||
|
union {
|
||||||
|
bool bool_val;
|
||||||
|
double f64_val;
|
||||||
|
Intern_String intern_val;
|
||||||
|
BigInt big_int_val;
|
||||||
|
Ast_Type *type_val;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
/*END*/
|
||||||
|
};
|
||||||
@@ -1,11 +1,5 @@
|
|||||||
|
|
||||||
struct Operator_Info{
|
|
||||||
Intern_String op;
|
|
||||||
String name;
|
|
||||||
Token_Kind op_kind;
|
|
||||||
bool valid_binary_expr;
|
|
||||||
bool valid_unary_expr;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*#import meta
|
/*#import meta
|
||||||
|
|
||||||
@@ -40,7 +34,7 @@ print(" return 0;\n}")
|
|||||||
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
Operator_Info op_info_table[] = {
|
Ast_Operator_Info op_info_table[] = {
|
||||||
{{}, "MUL"_s, TK_Mul, 1, 0},
|
{{}, "MUL"_s, TK_Mul, 1, 0},
|
||||||
{{}, "DIV"_s, TK_Div, 1, 0},
|
{{}, "DIV"_s, TK_Div, 1, 0},
|
||||||
{{}, "MOD"_s, TK_Mod, 1, 0},
|
{{}, "MOD"_s, TK_Mod, 1, 0},
|
||||||
@@ -62,7 +56,7 @@ Operator_Info op_info_table[] = {
|
|||||||
{{}, "NEG"_s, TK_Neg, 0, 1},
|
{{}, "NEG"_s, TK_Neg, 0, 1},
|
||||||
{{}, "NOT"_s, TK_Not, 0, 1},
|
{{}, "NOT"_s, TK_Not, 0, 1},
|
||||||
};
|
};
|
||||||
CORE_Static Operator_Info *
|
CORE_Static Ast_Operator_Info *
|
||||||
get_operator_info(Token_Kind op){
|
get_operator_info(Token_Kind op){
|
||||||
switch(op){
|
switch(op){
|
||||||
case TK_Mul: return op_info_table + 0;
|
case TK_Mul: return op_info_table + 0;
|
||||||
@@ -89,7 +83,7 @@ get_operator_info(Token_Kind op){
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
CORE_Static Operator_Info *
|
CORE_Static Ast_Operator_Info *
|
||||||
get_operator_info(Intern_String op){
|
get_operator_info(Intern_String op){
|
||||||
if(0){}
|
if(0){}
|
||||||
else if(op_info_table[0].op.str == op.str) return op_info_table + 0;
|
else if(op_info_table[0].op.str == op.str) return op_info_table + 0;
|
||||||
|
|||||||
@@ -268,6 +268,7 @@ For modules it's a bit different cause they should be distributed as valid.
|
|||||||
#error Couldnt figure out OS using macros
|
#error Couldnt figure out OS using macros
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "core_compiler_interface.hpp"
|
||||||
#include "c3_big_int.h"
|
#include "c3_big_int.h"
|
||||||
#include "core_compiler.h"
|
#include "core_compiler.h"
|
||||||
#include "core_types.h"
|
#include "core_types.h"
|
||||||
|
|||||||
@@ -864,7 +864,7 @@ parse_decl(B32 is_global){
|
|||||||
if(!expr->scope){
|
if(!expr->scope){
|
||||||
compiler_error(tname, "Operator overload doesn't have body");
|
compiler_error(tname, "Operator overload doesn't have body");
|
||||||
}
|
}
|
||||||
Operator_Info *op_info = get_operator_info(tname->intern_val);
|
Ast_Operator_Info *op_info = get_operator_info(tname->intern_val);
|
||||||
if(!op_info){
|
if(!op_info){
|
||||||
compiler_error(tname, "This operator cannot be overloaded");
|
compiler_error(tname, "This operator cannot be overloaded");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -546,7 +546,7 @@ resolve_name(Ast_Scope *scope, Token *pos, Intern_String name, Search_Flag searc
|
|||||||
|
|
||||||
CORE_Static Ast_Decl *
|
CORE_Static Ast_Decl *
|
||||||
resolve_operator_overload(Ast_Scope *scope, Ast_Type *left, Ast_Type *right, Token *pos, Token_Kind op, U64 argument_hash){
|
resolve_operator_overload(Ast_Scope *scope, Ast_Type *left, Ast_Type *right, Token *pos, Token_Kind op, U64 argument_hash){
|
||||||
Operator_Info *op_info = get_operator_info(op);
|
Ast_Operator_Info *op_info = get_operator_info(op);
|
||||||
if(op_info == 0) return 0;
|
if(op_info == 0) return 0;
|
||||||
|
|
||||||
// Search for all possible candidates in three scopes
|
// Search for all possible candidates in three scopes
|
||||||
|
|||||||
115
core_types.h
115
core_types.h
@@ -1,49 +1,7 @@
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Resolved Types
|
// Resolved Types
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
enum Ast_Type_Kind{
|
|
||||||
TYPE_NONE,
|
|
||||||
TYPE_S64, // FIRST_NUMERIC
|
|
||||||
TYPE_S32,
|
|
||||||
TYPE_S16,
|
|
||||||
TYPE_S8 ,
|
|
||||||
TYPE_INT,
|
|
||||||
TYPE_CHAR,
|
|
||||||
TYPE_U64,
|
|
||||||
TYPE_U32,
|
|
||||||
TYPE_U16,
|
|
||||||
TYPE_U8 ,
|
|
||||||
TYPE_F32,
|
|
||||||
TYPE_F64,
|
|
||||||
TYPE_POINTER,
|
|
||||||
TYPE_BOOL, // LAST_NUMERIC
|
|
||||||
TYPE_STRING,
|
|
||||||
TYPE_VOID,
|
|
||||||
TYPE_ARRAY,
|
|
||||||
TYPE_LAMBDA,
|
|
||||||
TYPE_STRUCT,
|
|
||||||
TYPE_UNION,
|
|
||||||
TYPE_ENUM,
|
|
||||||
TYPE_TYPE,
|
|
||||||
TYPE_SLICE,
|
|
||||||
TYPE_TUPLE,
|
|
||||||
|
|
||||||
TYPE_COMPLETING,
|
|
||||||
TYPE_INCOMPLETE,
|
|
||||||
TYPE_UNTYPED_BOOL, // FIRST_TYPED_NUMERIC, FIRST_NUMERIC
|
|
||||||
TYPE_UNTYPED_INT,
|
|
||||||
TYPE_UNTYPED_FLOAT, // LAST_TYPED_NUMERIC
|
|
||||||
TYPE_UNTYPED_STRING,
|
|
||||||
|
|
||||||
TYPE_UNTYPED_FIRST = TYPE_UNTYPED_BOOL,
|
|
||||||
TYPE_UNTYPED_LAST = TYPE_UNTYPED_STRING,
|
|
||||||
|
|
||||||
TYPE_UNTYPED_FIRST_NUMERIC = TYPE_UNTYPED_BOOL,
|
|
||||||
TYPE_UNTYPED_LAST_NUMERIC = TYPE_UNTYPED_FLOAT,
|
|
||||||
|
|
||||||
TYPE_FIRST_NUMERIC = TYPE_S64,
|
|
||||||
TYPE_LAST_NUMERIC = TYPE_BOOL,
|
|
||||||
};
|
|
||||||
|
|
||||||
#define CASE_SINT case TYPE_S8:case TYPE_S16:case TYPE_S32:case TYPE_S64: case TYPE_CHAR: case TYPE_INT
|
#define CASE_SINT case TYPE_S8:case TYPE_S16:case TYPE_S32:case TYPE_S64: case TYPE_CHAR: case TYPE_INT
|
||||||
#define CASE_UINT case TYPE_U8:case TYPE_U16:case TYPE_U32:case TYPE_U64
|
#define CASE_UINT case TYPE_U8:case TYPE_U16:case TYPE_U32:case TYPE_U64
|
||||||
@@ -53,76 +11,3 @@ enum Ast_Type_Kind{
|
|||||||
#define CASE_STRING case TYPE_UNTYPED_STRING: case TYPE_STRING: case TYPE_POINTER
|
#define CASE_STRING case TYPE_UNTYPED_STRING: case TYPE_STRING: case TYPE_POINTER
|
||||||
#define CASE_UNTYPED case TYPE_UNTYPED_INT: case TYPE_UNTYPED_BOOL: case TYPE_UNTYPED_FLOAT: case TYPE_UNTYPED_STRING
|
#define CASE_UNTYPED case TYPE_UNTYPED_INT: case TYPE_UNTYPED_BOOL: case TYPE_UNTYPED_FLOAT: case TYPE_UNTYPED_STRING
|
||||||
#define ARRAY_SIZE_SLICE (-1)
|
#define ARRAY_SIZE_SLICE (-1)
|
||||||
|
|
||||||
struct Value {
|
|
||||||
/*#import meta
|
|
||||||
print(meta.value_struct_content)
|
|
||||||
*/
|
|
||||||
Ast_Type *type;
|
|
||||||
Ast_Decl *resolved_decl;
|
|
||||||
union {
|
|
||||||
bool bool_val;
|
|
||||||
F64 f64_val;
|
|
||||||
Intern_String intern_val;
|
|
||||||
BigInt big_int_val;
|
|
||||||
Ast_Type *type_val;
|
|
||||||
};
|
|
||||||
/*END*/
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Ast;
|
|
||||||
struct Ast_Type;
|
|
||||||
struct Ast_Resolved_Member{
|
|
||||||
Intern_String name;
|
|
||||||
S32 offset;
|
|
||||||
B32 visited;
|
|
||||||
/*#import meta
|
|
||||||
meta.inline_value_fields()
|
|
||||||
*/
|
|
||||||
union {
|
|
||||||
Value value;
|
|
||||||
struct {
|
|
||||||
Ast_Type *type;
|
|
||||||
Ast_Decl *resolved_decl;
|
|
||||||
union {
|
|
||||||
bool bool_val;
|
|
||||||
F64 f64_val;
|
|
||||||
Intern_String intern_val;
|
|
||||||
BigInt big_int_val;
|
|
||||||
Ast_Type *type_val;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
/*END*/
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Ast_Type{
|
|
||||||
Ast_Type_Kind kind;
|
|
||||||
S32 size;
|
|
||||||
S32 align;
|
|
||||||
S32 is_unsigned;
|
|
||||||
S32 type_id;
|
|
||||||
S32 padding;
|
|
||||||
|
|
||||||
Ast *ast;
|
|
||||||
union{
|
|
||||||
Ast_Type *base;
|
|
||||||
struct{
|
|
||||||
Ast_Type *base;
|
|
||||||
S32 size;
|
|
||||||
// @note: if you have array with size "[32]"
|
|
||||||
// you still want to pass that array into
|
|
||||||
// a function that expects an array of size "[]"
|
|
||||||
// so we want also should check this
|
|
||||||
U64 slice_hash;
|
|
||||||
}arr;
|
|
||||||
struct{
|
|
||||||
Array<Ast_Resolved_Member> members;
|
|
||||||
}agg;
|
|
||||||
struct{
|
|
||||||
Ast_Type * ret;
|
|
||||||
Array<Ast_Type *> args;
|
|
||||||
U64 hash_without_ret;
|
|
||||||
}func;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|||||||
2
meta.py
2
meta.py
@@ -136,7 +136,7 @@ Ast_Type *type;
|
|||||||
Ast_Decl *resolved_decl;
|
Ast_Decl *resolved_decl;
|
||||||
union {
|
union {
|
||||||
bool bool_val;
|
bool bool_val;
|
||||||
F64 f64_val;
|
double f64_val;
|
||||||
Intern_String intern_val;
|
Intern_String intern_val;
|
||||||
BigInt big_int_val;
|
BigInt big_int_val;
|
||||||
Ast_Type *type_val;
|
Ast_Type *type_val;
|
||||||
|
|||||||
Reference in New Issue
Block a user