Before adding untyped types

This commit is contained in:
Krzosa Karol
2022-06-01 21:38:39 +02:00
parent 75985de125
commit ebb21df015
6 changed files with 178 additions and 152 deletions

View File

@@ -32,6 +32,7 @@ For now I don't thing it should be overloadable.
-------------------------------------------------------------------------------
@todo
[ ] - Test new operators, add constant eval for them
[ ] - Compiling and running a program
[ ] - Passing down program to compile through command line
[ ] - More operators
@@ -39,15 +40,21 @@ For now I don't thing it should be overloadable.
[ ] - Fixing access to constants, in C we cant have constants inside of structs / functions so we need to rewrite the tree
[ ] - Default values in structs??? Should compound stmts bring values from default values?? Maybe not? Whats the alternative
[ ] - Write up on order independent declarations
[ ] - Order independent declarations in structs
[ ] - Switch
[ ] - More basic types
[ ] - Array of inferred size
[ ] - Add single line lambda expressions
[ ] - Ternary operator
[ ] - Constants embeded in structs should be able to refer to other constants in that namespace without prefix
[ ] - Order independent constants in structs
[ ] - Can you even have recursive lambdas in structs, other recursive stuff
[ ] - Casting to basic types by call S64(x)
[ ] - Type aliases :: should probably be strictly typed, but assigning constant values should work
@ideas
[ ] - [Using] keyword that brings in the struct enviroment into current scope etc.
[ ] - Constant arrays that evaluate fully at compile time
[ ] - Rust like enum where you associate values(other structs) with keys
@donzo
[x] - lvalue, rvalue concept so we cant assign value to some arbitrary weird expression
@@ -78,10 +85,6 @@ For now I don't thing it should be overloadable.
#include "typecheck.h"
#include "typecheck.cpp"
#include "ccodegen.cpp"
int main(){
test_os_memory();
@@ -102,17 +105,17 @@ int main(){
printf("%s", result.str);
result = compile_file("order1.kl"_s);
printf("%s", result.str);
result = compile_file("order2.kl"_s);
printf("%s", result.str);
result = compile_file("lambdas.kl"_s);
printf("%s", result.str);
result = compile_file("order2.kl"_s);
printf("%s", result.str);
#endif
result = compile_file("lexer.kl"_s);
FILE *f = fopen("program.c", "w");
assert(f);
fprintf(f, "%.*s", (int)result.len, result.str);
fclose(f);
// result = compile_file("lexer.kl"_s);
// FILE *f = fopen("program.c", "w");
// assert(f);
// fprintf(f, "%.*s", (int)result.len, result.str);
// fclose(f);
// __debugbreak();
__debugbreak();
}

View File

@@ -134,6 +134,10 @@ struct Lexer{
force_inline B32 token_is_assign(Token_Kind token){return token >= TK_FirstAssign && token <= TK_LastAssign;}
force_inline B32 token_is_assign(Token *token){return token_is_assign(token->kind);}
force_inline B32 token_is_compare(Token_Kind token){return token >= TK_FirstCompare && token <= TK_LastCompare;}
force_inline B32 token_is_compare(Token *token){return token_is_compare(token->kind);}
function U8
lexc(Lex_Stream *s){

View File

@@ -110,41 +110,7 @@ token_expect(Token_Kind kind){
return 0;
}
//-----------------------------------------------------------------------------
// Expression parsing
//-----------------------------------------------------------------------------
/*
add = [+-]
mul = [/%*]
compare = == | != | >= | > | <= | <
logical = [&|^] | && | ||
unary = [&*-!~+] | ++ | --
atom_expr = Int
| Float
| String
| Identifier
| 'cast' '(' typespec ',' expr ')'
| 'size_type' '(' typespec ')'
| 'size_expr' '(' expr ')'
| '{' call_expr '}'
| '(' expr ')'
| '(' ':' typespec ')' '{' call_expr '}'
postfix_expr = atom_expr ('[' expr ']' | '.' Identifier | ++ | -- | '(' expr_list ')')*
unary_expr = unary ? unary_expr : atom_expr
mul_expr = atom_expr (mul atom_expr)*
add_expr = mul_expr (add mul_expr)*
logical_expr = add_expr (logical add_expr)*
compare_expr = logical_expr (compare logical_expr)*
ternary_expr = compare_expr ('?' ternary_expr ':' ternary_expr)?
expr = logical_expr
Compound literals
- (:[23]*Type){}
- Type{}
- { }
*/
function Ast_Expr *parse_expr(S64 rbp = 0);
function Ast_Expr *parse_expr(S64 minbp = 0);
function Ast_Expr *
parse_init_stmt(Ast_Expr *expr){

View File

@@ -56,6 +56,9 @@ test_assignments :: ()
i >>= 2
i <<= 2
i = i > 2
CONST :: 23 == 23
j: *int
*j = 1
/* invalid

View File

@@ -23,7 +23,14 @@ resolve_type_pair(Token *pos, Ast_Resolved_Type *a, Ast_Resolved_Type *b){
}
if(result->kind == TYPE_NULL) parsing_error(pos, "Couldn't infer type of null value");
return result;
}
function Operand
resolve_operand_pair(Token *pos, Operand a, Operand b){
Operand result = {};
result.is_const = a.is_const && b.is_const;
result.type = resolve_type_pair(pos, a.type, b.type);
return result;
}
@@ -400,8 +407,7 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res
CASE(BINARY, Binary){
Operand result = {};
switch(node->op){
case TK_ColonAssign:{
if(node->op == TK_ColonAssign){
// @note: This is actually a statement so it doesn't need to return Operand
assert(is_flag_set(node->flags, AST_STMT));
assert(node->left->kind == AST_IDENT);
@@ -409,8 +415,12 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res
Operand right = resolve_expr(node->right);
Ast_Atom *atom = (Ast_Atom *)node->left;
sym_insert(SYM_VAR, atom->intern_val, right.type, right.value, node);
}break;
case TK_Dot: {
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
else if(node->op == TK_Dot){
B32 required_to_be_const = false;
// @note: resolve first chunk which involves querying global map
// second part requires searching through a struct
@@ -486,13 +496,38 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res
if(result.is_const == false && required_to_be_const){
invalid_codepath;
}
} break;
default: {
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
else if(token_is_compare(node->op)){
Operand left = resolve_expr(node->left);
Operand right = resolve_expr(node->right);
result.type = resolve_type_pair(node->pos, left.type, right.type);
if(left.is_const && right.is_const){
result.is_const = true;
result = resolve_operand_pair(node->pos, left, right);
if(result.is_const){
if(result.type == type_int){
switch(node->op){
case TK_GreaterThen : result.bool_val = left.int_val > right.int_val; break;
case TK_GreaterThenOrEqual: result.bool_val = left.int_val >= right.int_val; break;
case TK_LesserThen : result.bool_val = left.int_val < right.int_val; break;
case TK_LesserThenOrEqual : result.bool_val = left.int_val <= right.int_val; break;
case TK_Equals : result.bool_val = left.int_val == right.int_val; break;
case TK_NotEquals : result.bool_val = left.int_val != right.int_val; break;
invalid_default_case;
}
}
else parsing_error(node->pos, "Arithmetic on type [%s] is not supported", type_names[result.type->kind]);
}
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
else{
Operand left = resolve_expr(node->left);
Operand right = resolve_expr(node->right);
result = resolve_operand_pair(node->pos, left, right);
if(result.is_const){
if(result.type == type_int){
switch(node->op){
case TK_Add: result.int_val = left.int_val + right.int_val; break;
@@ -503,9 +538,11 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res
}
}
else parsing_error(node->pos, "Arithmetic on type [%s] is not supported", type_names[result.type->kind]);
}break;
}
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
return result;
BREAK();
@@ -514,7 +551,7 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res
invalid_default_case;
}
return {};
invalid_return;
}
function Operand

View File

@@ -6,6 +6,9 @@ enum Ast_Resolved_Type_Kind{
TYPE_NULL,
TYPE_COMPLETING,
TYPE_INCOMPLETE,
TYPE_UNTYPED_BOOL,
TYPE_UNTYPED_INT,
TYPE_UNTYPED_STRING,
TYPE_INT,
TYPE_BOOL,
TYPE_UNSIGNED,
@@ -25,6 +28,9 @@ const char *type_names[] = {
"[Null]",
"[Completing]",
"[Incomplete]",
"[Untyped_Bool]",
"[Untyped_Int]",
"[Untyped_String]",
"[Int]",
"[Bool]",
"[Unsigned]",
@@ -75,7 +81,6 @@ const SizeU pointer_align = __alignof(SizeU);
global Ast_Resolved_Type type__null = {TYPE_NULL};
global Ast_Resolved_Type type__void = {TYPE_VOID};
global Ast_Resolved_Type type__int = {TYPE_INT, sizeof(int), __alignof(int)};
global Ast_Resolved_Type type__unsigned = {TYPE_INT, sizeof(unsigned), __alignof(unsigned)};
global Ast_Resolved_Type type__string = {TYPE_STRING, sizeof(String), __alignof(String)};
global Ast_Resolved_Type type__bool = {TYPE_BOOL, sizeof(bool), __alignof(bool)};
global Ast_Resolved_Type type__type = {TYPE_TYPE};
@@ -83,11 +88,18 @@ global Ast_Resolved_Type type__type = {TYPE_TYPE};
global Ast_Resolved_Type *type_type = &type__type;
global Ast_Resolved_Type *type_void = &type__void;
global Ast_Resolved_Type *type_int = &type__int;
global Ast_Resolved_Type *type_unsigned = &type__unsigned;
global Ast_Resolved_Type *type_string = &type__string;
global Ast_Resolved_Type *type_bool = &type__bool;
global Ast_Resolved_Type *type_null = &type__null;
global Ast_Resolved_Type type__untyped_bool = {TYPE_UNTYPED_BOOL, sizeof(bool), __alignof(bool)};
global Ast_Resolved_Type type__untyped_int = {TYPE_UNTYPED_INT, sizeof(S64), __alignof(S64)};
global Ast_Resolved_Type type__untyped_string = {TYPE_UNTYPED_STRING, sizeof(String), __alignof(String)};
global Ast_Resolved_Type *type_untyped_string = &type__untyped_string;
global Ast_Resolved_Type *type_untyped_bool = &type__untyped_bool;
global Ast_Resolved_Type *type_untyped_int = &type__untyped_int;
//-----------------------------------------------------------------------------
// Symbols
//-----------------------------------------------------------------------------
@@ -104,6 +116,7 @@ enum Sym_State{
};
#define VALUE_FIELDS \
bool bool_val; \
S64 int_val; \
Intern_String intern_val; \
Ast_Resolved_Type *type_val;