Added lambda expressions, lambda types, no body yet
This commit is contained in:
146
new_ast.cpp
146
new_ast.cpp
@@ -20,21 +20,14 @@ struct Parse_Ctx:Lexer{
|
|||||||
Allocator *perm; // Stores: AST, tokens, interns
|
Allocator *perm; // Stores: AST, tokens, interns
|
||||||
Allocator *heap;
|
Allocator *heap;
|
||||||
|
|
||||||
|
U64 unique_ids;
|
||||||
Map global_syms;
|
Map global_syms;
|
||||||
Map type_map;
|
Map type_map;
|
||||||
|
|
||||||
Token empty_token;
|
Token empty_token;
|
||||||
S64 indent;
|
S64 indent;
|
||||||
S64 pt[256]; // precedence table
|
|
||||||
|
|
||||||
void init(Allocator *perm_allocator, Allocator *heap_allocator){
|
void init(Allocator *perm_allocator, Allocator *heap_allocator){
|
||||||
const S64 addp = 1;
|
|
||||||
const S64 mulp = 2;
|
|
||||||
pt[TK_Add] = addp;
|
|
||||||
pt[TK_Sub] = addp;
|
|
||||||
pt[TK_Div] = mulp;
|
|
||||||
pt[TK_Mul] = mulp;
|
|
||||||
|
|
||||||
perm = perm_allocator;
|
perm = perm_allocator;
|
||||||
heap = heap_allocator;
|
heap = heap_allocator;
|
||||||
|
|
||||||
@@ -61,30 +54,33 @@ thread_local Parse_Ctx *pctx;
|
|||||||
// AST
|
// AST
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
enum Ast_Kind{
|
enum Ast_Kind{
|
||||||
AK_None,
|
AST_NONE,
|
||||||
|
|
||||||
AK_Package,
|
AST_PACKAGE,
|
||||||
|
|
||||||
AK_Expr_Str,
|
AST_STR,
|
||||||
AK_Expr_Int,
|
AST_INT,
|
||||||
AK_Expr_Cast,
|
AST_CAST,
|
||||||
AK_Expr_Ident,
|
AST_IDENT,
|
||||||
AK_Expr_Binary,
|
AST_INDEX,
|
||||||
AK_Expr_CompoundItem,
|
AST_UNARY,
|
||||||
AK_Expr_Compound,
|
AST_BINARY,
|
||||||
|
AST_COMPOUND_ITEM,
|
||||||
|
AST_COMPOUND,
|
||||||
|
|
||||||
AK_Decl_Func,
|
AST_LAMBDA,
|
||||||
AK_Decl_Func_Arg,
|
AST_LAMBDA_PARAM,
|
||||||
AK_Decl_Const,
|
AST_CONST,
|
||||||
AK_Decl_Var,
|
AST_VAR,
|
||||||
|
|
||||||
AK_Typespec_Ident,
|
AST_TYPESPEC_IDENT,
|
||||||
AK_Typespec_Pointer,
|
AST_TYPESPEC_POINTER,
|
||||||
AK_Typespec_Array,
|
AST_TYPESPEC_ARRAY,
|
||||||
AK_Typespec_Func
|
AST_TYPESPEC_LAMBDA
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Ast{
|
struct Ast{
|
||||||
|
U64 id;
|
||||||
Ast_Kind kind;
|
Ast_Kind kind;
|
||||||
Token *pos;
|
Token *pos;
|
||||||
};
|
};
|
||||||
@@ -94,6 +90,11 @@ struct Ast_Expr:Ast{
|
|||||||
union{
|
union{
|
||||||
Intern_String intern_val;
|
Intern_String intern_val;
|
||||||
U64 int_val;
|
U64 int_val;
|
||||||
|
struct{
|
||||||
|
Token_Kind op;
|
||||||
|
Ast_Expr *expr;
|
||||||
|
}unary;
|
||||||
|
|
||||||
struct{
|
struct{
|
||||||
Token_Kind op;
|
Token_Kind op;
|
||||||
Ast_Expr *left;
|
Ast_Expr *left;
|
||||||
@@ -112,9 +113,22 @@ struct Ast_Expr:Ast{
|
|||||||
Ast_Expr *expr;
|
Ast_Expr *expr;
|
||||||
Ast_Typespec *typespec;
|
Ast_Typespec *typespec;
|
||||||
}cast;
|
}cast;
|
||||||
|
struct{
|
||||||
|
Ast_Expr *expr;
|
||||||
|
Ast_Expr *index;
|
||||||
|
}index;
|
||||||
|
struct{
|
||||||
|
Intern_String name;
|
||||||
|
Ast_Typespec *typespec;
|
||||||
|
}lambda_param;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Ast_Lambda : Ast_Expr {
|
||||||
|
Array<Ast_Expr *> params;
|
||||||
|
Ast_Typespec *ret;
|
||||||
|
};
|
||||||
|
|
||||||
struct Ast_Typespec:Ast{
|
struct Ast_Typespec:Ast{
|
||||||
union{
|
union{
|
||||||
Ast_Typespec *base;
|
Ast_Typespec *base;
|
||||||
@@ -123,10 +137,7 @@ struct Ast_Typespec:Ast{
|
|||||||
Ast_Typespec *base;
|
Ast_Typespec *base;
|
||||||
Ast_Expr *expr;
|
Ast_Expr *expr;
|
||||||
}arr;
|
}arr;
|
||||||
struct{
|
Ast_Lambda *lambda;
|
||||||
Ast_Typespec *ret;
|
|
||||||
Array<Ast_Typespec*> args;
|
|
||||||
}func;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -155,32 +166,33 @@ struct Ast_Package:Ast{
|
|||||||
#define AST_NEW(T,ikind,ipos) \
|
#define AST_NEW(T,ikind,ipos) \
|
||||||
Ast_##T *result = exp_alloc_type(pctx->perm, Ast_##T); \
|
Ast_##T *result = exp_alloc_type(pctx->perm, Ast_##T); \
|
||||||
result->kind = ikind; \
|
result->kind = ikind; \
|
||||||
result->pos = ipos
|
result->pos = ipos; \
|
||||||
|
result->id = ++pctx->unique_ids
|
||||||
|
|
||||||
function Ast_Expr *
|
function Ast_Expr *
|
||||||
ast_expr_string(Token *pos, Intern_String string){
|
ast_expr_string(Token *pos, Intern_String string){
|
||||||
AST_NEW(Expr, AK_Expr_Str, pos);
|
AST_NEW(Expr, AST_STR, pos);
|
||||||
result->intern_val = string;
|
result->intern_val = string;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Expr *
|
function Ast_Expr *
|
||||||
ast_expr_identifier(Token *pos, Intern_String string){
|
ast_expr_identifier(Token *pos, Intern_String string){
|
||||||
AST_NEW(Expr, AK_Expr_Ident, pos);
|
AST_NEW(Expr, AST_IDENT, pos);
|
||||||
result->intern_val = string;
|
result->intern_val = string;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Expr *
|
function Ast_Expr *
|
||||||
ast_expr_integer(Token *pos, S64 integer){
|
ast_expr_integer(Token *pos, S64 integer){
|
||||||
AST_NEW(Expr, AK_Expr_Int, pos);
|
AST_NEW(Expr, AST_INT, pos);
|
||||||
result->int_val = integer;
|
result->int_val = integer;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Expr *
|
function Ast_Expr *
|
||||||
ast_expr_binary(Ast_Expr *left, Ast_Expr *right, Token *op){
|
ast_expr_binary(Ast_Expr *left, Ast_Expr *right, Token *op){
|
||||||
AST_NEW(Expr, AK_Expr_Binary, op);
|
AST_NEW(Expr, AST_BINARY, op);
|
||||||
result->binary.op = op->kind;
|
result->binary.op = op->kind;
|
||||||
result->binary.left = left;
|
result->binary.left = left;
|
||||||
result->binary.right = right;
|
result->binary.right = right;
|
||||||
@@ -189,7 +201,7 @@ ast_expr_binary(Ast_Expr *left, Ast_Expr *right, Token *op){
|
|||||||
|
|
||||||
function Ast_Expr *
|
function Ast_Expr *
|
||||||
ast_expr_compound(Token *pos, Ast_Typespec *typespec, Array<Ast_Expr *> exprs){
|
ast_expr_compound(Token *pos, Ast_Typespec *typespec, Array<Ast_Expr *> exprs){
|
||||||
AST_NEW(Expr, AK_Expr_Compound, pos);
|
AST_NEW(Expr, AST_COMPOUND, pos);
|
||||||
result->compound.typespec = typespec;
|
result->compound.typespec = typespec;
|
||||||
result->compound.exprs = exprs.tight_copy(pctx->perm);
|
result->compound.exprs = exprs.tight_copy(pctx->perm);
|
||||||
return result;
|
return result;
|
||||||
@@ -197,7 +209,7 @@ ast_expr_compound(Token *pos, Ast_Typespec *typespec, Array<Ast_Expr *> exprs){
|
|||||||
|
|
||||||
function Ast_Expr *
|
function Ast_Expr *
|
||||||
ast_expr_compound_item(Token *pos, Ast_Expr *index, Ast_Expr *name, Ast_Expr *item){
|
ast_expr_compound_item(Token *pos, Ast_Expr *index, Ast_Expr *name, Ast_Expr *item){
|
||||||
AST_NEW(Expr, AK_Expr_CompoundItem, pos);
|
AST_NEW(Expr, AST_COMPOUND_ITEM, pos);
|
||||||
result->compound_item.name = name;
|
result->compound_item.name = name;
|
||||||
result->compound_item.index = index;
|
result->compound_item.index = index;
|
||||||
result->compound_item.item = item;
|
result->compound_item.item = item;
|
||||||
@@ -206,42 +218,80 @@ ast_expr_compound_item(Token *pos, Ast_Expr *index, Ast_Expr *name, Ast_Expr *it
|
|||||||
|
|
||||||
function Ast_Expr *
|
function Ast_Expr *
|
||||||
ast_expr_cast(Token *pos, Ast_Expr *expr, Ast_Typespec *typespec){
|
ast_expr_cast(Token *pos, Ast_Expr *expr, Ast_Typespec *typespec){
|
||||||
AST_NEW(Expr, AK_Expr_Cast, pos);
|
AST_NEW(Expr, AST_CAST, pos);
|
||||||
result->cast.expr = expr;
|
result->cast.expr = expr;
|
||||||
result->cast.typespec = typespec;
|
result->cast.typespec = typespec;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Ast_Expr *
|
||||||
|
ast_expr_unary(Token *pos, Token_Kind op, Ast_Expr *expr){
|
||||||
|
AST_NEW(Expr, AST_UNARY, pos);
|
||||||
|
result->unary.expr = expr;
|
||||||
|
result->unary.op = op;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Ast_Expr *
|
||||||
|
ast_expr_index(Token *pos, Ast_Expr *expr, Ast_Expr *index){
|
||||||
|
AST_NEW(Expr, AST_INDEX, pos);
|
||||||
|
result->index.expr = expr;
|
||||||
|
result->index.index = index;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function Ast_Lambda *
|
||||||
|
ast_lambda(Token *pos, Array<Ast_Expr *> params, Ast_Typespec *ret){
|
||||||
|
AST_NEW(Lambda, AST_LAMBDA, pos);
|
||||||
|
result->params = params.tight_copy(pctx->perm);
|
||||||
|
result->ret = ret;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Ast_Expr *
|
||||||
|
ast_expr_lambda_empty(Token *pos){
|
||||||
|
AST_NEW(Expr, AST_LAMBDA, pos);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Ast_Expr *
|
||||||
|
ast_expr_lambda_param(Token *pos, Intern_String name, Ast_Typespec *typespec){
|
||||||
|
AST_NEW(Expr, AST_LAMBDA_PARAM, pos);
|
||||||
|
result->lambda_param.name = name;
|
||||||
|
result->lambda_param.typespec = typespec;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Typespecs
|
// Typespecs
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
function Ast_Typespec *
|
function Ast_Typespec *
|
||||||
ast_typespec_name(Token *pos, Intern_String name){
|
ast_typespec_name(Token *pos, Intern_String name){
|
||||||
AST_NEW(Typespec, AK_Typespec_Ident, pos);
|
AST_NEW(Typespec, AST_TYPESPEC_IDENT, pos);
|
||||||
result->name = name;
|
result->name = name;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Typespec *
|
function Ast_Typespec *
|
||||||
ast_typespec_pointer(Token *pos, Ast_Typespec *base){
|
ast_typespec_pointer(Token *pos, Ast_Typespec *base){
|
||||||
AST_NEW(Typespec, AK_Typespec_Pointer, pos);
|
AST_NEW(Typespec, AST_TYPESPEC_POINTER, pos);
|
||||||
result->base = base;
|
result->base = base;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Typespec *
|
function Ast_Typespec *
|
||||||
ast_typespec_array(Token *pos, Ast_Typespec *base, Ast_Expr *expr){
|
ast_typespec_array(Token *pos, Ast_Typespec *base, Ast_Expr *expr){
|
||||||
AST_NEW(Typespec, AK_Typespec_Array, pos);
|
AST_NEW(Typespec, AST_TYPESPEC_ARRAY, pos);
|
||||||
result->arr.base = base;
|
result->arr.base = base;
|
||||||
result->arr.expr = expr;
|
result->arr.expr = expr;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Typespec *
|
function Ast_Typespec *
|
||||||
ast_typespec_func(Token *pos, Ast_Typespec *ret, Array<Ast_Typespec*> args){
|
ast_typespec_lambda(Token *pos, Ast_Lambda *lambda){
|
||||||
AST_NEW(Typespec, AK_Typespec_Func, pos);
|
AST_NEW(Typespec, AST_TYPESPEC_LAMBDA, pos);
|
||||||
result->func.ret = ret;
|
result->lambda = lambda;
|
||||||
result->func.args = args.tight_copy(pctx->perm);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,14 +300,14 @@ ast_typespec_func(Token *pos, Ast_Typespec *ret, Array<Ast_Typespec*> args){
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
function Ast_Decl *
|
function Ast_Decl *
|
||||||
ast_decl_func(Token *pos, Intern_String name){
|
ast_decl_func(Token *pos, Intern_String name){
|
||||||
AST_NEW(Decl, AK_Decl_Func, pos);
|
AST_NEW(Decl, AST_LAMBDA, pos);
|
||||||
result->name = name;
|
result->name = name;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Decl *
|
function Ast_Decl *
|
||||||
ast_decl_var(Token *pos, Ast_Typespec *typespec, Intern_String name, Ast_Expr *expr){
|
ast_decl_var(Token *pos, Ast_Typespec *typespec, Intern_String name, Ast_Expr *expr){
|
||||||
AST_NEW(Decl, AK_Decl_Var, pos);
|
AST_NEW(Decl, AST_VAR, pos);
|
||||||
result->var.expr = expr;
|
result->var.expr = expr;
|
||||||
result->var.typespec = typespec;
|
result->var.typespec = typespec;
|
||||||
result->name = name;
|
result->name = name;
|
||||||
@@ -267,13 +317,13 @@ ast_decl_var(Token *pos, Ast_Typespec *typespec, Intern_String name, Ast_Expr *e
|
|||||||
function Ast_Decl *
|
function Ast_Decl *
|
||||||
ast_decl_const(Token *pos, Intern_String name, Ast_Expr *expr){
|
ast_decl_const(Token *pos, Intern_String name, Ast_Expr *expr){
|
||||||
Ast_Decl *result = ast_decl_var(pos, 0, name, expr);
|
Ast_Decl *result = ast_decl_var(pos, 0, name, expr);
|
||||||
result->kind = AK_Decl_Const;
|
result->kind = AST_CONST;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Package *
|
function Ast_Package *
|
||||||
ast_package(Token *pos, String name, Array<Ast_Decl *> decls){
|
ast_package(Token *pos, String name, Array<Ast_Decl *> decls){
|
||||||
AST_NEW(Package, AK_Package, pos);
|
AST_NEW(Package, AST_PACKAGE, pos);
|
||||||
result->decls = decls.tight_copy(pctx->perm);
|
result->decls = decls.tight_copy(pctx->perm);
|
||||||
result->name = intern_string(&pctx->interns, name);
|
result->name = intern_string(&pctx->interns, name);
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -82,6 +82,9 @@ enum Token_Kind{
|
|||||||
TK_Float,
|
TK_Float,
|
||||||
TK_Integer,
|
TK_Integer,
|
||||||
TK_Keyword,
|
TK_Keyword,
|
||||||
|
|
||||||
|
TK_Pointer = TK_BitXor,
|
||||||
|
TK_Dereference,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Token{
|
struct Token{
|
||||||
|
|||||||
144
new_parse.cpp
144
new_parse.cpp
@@ -21,8 +21,8 @@ token_next(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Token *
|
function Token *
|
||||||
token_is(Token_Kind kind){
|
token_is(Token_Kind kind, S64 lookahead = 0){
|
||||||
Token *token = token_get();
|
Token *token = token_get(lookahead);
|
||||||
if(token->kind == kind){
|
if(token->kind == kind){
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
@@ -158,12 +158,45 @@ parse_expr_compound(){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Ast_Typespec *
|
||||||
|
parse_optional_type(){
|
||||||
|
Ast_Typespec *result = 0;
|
||||||
|
if(token_match(TK_Colon)) result = parse_typespec();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Ast_Lambda *
|
||||||
|
parse_lambda(Token *token, B32 is_typespec = false){ // @Todo(Krzosa): is_typespec is not used currently
|
||||||
|
// @Todo(Krzosa): Combine this with typespec function parsing
|
||||||
|
Scratch scratch;
|
||||||
|
Array<Ast_Expr *> params = {scratch};
|
||||||
|
// @Note(Krzosa): No need to guard against "()"
|
||||||
|
// We needed to lookahead to verify it's a function
|
||||||
|
// and this routine only fires when we have situation
|
||||||
|
// with at least one parameter
|
||||||
|
for(;;){
|
||||||
|
Token *name = token_expect(TK_Identifier);
|
||||||
|
token_expect(TK_Colon);
|
||||||
|
Ast_Typespec *typespec = parse_typespec();
|
||||||
|
Ast_Expr *param = ast_expr_lambda_param(name, name->intern_val, typespec);
|
||||||
|
params.add(param);
|
||||||
|
|
||||||
|
if(!token_match(TK_Comma)){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
token_expect(TK_CloseParen);
|
||||||
|
Ast_Lambda *result = ast_lambda(token, params, parse_optional_type());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
function Ast_Expr *
|
function Ast_Expr *
|
||||||
parse_expr_nud(Token *token){
|
null_denotation(Token *token){
|
||||||
switch(token->kind){
|
switch(token->kind){
|
||||||
case TK_StringLit: return ast_expr_string(token, token->intern_val);
|
case TK_StringLit : return ast_expr_string(token, token->intern_val);
|
||||||
case TK_Identifier: return ast_expr_identifier(token, token->intern_val);
|
case TK_Identifier: return ast_expr_identifier(token, token->intern_val);
|
||||||
case TK_Integer: return ast_expr_integer(token, token->int_val);
|
case TK_Integer : return ast_expr_integer(token, token->int_val);
|
||||||
|
case TK_BitXor : return ast_expr_unary(token, TK_Dereference, parse_expr());
|
||||||
case TK_Keyword: {
|
case TK_Keyword: {
|
||||||
if(token->intern_val == keyword_cast){
|
if(token->intern_val == keyword_cast){
|
||||||
token_expect(TK_OpenParen);
|
token_expect(TK_OpenParen);
|
||||||
@@ -179,22 +212,41 @@ parse_expr_nud(Token *token){
|
|||||||
}
|
}
|
||||||
}break;
|
}break;
|
||||||
case TK_OpenBrace: return parse_expr_compound();
|
case TK_OpenBrace: return parse_expr_compound();
|
||||||
case TK_OpenParen: {Ast_Expr *result = parse_expr(); token_expect(TK_CloseParen); return result;}
|
case TK_OpenParen: {
|
||||||
|
if(token_match(TK_CloseParen)) return ast_expr_lambda_empty(token);
|
||||||
|
else if(token_is(TK_Identifier) && token_is(TK_Colon, 1)) return parse_lambda(token);
|
||||||
|
else{
|
||||||
|
Ast_Expr *result = parse_expr();
|
||||||
|
token_expect(TK_CloseParen);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
default: parsing_error(token, "Unexpected token of kind: [%s] in expression", token_kind_string(token->kind).str); return 0;
|
default: parsing_error(token, "Unexpected token of kind: [%s] in expression", token_kind_string(token->kind).str); return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function S64
|
function S64
|
||||||
op_precedence(Token_Kind kind){
|
left_binding_power(Token_Kind kind){
|
||||||
S64 result = pctx->pt[kind];
|
switch(kind){
|
||||||
return result;
|
case TK_Sub: case TK_Add: return 1;
|
||||||
|
case TK_Mul: case TK_Div: return 2;
|
||||||
|
default: return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function S64
|
||||||
|
postfix_binding_power(Token_Kind kind){
|
||||||
|
switch(kind){
|
||||||
|
case TK_Increment: case TK_Decrement: case TK_BitXor: case TK_OpenBracket: return 1;
|
||||||
|
default: return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Expr *
|
function Ast_Expr *
|
||||||
parse_expr_led(Token *op, Ast_Expr *left){
|
left_denotation(Token *op, Ast_Expr *left){
|
||||||
enum{ Left_Associative, Right_Associative };
|
enum{ Left_Associative, Right_Associative };
|
||||||
S64 assoc = Left_Associative;
|
S64 assoc = Left_Associative;
|
||||||
Ast_Expr *right = parse_expr(op_precedence(op->kind) - assoc);
|
Ast_Expr *right = parse_expr(left_binding_power(op->kind) - assoc);
|
||||||
switch(op->kind){
|
switch(op->kind){
|
||||||
case TK_Add: case TK_Mul: case TK_Sub: case TK_Div: return ast_expr_binary(left, right, op);
|
case TK_Add: case TK_Mul: case TK_Sub: case TK_Div: return ast_expr_binary(left, right, op);
|
||||||
default: parsing_error(op, "Unexpected token of kind: [%s] in expression", token_kind_string(op->kind).str); return 0;
|
default: parsing_error(op, "Unexpected token of kind: [%s] in expression", token_kind_string(op->kind).str); return 0;
|
||||||
@@ -204,10 +256,30 @@ parse_expr_led(Token *op, Ast_Expr *left){
|
|||||||
function Ast_Expr *
|
function Ast_Expr *
|
||||||
parse_expr(S64 rbp){
|
parse_expr(S64 rbp){
|
||||||
Token *token = token_next();
|
Token *token = token_next();
|
||||||
Ast_Expr *left = parse_expr_nud(token);
|
Ast_Expr *left = null_denotation(token);
|
||||||
while(rbp < op_precedence(token_get()->kind)){
|
for(;;){
|
||||||
|
token = token_get();
|
||||||
|
|
||||||
|
if((rbp == 0) && (token->kind == TK_Increment || token->kind == TK_Decrement || token->kind == TK_BitXor || token->kind == TK_OpenBracket)){
|
||||||
|
token_next();
|
||||||
|
if(token->kind == TK_OpenBracket){
|
||||||
|
Ast_Expr *index = parse_expr();
|
||||||
|
left = ast_expr_index(token, left, index);
|
||||||
|
token_expect(TK_CloseBracket);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
if(token->kind == TK_Increment) token->kind = TK_PostIncrement;
|
||||||
|
else if(token->kind == TK_Decrement) token->kind = TK_PostDecrement;
|
||||||
|
left = ast_expr_unary(token, token->kind, left);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(rbp < left_binding_power(token->kind)){
|
||||||
token = token_next();
|
token = token_next();
|
||||||
left = parse_expr_led(token, left);
|
left = left_denotation(token, left);
|
||||||
|
}
|
||||||
|
else break;
|
||||||
|
|
||||||
}
|
}
|
||||||
return left;
|
return left;
|
||||||
}
|
}
|
||||||
@@ -215,8 +287,16 @@ parse_expr(S64 rbp){
|
|||||||
function S64
|
function S64
|
||||||
expr_eval(Ast_Expr *expr){
|
expr_eval(Ast_Expr *expr){
|
||||||
switch(expr->kind){
|
switch(expr->kind){
|
||||||
case AK_Expr_Int: return expr->int_val;
|
case AST_INT: return expr->int_val;
|
||||||
case AK_Expr_Binary : {
|
case AST_UNARY:{
|
||||||
|
S64 value = expr_eval(expr->unary.expr);
|
||||||
|
switch(expr->unary.op){
|
||||||
|
case TK_PostDecrement: return value - 1;
|
||||||
|
case TK_PostIncrement: return value + 1;
|
||||||
|
default: invalid_codepath;
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
case AST_BINARY : {
|
||||||
S64 left = expr_eval(expr->binary.left);
|
S64 left = expr_eval(expr->binary.left);
|
||||||
S64 right = expr_eval(expr->binary.right);
|
S64 right = expr_eval(expr->binary.right);
|
||||||
switch(expr->binary.op){
|
switch(expr->binary.op){
|
||||||
@@ -243,6 +323,8 @@ test_parse_expr(){
|
|||||||
TEST_PARSER();
|
TEST_PARSER();
|
||||||
struct Test{String str;S64 val;};
|
struct Test{String str;S64 val;};
|
||||||
Array<Test> exprs = {scratch};
|
Array<Test> exprs = {scratch};
|
||||||
|
//exprs.add({"thing[1][2][3]"_s, 0});
|
||||||
|
exprs.add({"4++++--"_s, 5});
|
||||||
exprs.add({"(4+5)*2"_s, (4+5)*2});
|
exprs.add({"(4+5)*2"_s, (4+5)*2});
|
||||||
exprs.add({"4+5*2"_s, 4+5*2});
|
exprs.add({"4+5*2"_s, 4+5*2});
|
||||||
exprs.add({"4*5+5"_s, 4*5+5});
|
exprs.add({"4*5+5"_s, 4*5+5});
|
||||||
@@ -259,36 +341,12 @@ test_parse_expr(){
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Parsing declarations
|
// Parsing declarations
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
function Ast_Typespec *
|
|
||||||
parse_optional_type(){
|
|
||||||
Ast_Typespec *result = 0;
|
|
||||||
if(token_match(TK_Colon)) result = parse_typespec();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function Ast_Typespec *
|
|
||||||
parse_typespec_function(Token *token){
|
|
||||||
Scratch scratch;
|
|
||||||
Array<Ast_Typespec *> args = {scratch};
|
|
||||||
if(!token_is(TK_CloseParen)) {
|
|
||||||
for(;;) {
|
|
||||||
args.add(parse_typespec());
|
|
||||||
if(!token_match(TK_Comma)){
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
token_expect(TK_CloseParen);
|
|
||||||
Ast_Typespec *ret = parse_optional_type();
|
|
||||||
Ast_Typespec *result = ast_typespec_func(token, ret, args);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// [10]*int - Array of 10 pointers to ints
|
// [10]*int - Array of 10 pointers to ints
|
||||||
function Ast_Typespec *
|
function Ast_Typespec *
|
||||||
parse_typespec_recurse(){
|
parse_typespec_recurse(){
|
||||||
Token *token = token_get();
|
Token *token = token_get();
|
||||||
if(token_match(TK_Mul)){
|
if(token_match(TK_BitXor)){
|
||||||
Ast_Typespec *result = parse_typespec_recurse();
|
Ast_Typespec *result = parse_typespec_recurse();
|
||||||
result = ast_typespec_pointer(token, result);
|
result = ast_typespec_pointer(token, result);
|
||||||
return result;
|
return result;
|
||||||
@@ -301,8 +359,8 @@ parse_typespec_recurse(){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
else if(token_match(TK_OpenParen)){
|
else if(token_match(TK_OpenParen)){
|
||||||
Ast_Typespec *result = parse_typespec_function(token);
|
Ast_Lambda *result = parse_lambda(token, true);
|
||||||
return result;
|
return ast_typespec_lambda(token, result);
|
||||||
}
|
}
|
||||||
else if(token_match(TK_Identifier)){
|
else if(token_match(TK_Identifier)){
|
||||||
Ast_Typespec *result = ast_typespec_name(token, token->intern_val);
|
Ast_Typespec *result = ast_typespec_name(token, token->intern_val);
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ eval_typespec(Ast_Typespec *ast){
|
|||||||
if(!ast) return 0;
|
if(!ast) return 0;
|
||||||
|
|
||||||
switch(ast->kind){
|
switch(ast->kind){
|
||||||
Ast_Begin(AK_Typespec_Ident, Ast_Typespec){
|
Ast_Begin(AST_TYPESPEC_IDENT, Ast_Typespec){
|
||||||
Sym *type_sym = sym_get(node->name);
|
Sym *type_sym = sym_get(node->name);
|
||||||
if(!type_sym){
|
if(!type_sym){
|
||||||
parsing_error(node->pos, "This type is not defined");
|
parsing_error(node->pos, "This type is not defined");
|
||||||
@@ -109,14 +109,24 @@ eval_typespec(Ast_Typespec *ast){
|
|||||||
Ast_End();
|
Ast_End();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast_Begin(AK_Typespec_Pointer, Ast_Typespec){
|
Ast_Begin(AST_TYPESPEC_LAMBDA, Ast_Typespec){
|
||||||
|
Scratch scratch;
|
||||||
|
Type *ret = eval_typespec(node->lambda->ret);
|
||||||
|
Array<Type *> params = {scratch};
|
||||||
|
For(node->lambda->params) params.add(eval_typespec(it[0]->lambda_param.typespec));
|
||||||
|
Type *result = type_lambda(ret, params);
|
||||||
|
return result;
|
||||||
|
Ast_End();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ast_Begin(AST_TYPESPEC_POINTER, Ast_Typespec){
|
||||||
Type *type = eval_typespec(node->base);
|
Type *type = eval_typespec(node->base);
|
||||||
Type *result = type_pointer(type);
|
Type *result = type_pointer(type);
|
||||||
return result;
|
return result;
|
||||||
Ast_End();
|
Ast_End();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast_Begin(AK_Typespec_Array, Ast_Typespec){
|
Ast_Begin(AST_TYPESPEC_ARRAY, Ast_Typespec){
|
||||||
Type *type = eval_typespec(node->arr.base);
|
Type *type = eval_typespec(node->arr.base);
|
||||||
Operand expr = eval_expr(node->arr.expr);
|
Operand expr = eval_expr(node->arr.expr);
|
||||||
if(!expr.is_const) parsing_error(node->pos, "Array size is not a constant");
|
if(!expr.is_const) parsing_error(node->pos, "Array size is not a constant");
|
||||||
@@ -149,19 +159,35 @@ resolve_type_pair(Token *pos, Type *a, Type *b){
|
|||||||
function Operand
|
function Operand
|
||||||
eval_expr(Ast_Expr *ast, Type *exp_compound_type){
|
eval_expr(Ast_Expr *ast, Type *exp_compound_type){
|
||||||
switch(ast->kind){
|
switch(ast->kind){
|
||||||
Ast_Begin(AK_Expr_Int, Ast_Expr){
|
Ast_Begin(AST_INT, Ast_Expr){
|
||||||
Operand result = {type_int, true, {.int_val=(S64)node->int_val}};
|
Operand result = {type_int, true, {.int_val=(S64)node->int_val}};
|
||||||
return result;
|
return result;
|
||||||
Ast_End();
|
Ast_End();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast_Begin(AK_Expr_Str, Ast_Expr){
|
Ast_Begin(AST_STR, Ast_Expr){
|
||||||
Operand result = {type_string, true, {.intern_val = node->intern_val}};
|
Operand result = {type_string, true, {.intern_val = node->intern_val}};
|
||||||
return result;
|
return result;
|
||||||
Ast_End();
|
Ast_End();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast_Begin(AK_Expr_Compound, Ast_Expr){
|
Ast_Begin(AST_LAMBDA, Ast_Lambda){
|
||||||
|
Type *type = eval_typespec(ast_typespec_lambda(0, node));
|
||||||
|
return {type, true};
|
||||||
|
Ast_End();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ast_Begin(AST_INDEX, Ast_Expr){
|
||||||
|
Operand left = eval_expr(node->index.expr);
|
||||||
|
Operand index = eval_expr(node->index.index);
|
||||||
|
if(left.type->kind != TYPE_Array) parsing_error(node->pos, "Indexing variable that is not an array");
|
||||||
|
if(index.type != type_int) parsing_error(node->pos, "Trying to index the array with invalid type, expected int");
|
||||||
|
Operand result = {left.type->arr.base};
|
||||||
|
return result;
|
||||||
|
Ast_End();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ast_Begin(AST_COMPOUND, Ast_Expr){
|
||||||
Type *type = eval_typespec(node->compound.typespec);
|
Type *type = eval_typespec(node->compound.typespec);
|
||||||
Type *variable_type = exp_compound_type;
|
Type *variable_type = exp_compound_type;
|
||||||
if(!type && variable_type) type = variable_type;
|
if(!type && variable_type) type = variable_type;
|
||||||
@@ -173,16 +199,18 @@ eval_expr(Ast_Expr *ast, Type *exp_compound_type){
|
|||||||
Type *item_type = type->arr.base;
|
Type *item_type = type->arr.base;
|
||||||
|
|
||||||
For(node->compound.exprs){
|
For(node->compound.exprs){
|
||||||
assert(it[0]->kind == AK_Expr_CompoundItem);
|
assert(it[0]->kind == AST_COMPOUND_ITEM);
|
||||||
if(it[0]->compound_item.name) parsing_error(it[0]->pos, "Invalid array indexing in compound expression");
|
Ast_Expr *i = (Ast_Expr *)it[0];
|
||||||
if(it[0]->compound_item.index){
|
assert(i->kind == AST_COMPOUND_ITEM);
|
||||||
Operand index_op = eval_expr(it[0]->compound_item.index);
|
if(i->compound_item.name) parsing_error(i->pos, "Invalid array indexing in compound expression");
|
||||||
if(!index_op.is_const) parsing_error(it[0]->pos, "Index in a compound expression is not a constant");
|
if(i->compound_item.index){
|
||||||
if(index_op.type != type_int) parsing_error(it[0]->pos, "Index should be of type int");
|
Operand index_op = eval_expr(i->compound_item.index);
|
||||||
if(index_op.int_val > (type->arr.size - 1)) parsing_error(it[0]->pos, "Invalid index in compound expression, larger then type can store");
|
if(!index_op.is_const) parsing_error(i->pos, "Index in a compound expression is not a constant");
|
||||||
|
if(index_op.type != type_int) parsing_error(i->pos, "Index should be of type int");
|
||||||
|
if(index_op.int_val > (type->arr.size - 1)) parsing_error(i->pos, "Invalid index in compound expression, larger then type can store");
|
||||||
}
|
}
|
||||||
Operand expr = eval_expr(it[0]->compound_item.item);
|
Operand expr = eval_expr(i->compound_item.item);
|
||||||
if(expr.type != item_type) parsing_error(it[0]->pos, "Invalid type of item in compound expression");
|
resolve_type_pair(i->pos, expr.type, item_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else parsing_error(node->pos, "Invalid compound expression type");
|
else parsing_error(node->pos, "Invalid compound expression type");
|
||||||
@@ -192,7 +220,7 @@ eval_expr(Ast_Expr *ast, Type *exp_compound_type){
|
|||||||
Ast_End();
|
Ast_End();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast_Begin(AK_Expr_Ident, Ast_Expr){
|
Ast_Begin(AST_IDENT, Ast_Expr){
|
||||||
Sym *sym = sym_get(node->intern_val);
|
Sym *sym = sym_get(node->intern_val);
|
||||||
if(!sym){
|
if(!sym){
|
||||||
parsing_error(node->pos, "Identifier is undefined");
|
parsing_error(node->pos, "Identifier is undefined");
|
||||||
@@ -203,7 +231,7 @@ eval_expr(Ast_Expr *ast, Type *exp_compound_type){
|
|||||||
Ast_End();
|
Ast_End();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast_Begin(AK_Expr_Cast, Ast_Expr){
|
Ast_Begin(AST_CAST, Ast_Expr){
|
||||||
Operand expr = eval_expr(node->cast.expr);
|
Operand expr = eval_expr(node->cast.expr);
|
||||||
Type *type = eval_typespec(node->cast.typespec);
|
Type *type = eval_typespec(node->cast.typespec);
|
||||||
|
|
||||||
@@ -229,7 +257,25 @@ eval_expr(Ast_Expr *ast, Type *exp_compound_type){
|
|||||||
Ast_End();
|
Ast_End();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast_Begin(AK_Expr_Binary, Ast_Expr){
|
Ast_Begin(AST_UNARY, Ast_Expr){
|
||||||
|
Operand value = eval_expr(node->unary.expr);
|
||||||
|
switch(node->unary.op){
|
||||||
|
case TK_BitXor:{
|
||||||
|
if(value.type->kind != TYPE_Pointer) parsing_error(node->pos, "Dereferencing a value that is not a pointer");
|
||||||
|
Operand result = {value.type->base};
|
||||||
|
return result;
|
||||||
|
}break;
|
||||||
|
case TK_Dereference:{
|
||||||
|
Operand result = {type_pointer(value.type)};
|
||||||
|
return result;
|
||||||
|
}break;
|
||||||
|
invalid_default_case; return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
Ast_End();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ast_Begin(AST_BINARY, Ast_Expr){
|
||||||
Operand left = eval_expr(ast->binary.left);
|
Operand left = eval_expr(ast->binary.left);
|
||||||
Operand right = eval_expr(ast->binary.right);
|
Operand right = eval_expr(ast->binary.right);
|
||||||
Operand result = {};
|
Operand result = {};
|
||||||
@@ -262,14 +308,14 @@ function void
|
|||||||
eval_decl(Ast *ast){
|
eval_decl(Ast *ast){
|
||||||
switch(ast->kind){
|
switch(ast->kind){
|
||||||
|
|
||||||
Ast_Begin(AK_Package, Ast_Package){
|
Ast_Begin(AST_PACKAGE, Ast_Package){
|
||||||
For(node->decls) eval_decl(*it);
|
For(node->decls) eval_decl(*it);
|
||||||
Ast_End();
|
Ast_End();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast_Begin(AK_Decl_Var, Ast_Decl){
|
Ast_Begin(AST_VAR, Ast_Decl){
|
||||||
Type *type = eval_typespec(node->var.typespec);
|
Type *type = eval_typespec(node->var.typespec);
|
||||||
Operand expr = eval_expr(node->var.expr, type);
|
Operand expr = node->var.expr ? eval_expr(node->var.expr, type) : Operand{};
|
||||||
Type *resolved_type = resolve_type_pair(node->pos, type, expr.type);
|
Type *resolved_type = resolve_type_pair(node->pos, type, expr.type);
|
||||||
|
|
||||||
Sym *sym = sym_new(SYM_Var, node->name, resolved_type, node);
|
Sym *sym = sym_new(SYM_Var, node->name, resolved_type, node);
|
||||||
@@ -277,7 +323,7 @@ eval_decl(Ast *ast){
|
|||||||
Ast_End();
|
Ast_End();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast_Begin(AK_Decl_Const, Ast_Decl){
|
Ast_Begin(AST_CONST, Ast_Decl){
|
||||||
Type *type = eval_typespec(node->var.typespec);
|
Type *type = eval_typespec(node->var.typespec);
|
||||||
if(type && type->kind == TYPE_Pointer) parsing_error(node->pos, "Const cant be a pointer");
|
if(type && type->kind == TYPE_Pointer) parsing_error(node->pos, "Const cant be a pointer");
|
||||||
Operand expr = eval_expr(node->var.expr);
|
Operand expr = eval_expr(node->var.expr);
|
||||||
|
|||||||
10
new_type.cpp
10
new_type.cpp
@@ -111,7 +111,7 @@ type_array(Type *base, SizeU size){
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Type *
|
function Type *
|
||||||
type_function(Type *ret, Array<Type *> args){
|
type_lambda(Type *ret, Array<Type *> args){
|
||||||
U64 hash = hash_ptr(ret);
|
U64 hash = hash_ptr(ret);
|
||||||
For(args) hash = hash_mix(hash, hash_ptr(*it));
|
For(args) hash = hash_mix(hash, hash_ptr(*it));
|
||||||
Type *result = (Type *)map_get_u64(&pctx->type_map, hash);
|
Type *result = (Type *)map_get_u64(&pctx->type_map, hash);
|
||||||
@@ -153,8 +153,8 @@ test_types(){
|
|||||||
|
|
||||||
Array<Type*> types = {scratch};
|
Array<Type*> types = {scratch};
|
||||||
types.add(type_array(type_int, 32));
|
types.add(type_array(type_int, 32));
|
||||||
Type *func_type1 = type_function(types[0], types);
|
Type *func_type1 = type_lambda(types[0], types);
|
||||||
Type *func_type2 = type_function(types[0], types);
|
Type *func_type2 = type_lambda(types[0], types);
|
||||||
assert(func_type1 == func_type2);
|
assert(func_type1 == func_type2);
|
||||||
|
|
||||||
Array<Type*> types2 = {scratch};
|
Array<Type*> types2 = {scratch};
|
||||||
@@ -163,8 +163,8 @@ test_types(){
|
|||||||
types2.add(type_int);
|
types2.add(type_int);
|
||||||
}
|
}
|
||||||
types.add(type_int);
|
types.add(type_int);
|
||||||
Type *func_type3 = type_function(types[0], types);
|
Type *func_type3 = type_lambda(types[0], types);
|
||||||
Type *func_type4 = type_function(types[0], types2);
|
Type *func_type4 = type_lambda(types[0], types2);
|
||||||
assert(func_type1 != func_type3);
|
assert(func_type1 != func_type3);
|
||||||
assert(func_type3 == func_type4);
|
assert(func_type3 == func_type4);
|
||||||
}
|
}
|
||||||
|
|||||||
3
print.c
3
print.c
@@ -4,9 +4,6 @@ function void typespec_print(Typespec *spec);
|
|||||||
global S64 indent;
|
global S64 indent;
|
||||||
|
|
||||||
#define println(...) do{ printf("\n"); print_indent(); printf(__VA_ARGS__); }while(0)
|
#define println(...) do{ printf("\n"); print_indent(); printf(__VA_ARGS__); }while(0)
|
||||||
#define AST_CAST(item, T) T *item = (T *)item
|
|
||||||
#define AST_IterT(parent, name, T) for(T *name = (T *)(parent)->first; name; name=(T *)name->next) // , assert(name->kind == AST_##type
|
|
||||||
#define AST_Iter(parent,name) AST_IterT(parent,name,AST)
|
|
||||||
|
|
||||||
|
|
||||||
function void
|
function void
|
||||||
|
|||||||
66
test3.kl
66
test3.kl
@@ -1,35 +1,57 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Player :: struct
|
||||||
|
id : int
|
||||||
|
name: String
|
||||||
|
|
||||||
|
compound_of_struct: Player = {
|
||||||
|
id = 10,
|
||||||
|
name = "Guy",
|
||||||
|
}
|
||||||
|
|
||||||
|
second_compound_syntax := :Player{...}
|
||||||
|
|
||||||
|
max :: (a: int, b: int) { if a > b then return a; return b; }
|
||||||
|
|
||||||
|
max :: (a: int, b: int)
|
||||||
|
if a > b then return a
|
||||||
|
return b
|
||||||
|
|
||||||
|
; - treated as new line
|
||||||
|
{ and } - treated as new line scope and end of new line scope
|
||||||
|
*/
|
||||||
|
|
||||||
|
test_function :: (thing: int): ^int
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Booleans
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
boolean: bool = true
|
boolean: bool = true
|
||||||
value_of_bool: int = cast(boolean: int)
|
value_of_bool: int = cast(boolean: int)
|
||||||
base := null
|
base := null
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Compound expressions
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
array1: [4]int = {1,2,3,4}
|
array1: [4]int = {1,2,3,4}
|
||||||
array2: [32]int = {1,2,3,4}
|
array2: [32]int = {1,2,3,4}
|
||||||
array3: [32]int = {
|
array3: [32]int = {
|
||||||
[0] = 0,
|
[0] = 0,
|
||||||
|
[1] = 1,
|
||||||
[31] = 31,
|
[31] = 31,
|
||||||
}
|
}
|
||||||
|
array_item := array1[0]
|
||||||
|
array_item_imp: int = array2[2]
|
||||||
|
|
||||||
/*
|
//-----------------------------------------------------------------------------
|
||||||
|
// Pointers
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
pointer_decl : ^int
|
||||||
|
variable_from_deref: int = pointer_decl^
|
||||||
|
pointer_from_var : ^int = ^variable_from_deref
|
||||||
|
boolean_pointer := ^boolean
|
||||||
|
|
||||||
pointer: *int
|
|
||||||
variable: int = *pointer
|
|
||||||
pointer_from_var := ^variable
|
|
||||||
|
|
||||||
pointer := &base
|
|
||||||
base_from_pointer := *pointer
|
|
||||||
|
|
||||||
structure: Data = {}
|
|
||||||
|
|
||||||
array2: [4]int = {
|
|
||||||
[0] = 0,
|
|
||||||
[1] = 1
|
|
||||||
}
|
|
||||||
array_to_pointer: *[4]int = &array1
|
|
||||||
array_to_pointer_imp : = &array1
|
|
||||||
|
|
||||||
|
|
||||||
*/
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Implicit type
|
// Implicit type
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@@ -39,9 +61,9 @@ implicit_str :: "Hello world"
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Pointers
|
// Pointers
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
pointer: *int = cast(null: *int)
|
pointer: ^int = cast(null: ^int)
|
||||||
pointer2: *int = null
|
pointer2: ^int = null
|
||||||
pointer3: **int = null
|
pointer3: ^^int = null
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// String types
|
// String types
|
||||||
|
|||||||
10
type.c
10
type.c
@@ -99,7 +99,7 @@ type_array(Arena *arena, Type *base, SizeU size){
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Type *
|
function Type *
|
||||||
type_function(Arena *arena, Type *ret, Type **params, S32 count){
|
type_lambda(Arena *arena, Type *ret, Type **params, S32 count){
|
||||||
U64 hash = hash_ptr(ret);
|
U64 hash = hash_ptr(ret);
|
||||||
for(S32 i = 0; i < count; i++)
|
for(S32 i = 0; i < count; i++)
|
||||||
hash = hash_mix(hash, hash_ptr(params[i]));
|
hash = hash_mix(hash, hash_ptr(params[i]));
|
||||||
@@ -138,8 +138,8 @@ test_types(){
|
|||||||
|
|
||||||
Type **types = 0;
|
Type **types = 0;
|
||||||
array_push(types, type_array(arena, type_int, 32));
|
array_push(types, type_array(arena, type_int, 32));
|
||||||
Type *func_type1 = type_function(arena, types[0], types, array_len(types));
|
Type *func_type1 = type_lambda(arena, types[0], types, array_len(types));
|
||||||
Type *func_type2 = type_function(arena, types[0], types, array_len(types));
|
Type *func_type2 = type_lambda(arena, types[0], types, array_len(types));
|
||||||
assert(func_type1 == func_type2);
|
assert(func_type1 == func_type2);
|
||||||
|
|
||||||
Type **types2 = 0;
|
Type **types2 = 0;
|
||||||
@@ -148,8 +148,8 @@ test_types(){
|
|||||||
array_push(types2, type_int);
|
array_push(types2, type_int);
|
||||||
}
|
}
|
||||||
array_push(types, type_int);
|
array_push(types, type_int);
|
||||||
Type *func_type3 = type_function(arena, types[0], types, array_len(types));
|
Type *func_type3 = type_lambda(arena, types[0], types, array_len(types));
|
||||||
Type *func_type4 = type_function(arena, types[0], types2, array_len(types));
|
Type *func_type4 = type_lambda(arena, types[0], types2, array_len(types));
|
||||||
assert(func_type1 != func_type3);
|
assert(func_type1 != func_type3);
|
||||||
assert(func_type3 == func_type4);
|
assert(func_type3 == func_type4);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user