Begin structs, add comment on multiline lambdas, add Ast flags
This commit is contained in:
@@ -245,8 +245,8 @@ gen_ast(Ast *ast){
|
|||||||
Sym *sym = resolved_get(node);
|
Sym *sym = resolved_get(node);
|
||||||
|
|
||||||
if(sym->type->kind == TYPE_Lambda){
|
if(sym->type->kind == TYPE_Lambda){
|
||||||
if(node->expr->kind == AST_LAMBDA){
|
if(node->value->kind == AST_LAMBDA){
|
||||||
Ast_Lambda *lambda = (Ast_Lambda *)node->expr;
|
Ast_Lambda *lambda = (Ast_Lambda *)node->value;
|
||||||
gen("static ");
|
gen("static ");
|
||||||
Ast_Resolved_Type *ret = resolved_type_get(lambda->ret);
|
Ast_Resolved_Type *ret = resolved_type_get(lambda->ret);
|
||||||
gen_simple_decl(ret, node->name);
|
gen_simple_decl(ret, node->name);
|
||||||
@@ -267,7 +267,7 @@ gen_ast(Ast *ast){
|
|||||||
else{
|
else{
|
||||||
gen_simple_decl(sym->type, node->name);
|
gen_simple_decl(sym->type, node->name);
|
||||||
gen(" = ");
|
gen(" = ");
|
||||||
gen_expr(node->expr);
|
gen_expr((Ast_Expr *)node->value);
|
||||||
gen(";");
|
gen(";");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
28
main.cpp
28
main.cpp
@@ -7,8 +7,32 @@
|
|||||||
#include "new_resolve.cpp"
|
#include "new_resolve.cpp"
|
||||||
#include "ccodegen.cpp"
|
#include "ccodegen.cpp"
|
||||||
|
|
||||||
|
// 2022.05.28 - On lambda expressions
|
||||||
|
// I think it's not wise to add the multiline lambda expressions
|
||||||
|
// As is the case with python it would require new alternative syntax.
|
||||||
|
// The idea was to imply that the whitespace significant syntax is just
|
||||||
|
// inserting '{' '}' ';' automatically and if you decide to write a brace
|
||||||
|
// it stops being whitespace significant and you can type everything with semicolons and braces
|
||||||
|
// Problem is first of all it's kind of weird to have a completly different syntax
|
||||||
|
// in a language to solve something that is a minor inconvenience,
|
||||||
|
// second of all it turned out to be kind of bad, maybe if it would be more
|
||||||
|
// complicated then it would be ok but it implies that you have to semicolon end
|
||||||
|
// a lot of thing unintuitively.
|
||||||
|
//
|
||||||
|
// Probably single line lambdas should be ok. Currently braces turn off indentation
|
||||||
|
// awareness. There might be something you can do by trying to turn that on
|
||||||
|
// problem is that complicates parsing a lot cause you have to account for multiple
|
||||||
|
// indent styles, which means error messages become bad.
|
||||||
|
|
||||||
|
|
||||||
/// @todo
|
/// @todo
|
||||||
/// [x] - Typespecs should probably be expressions so stuff like would be possible :: *[32]int
|
/// [x] - Typespecs should probably be expressions so stuff like would be possible :: *[32]int
|
||||||
|
/// [ ] - Add single line lambda expressions/
|
||||||
|
/// [ ] - Think about compound expressions, unify with calls - maybe Thing(a=1) instead of Thing{a=1}
|
||||||
|
/// [ ] - Structs
|
||||||
|
/// [ ] - Enums
|
||||||
|
/// [ ] - For loop
|
||||||
|
/// [ ] - Switch
|
||||||
|
|
||||||
|
|
||||||
int main(){
|
int main(){
|
||||||
@@ -23,8 +47,8 @@ int main(){
|
|||||||
test_intern_table();
|
test_intern_table();
|
||||||
lex_test();
|
lex_test();
|
||||||
|
|
||||||
String result = compile_file("globals.kl"_s);
|
// String result = compile_file("globals.kl"_s);
|
||||||
// String result = compile_file("lambdas.kl"_s);
|
String result = compile_file("structs.kl"_s);
|
||||||
// String result = compile_file("order_independent_globals.kl"_s);
|
// String result = compile_file("order_independent_globals.kl"_s);
|
||||||
printf("%s", result.str);
|
printf("%s", result.str);
|
||||||
|
|
||||||
|
|||||||
57
new_ast.cpp
57
new_ast.cpp
@@ -100,13 +100,14 @@ enum Ast_Kind{
|
|||||||
AST_BLOCK,
|
AST_BLOCK,
|
||||||
AST_LAMBDA,
|
AST_LAMBDA,
|
||||||
AST_LAMBDA_ARG,
|
AST_LAMBDA_ARG,
|
||||||
|
AST_STRUCT,
|
||||||
AST_CONST,
|
AST_CONST,
|
||||||
AST_VAR,
|
AST_VAR,
|
||||||
|
};
|
||||||
|
|
||||||
AST_TYPESPEC_IDENT,
|
typedef U32 Ast_Flag;
|
||||||
AST_TYPESPEC_POINTER,
|
enum{
|
||||||
AST_TYPESPEC_ARRAY,
|
AST_EXPR = 1,
|
||||||
AST_TYPESPEC_LAMBDA
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Ast{
|
struct Ast{
|
||||||
@@ -115,11 +116,12 @@ struct Ast{
|
|||||||
|
|
||||||
Ast_Kind kind;
|
Ast_Kind kind;
|
||||||
Ast *parent;
|
Ast *parent;
|
||||||
|
Ast_Flag flags;
|
||||||
// @todo?
|
// @todo?
|
||||||
// bool is_atom: 1;
|
// bool is_atom: 1;
|
||||||
// bool is_stmt: 1;
|
// bool is_stmt: 1;
|
||||||
// bool is_expr: 1;
|
|
||||||
// bool is_decl: 1;
|
// bool is_decl: 1;
|
||||||
|
// bool is_expr: 1;
|
||||||
// bool is_named: 1;
|
// bool is_named: 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -211,6 +213,12 @@ struct Ast_Array: Ast_Expr{
|
|||||||
Ast_Expr *expr;
|
Ast_Expr *expr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Ast_Struct: Ast{
|
||||||
|
// Required to be Ast_Struct or Ast_Var or Ast_Const
|
||||||
|
Array<Ast *> members;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
struct Ast_Named:Ast{
|
struct Ast_Named:Ast{
|
||||||
Intern_String name;
|
Intern_String name;
|
||||||
};
|
};
|
||||||
@@ -221,7 +229,7 @@ struct Ast_Var: Ast_Named{
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Ast_Const: Ast_Named{
|
struct Ast_Const: Ast_Named{
|
||||||
Ast_Expr *expr;
|
Ast *value;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Ast_Package:Ast{
|
struct Ast_Package:Ast{
|
||||||
@@ -240,22 +248,25 @@ struct Ast_Package:Ast{
|
|||||||
result->id = ++pctx->unique_ids
|
result->id = ++pctx->unique_ids
|
||||||
|
|
||||||
function Ast_Atom *
|
function Ast_Atom *
|
||||||
ast_str(Token *pos, Intern_String string){
|
ast_str(Token *pos, Intern_String string, Ast_Flag flags = 0){
|
||||||
AST_NEW(Atom, STR, pos);
|
AST_NEW(Atom, STR, pos);
|
||||||
|
result->flags = flags;
|
||||||
result->intern_val = string;
|
result->intern_val = string;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Atom *
|
function Ast_Atom *
|
||||||
ast_ident(Token *pos, Intern_String string){
|
ast_ident(Token *pos, Intern_String string, Ast_Flag flags = 0){
|
||||||
AST_NEW(Atom, IDENT, pos);
|
AST_NEW(Atom, IDENT, pos);
|
||||||
|
result->flags = flags;
|
||||||
result->intern_val = string;
|
result->intern_val = string;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Atom *
|
function Ast_Atom *
|
||||||
ast_int(Token *pos, S64 integer){
|
ast_int(Token *pos, S64 integer, Ast_Flag flags){
|
||||||
AST_NEW(Atom, INT, pos);
|
AST_NEW(Atom, INT, pos);
|
||||||
|
result->flags = flags;
|
||||||
result->int_val = integer;
|
result->int_val = integer;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -263,6 +274,7 @@ ast_int(Token *pos, S64 integer){
|
|||||||
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(Binary, BINARY, op);
|
AST_NEW(Binary, BINARY, op);
|
||||||
|
result->flags = AST_EXPR;
|
||||||
result->op = op->kind;
|
result->op = op->kind;
|
||||||
result->left = left;
|
result->left = left;
|
||||||
result->right = right;
|
result->right = right;
|
||||||
@@ -274,6 +286,7 @@ ast_expr_binary(Ast_Expr *left, Ast_Expr *right, Token *op){
|
|||||||
function Ast_Compound *
|
function Ast_Compound *
|
||||||
ast_expr_compound(Token *pos, Ast_Expr *typespec, Array<Ast_Compound_Item *> exprs){
|
ast_expr_compound(Token *pos, Ast_Expr *typespec, Array<Ast_Compound_Item *> exprs){
|
||||||
AST_NEW(Compound, COMPOUND, pos);
|
AST_NEW(Compound, COMPOUND, pos);
|
||||||
|
result->flags = AST_EXPR;
|
||||||
result->typespec = typespec;
|
result->typespec = typespec;
|
||||||
result->exprs = exprs.tight_copy(pctx->perm);
|
result->exprs = exprs.tight_copy(pctx->perm);
|
||||||
if(result->typespec) result->typespec->parent = result;
|
if(result->typespec) result->typespec->parent = result;
|
||||||
@@ -284,6 +297,7 @@ ast_expr_compound(Token *pos, Ast_Expr *typespec, Array<Ast_Compound_Item *> exp
|
|||||||
function Ast_Compound_Item *
|
function Ast_Compound_Item *
|
||||||
ast_expr_compound_item(Token *pos, Ast_Expr *index, Ast_Atom *name, Ast_Expr *item){
|
ast_expr_compound_item(Token *pos, Ast_Expr *index, Ast_Atom *name, Ast_Expr *item){
|
||||||
AST_NEW(Compound_Item, COMPOUND_ITEM, pos);
|
AST_NEW(Compound_Item, COMPOUND_ITEM, pos);
|
||||||
|
result->flags = AST_EXPR;
|
||||||
result->name = name;
|
result->name = name;
|
||||||
result->index = index;
|
result->index = index;
|
||||||
result->item = item;
|
result->item = item;
|
||||||
@@ -296,6 +310,7 @@ ast_expr_compound_item(Token *pos, Ast_Expr *index, Ast_Atom *name, Ast_Expr *it
|
|||||||
function Ast_Expr *
|
function Ast_Expr *
|
||||||
ast_expr_cast(Token *pos, Ast_Expr *expr, Ast_Expr *typespec){
|
ast_expr_cast(Token *pos, Ast_Expr *expr, Ast_Expr *typespec){
|
||||||
AST_NEW(Cast, CAST, pos);
|
AST_NEW(Cast, CAST, pos);
|
||||||
|
result->flags = AST_EXPR;
|
||||||
result->expr = expr;
|
result->expr = expr;
|
||||||
result->typespec = typespec;
|
result->typespec = typespec;
|
||||||
expr->parent = result;
|
expr->parent = result;
|
||||||
@@ -306,6 +321,7 @@ ast_expr_cast(Token *pos, Ast_Expr *expr, Ast_Expr *typespec){
|
|||||||
function Ast_Expr *
|
function Ast_Expr *
|
||||||
ast_expr_unary(Token *pos, Token_Kind op, Ast_Expr *expr){
|
ast_expr_unary(Token *pos, Token_Kind op, Ast_Expr *expr){
|
||||||
AST_NEW(Unary, UNARY, pos);
|
AST_NEW(Unary, UNARY, pos);
|
||||||
|
result->flags = AST_EXPR;
|
||||||
result->expr = expr;
|
result->expr = expr;
|
||||||
result->op = op;
|
result->op = op;
|
||||||
expr->parent = result;
|
expr->parent = result;
|
||||||
@@ -315,6 +331,7 @@ ast_expr_unary(Token *pos, Token_Kind op, Ast_Expr *expr){
|
|||||||
function Ast_Expr *
|
function Ast_Expr *
|
||||||
ast_expr_index(Token *pos, Ast_Expr *expr, Ast_Expr *index){
|
ast_expr_index(Token *pos, Ast_Expr *expr, Ast_Expr *index){
|
||||||
AST_NEW(Index, INDEX, pos);
|
AST_NEW(Index, INDEX, pos);
|
||||||
|
result->flags = AST_EXPR;
|
||||||
result->expr = expr;
|
result->expr = expr;
|
||||||
result->index = index;
|
result->index = index;
|
||||||
expr->parent = result;
|
expr->parent = result;
|
||||||
@@ -325,6 +342,7 @@ ast_expr_index(Token *pos, Ast_Expr *expr, Ast_Expr *index){
|
|||||||
function Ast_Lambda *
|
function Ast_Lambda *
|
||||||
ast_lambda(Token *pos, Array<Ast_Lambda_Arg *> params, Ast_Expr *ret, Ast_Block *block){
|
ast_lambda(Token *pos, Array<Ast_Lambda_Arg *> params, Ast_Expr *ret, Ast_Block *block){
|
||||||
AST_NEW(Lambda, LAMBDA, pos);
|
AST_NEW(Lambda, LAMBDA, pos);
|
||||||
|
result->flags = AST_EXPR;
|
||||||
result->args = params.tight_copy(pctx->perm);
|
result->args = params.tight_copy(pctx->perm);
|
||||||
result->block = block;
|
result->block = block;
|
||||||
result->ret = ret;
|
result->ret = ret;
|
||||||
@@ -339,6 +357,7 @@ ast_lambda(Token *pos, Array<Ast_Lambda_Arg *> params, Ast_Expr *ret, Ast_Block
|
|||||||
function Ast_Lambda_Arg *
|
function Ast_Lambda_Arg *
|
||||||
ast_expr_lambda_arg(Token *pos, Intern_String name, Ast_Expr *typespec){
|
ast_expr_lambda_arg(Token *pos, Intern_String name, Ast_Expr *typespec){
|
||||||
AST_NEW(Lambda_Arg, LAMBDA_ARG, pos);
|
AST_NEW(Lambda_Arg, LAMBDA_ARG, pos);
|
||||||
|
result->flags = AST_EXPR;
|
||||||
result->name = name;
|
result->name = name;
|
||||||
result->typespec = typespec;
|
result->typespec = typespec;
|
||||||
result->typespec->parent = result;
|
result->typespec->parent = result;
|
||||||
@@ -387,11 +406,23 @@ ast_init(Token *pos, Token_Kind op, Ast_Atom *ident, Ast_Expr *expr){
|
|||||||
function Ast_Array *
|
function Ast_Array *
|
||||||
ast_array(Token *pos, Ast_Expr *expr){
|
ast_array(Token *pos, Ast_Expr *expr){
|
||||||
AST_NEW(Array, ARRAY, pos);
|
AST_NEW(Array, ARRAY, pos);
|
||||||
|
result->flags = AST_EXPR;
|
||||||
result->expr = expr;
|
result->expr = expr;
|
||||||
result->expr->parent = result;
|
result->expr->parent = result;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Ast_Struct *
|
||||||
|
ast_struct(Token *pos, Array<Ast *> members){
|
||||||
|
AST_NEW(Struct, STRUCT, pos);
|
||||||
|
result->members = members.tight_copy(pctx->perm);
|
||||||
|
For(result->members) {
|
||||||
|
assert(it[0]->kind == AST_VAR || it[0]->kind == AST_CONST || it[0]->kind == AST_STRUCT);
|
||||||
|
it[0]->parent = result;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Declarations
|
// Declarations
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@@ -407,11 +438,13 @@ ast_var(Token *pos, Ast_Expr *typespec, Intern_String name, Ast_Expr *expr){
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Const *
|
function Ast_Const *
|
||||||
ast_const(Token *pos, Intern_String name, Ast_Expr *expr){
|
ast_const(Token *pos, Intern_String name, Ast *value){
|
||||||
AST_NEW(Const, CONST, pos);
|
AST_NEW(Const, CONST, pos);
|
||||||
result->expr = expr;
|
|
||||||
|
assert(value->kind == AST_STRUCT || is_flag_set(value->flags, AST_EXPR));
|
||||||
|
result->value = value;
|
||||||
result->name = name;
|
result->name = name;
|
||||||
result->expr->parent = result;
|
result->value->parent = result;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -281,9 +281,9 @@ parse_lambda(Token *token, B32 is_typespec = false){
|
|||||||
function Ast_Expr *
|
function Ast_Expr *
|
||||||
null_denotation(Token *token){
|
null_denotation(Token *token){
|
||||||
switch(token->kind){
|
switch(token->kind){
|
||||||
case TK_StringLit : return ast_str(token, token->intern_val);
|
case TK_StringLit : return ast_str(token, token->intern_val, AST_EXPR);
|
||||||
case TK_Identifier : return ast_ident(token, token->intern_val);
|
case TK_Identifier : return ast_ident(token, token->intern_val, AST_EXPR);
|
||||||
case TK_Integer : return ast_int(token, token->int_val);
|
case TK_Integer : return ast_int(token, token->int_val, AST_EXPR);
|
||||||
case TK_Pointer : return ast_expr_unary(token, TK_Pointer, parse_expr());
|
case TK_Pointer : return ast_expr_unary(token, TK_Pointer, parse_expr());
|
||||||
case TK_Dereference: return ast_expr_unary(token, TK_Dereference, parse_expr());
|
case TK_Dereference: return ast_expr_unary(token, TK_Dereference, parse_expr());
|
||||||
case TK_OpenBracket: {
|
case TK_OpenBracket: {
|
||||||
@@ -386,6 +386,23 @@ parse_assign_expr(){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Ast_Struct *
|
||||||
|
parse_struct(Token *pos){
|
||||||
|
Scratch scratch;
|
||||||
|
Array<Ast *> members = {scratch};
|
||||||
|
|
||||||
|
token_match(OPEN_SCOPE);
|
||||||
|
do{
|
||||||
|
Token *token = token_get();
|
||||||
|
Ast_Named *named = parse_named(false);
|
||||||
|
if(!named) parsing_error(token, "Failed to parse struct member");
|
||||||
|
}while(token_match(SAME_SCOPE));
|
||||||
|
token_expect(CLOSE_SCOPE);
|
||||||
|
|
||||||
|
Ast_Struct *result = ast_struct(pos, members);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
function Ast_Named *
|
function Ast_Named *
|
||||||
parse_named(B32 is_global){
|
parse_named(B32 is_global){
|
||||||
Ast_Named *result = 0;
|
Ast_Named *result = 0;
|
||||||
@@ -393,10 +410,24 @@ parse_named(B32 is_global){
|
|||||||
if(token_is(TK_Identifier)){
|
if(token_is(TK_Identifier)){
|
||||||
if(is_global && pctx->indent != 0) parsing_error(token_get(), "Top level declarations shouldn't be indented");
|
if(is_global && pctx->indent != 0) parsing_error(token_get(), "Top level declarations shouldn't be indented");
|
||||||
Token *name = token_next();
|
Token *name = token_next();
|
||||||
if(token_match(TK_DoubleColon)){ // Constant
|
|
||||||
|
// @note: parse constant
|
||||||
|
if(token_match(TK_DoubleColon)){
|
||||||
|
// parse struct binding
|
||||||
|
Token *struct_pos = token_get();
|
||||||
|
if(token_match_keyword(keyword_struct)){
|
||||||
|
Ast_Struct *struct_val = parse_struct(struct_pos);
|
||||||
|
result = ast_const(name, name->intern_val, struct_val);
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse constant expression
|
||||||
|
else{
|
||||||
Ast_Expr *expr = parse_expr();
|
Ast_Expr *expr = parse_expr();
|
||||||
result = ast_const(name, name->intern_val, expr);
|
result = ast_const(name, name->intern_val, expr);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// @note: parse variable
|
||||||
else if(token_match(TK_Colon)){
|
else if(token_match(TK_Colon)){
|
||||||
Ast_Expr *typespec = 0;
|
Ast_Expr *typespec = 0;
|
||||||
Ast_Expr *expr = 0;
|
Ast_Expr *expr = 0;
|
||||||
|
|||||||
@@ -504,7 +504,7 @@ eval_decl(Ast *ast, Sym *sym){
|
|||||||
}
|
}
|
||||||
|
|
||||||
Ast_Begin(AST_CONST, Ast_Const){
|
Ast_Begin(AST_CONST, Ast_Const){
|
||||||
Operand expr = eval_expr(node->expr, 0, sym);
|
Operand expr = eval_expr((Ast_Expr *)node->value, 0, sym);
|
||||||
if(!expr.type) parsing_error(node->pos, "Constant value without expression");
|
if(!expr.type) parsing_error(node->pos, "Constant value without expression");
|
||||||
if(!expr.is_const) parsing_error(node->pos, "Value of constant variable is not a constant expression");
|
if(!expr.is_const) parsing_error(node->pos, "Value of constant variable is not a constant expression");
|
||||||
return expr;
|
return expr;
|
||||||
@@ -519,8 +519,8 @@ function Ast_Lambda *
|
|||||||
ast_get_lambda(Ast *ast){
|
ast_get_lambda(Ast *ast){
|
||||||
if(ast->kind == AST_CONST){
|
if(ast->kind == AST_CONST){
|
||||||
auto ast_const = (Ast_Const *)ast;
|
auto ast_const = (Ast_Const *)ast;
|
||||||
if(ast_const->expr){
|
if(ast_const->value){
|
||||||
auto ast_expr = ast_const->expr;
|
auto ast_expr = ast_const->value;
|
||||||
if(ast_expr->kind == AST_LAMBDA){
|
if(ast_expr->kind == AST_LAMBDA){
|
||||||
return (Ast_Lambda *)ast_expr;
|
return (Ast_Lambda *)ast_expr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ unifying the call expression and compound expression
|
|||||||
seems more unified and better for coherence
|
seems more unified and better for coherence
|
||||||
but more abigous and probably harder to implement
|
but more abigous and probably harder to implement
|
||||||
|
|
||||||
|
value :: call((thing: int): int thing += 1; return thing, )
|
||||||
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
0
structs.kl
Normal file
0
structs.kl
Normal file
Reference in New Issue
Block a user