Fixing bugs, pointer arithmetic checking, better for, working on first program
This commit is contained in:
14
ccodegen.cpp
14
ccodegen.cpp
@@ -66,7 +66,7 @@ gen_simple_decl(Ast_Resolved_Type *ast, Intern_String name){
|
|||||||
|
|
||||||
function void
|
function void
|
||||||
gen_value(Value a){
|
gen_value(Value a){
|
||||||
gen("%s", docname(a.type));
|
// gen("%s", docname(a.type));
|
||||||
switch(a.type->kind){
|
switch(a.type->kind){
|
||||||
CASE_INT: {
|
CASE_INT: {
|
||||||
Scratch scratch;
|
Scratch scratch;
|
||||||
@@ -94,10 +94,12 @@ gen_expr(Ast_Expr *ast){
|
|||||||
}
|
}
|
||||||
|
|
||||||
CASE(INDEX, Index){
|
CASE(INDEX, Index){
|
||||||
|
gen("(");
|
||||||
gen_expr(node->expr);
|
gen_expr(node->expr);
|
||||||
gen("[");
|
gen("[");
|
||||||
gen_expr(node->index);
|
gen_expr(node->index);
|
||||||
gen("]");
|
gen("]");
|
||||||
|
gen(")");
|
||||||
BREAK();
|
BREAK();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,7 +337,7 @@ gen_ast(Ast *ast){
|
|||||||
if(sym->type_val->kind == TYPE_STRUCT){
|
if(sym->type_val->kind == TYPE_STRUCT){
|
||||||
Ast_Struct *agg = (Ast_Struct *)sym->type_val->ast;
|
Ast_Struct *agg = (Ast_Struct *)sym->type_val->ast;
|
||||||
if(node->value->kind == AST_STRUCT){
|
if(node->value->kind == AST_STRUCT){
|
||||||
gen("struct %s{", node->name.str);
|
gen("typedef struct %s{", node->name.str);
|
||||||
global_indent++;
|
global_indent++;
|
||||||
For(agg->members){
|
For(agg->members){
|
||||||
genln("");
|
genln("");
|
||||||
@@ -347,7 +349,7 @@ gen_ast(Ast *ast){
|
|||||||
gen_ast(it);
|
gen_ast(it);
|
||||||
}
|
}
|
||||||
global_indent--;
|
global_indent--;
|
||||||
genln("};");
|
genln("}%s;", node->name.str);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
// Type alias
|
// Type alias
|
||||||
@@ -428,12 +430,18 @@ typedef U64 SizeU;
|
|||||||
typedef S64 SizeS;
|
typedef S64 SizeS;
|
||||||
typedef float F32;
|
typedef float F32;
|
||||||
typedef double F64;
|
typedef double F64;
|
||||||
|
typedef S32 Bool;
|
||||||
|
|
||||||
typedef struct String{
|
typedef struct String{
|
||||||
U8 *str;
|
U8 *str;
|
||||||
S64 len;
|
S64 len;
|
||||||
}String;
|
}String;
|
||||||
#define LIT(x) (String){.str=(U8 *)x, .len=sizeof(x)-1}
|
#define LIT(x) (String){.str=(U8 *)x, .len=sizeof(x)-1}
|
||||||
|
|
||||||
|
void entry();
|
||||||
|
int main(){
|
||||||
|
entry();
|
||||||
|
}
|
||||||
)==");
|
)==");
|
||||||
|
|
||||||
F64 resolve_begin = os_time();
|
F64 resolve_begin = os_time();
|
||||||
|
|||||||
9
main.cpp
9
main.cpp
@@ -77,7 +77,6 @@ Expr:
|
|||||||
|
|
||||||
|
|
||||||
@todo
|
@todo
|
||||||
[ ] - Fix casting
|
|
||||||
[ ] - Make sure pointer arithmetic works
|
[ ] - Make sure pointer arithmetic works
|
||||||
[ ] - Passing down program to compile through command line
|
[ ] - Passing down program to compile through command line
|
||||||
[ ] - More for loop variations
|
[ ] - More for loop variations
|
||||||
@@ -108,10 +107,12 @@ Expr:
|
|||||||
[ ] - Compound that zeros values - .{} , Compound that assumes defaults from struct definition - {}
|
[ ] - Compound that zeros values - .{} , Compound that assumes defaults from struct definition - {}
|
||||||
|
|
||||||
@donzo
|
@donzo
|
||||||
|
[x] - We are parsing wrong here: (t.str=(&string_to_lex.str)[i]);
|
||||||
[x] - Test new operators, add constant eval for them
|
[x] - Test new operators, add constant eval for them
|
||||||
[x] - lvalue, rvalue concept so we cant assign value to some arbitrary weird expression
|
[x] - lvalue, rvalue concept so we cant assign value to some arbitrary weird expression
|
||||||
[x] - More basic types
|
[x] - More basic types
|
||||||
[x] - Implementing required operations int128
|
[x] - Implementing required operations int128
|
||||||
|
[x] - Fix casting
|
||||||
[x] - Add basic support for floats
|
[x] - Add basic support for floats
|
||||||
[x] - Converting from U64 token to S64 Atom introduces unnanounced error (negates) - probably need big int
|
[x] - Converting from U64 token to S64 Atom introduces unnanounced error (negates) - probably need big int
|
||||||
[x] - Add basic setup for new type system
|
[x] - Add basic setup for new type system
|
||||||
@@ -167,7 +168,7 @@ int main(){
|
|||||||
|
|
||||||
|
|
||||||
String result = {};
|
String result = {};
|
||||||
#if 1
|
#if 0
|
||||||
result = compile_file("globals.kl"_s);
|
result = compile_file("globals.kl"_s);
|
||||||
printf("%s", result.str);
|
printf("%s", result.str);
|
||||||
result = compile_file("enums.kl"_s);
|
result = compile_file("enums.kl"_s);
|
||||||
@@ -178,12 +179,12 @@ int main(){
|
|||||||
printf("%s", result.str);
|
printf("%s", result.str);
|
||||||
result = compile_file("lambdas.kl"_s);
|
result = compile_file("lambdas.kl"_s);
|
||||||
printf("%s", result.str);
|
printf("%s", result.str);
|
||||||
#endif
|
|
||||||
result = compile_file("new_types.kl"_s);
|
result = compile_file("new_types.kl"_s);
|
||||||
printf("%s", result.str);
|
printf("%s", result.str);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
#if 1
|
||||||
result = compile_file("program.kl"_s);
|
result = compile_file("program.kl"_s);
|
||||||
FILE *f = fopen("program.c", "w");
|
FILE *f = fopen("program.c", "w");
|
||||||
assert(f);
|
assert(f);
|
||||||
|
|||||||
@@ -118,7 +118,9 @@ function Ast_Expr *parse_expr(S64 minbp = 0);
|
|||||||
function Ast_Expr *
|
function Ast_Expr *
|
||||||
parse_init_stmt(Ast_Expr *expr){
|
parse_init_stmt(Ast_Expr *expr){
|
||||||
Token *token = token_get();
|
Token *token = token_get();
|
||||||
if(token->kind == TK_ColonAssign && expr->kind != AST_IDENT) parsing_error(expr->pos, "Binding with [:=] to something that is not an identifier");
|
if(token->kind == TK_ColonAssign && expr->kind != AST_IDENT)
|
||||||
|
parsing_error(expr->pos, "Binding with [:=] to something that is not an identifier");
|
||||||
|
|
||||||
if(token_is_assign(token)){
|
if(token_is_assign(token)){
|
||||||
token_next();
|
token_next();
|
||||||
Ast_Expr *value = parse_expr();
|
Ast_Expr *value = parse_expr();
|
||||||
@@ -359,7 +361,7 @@ binding_power(Binding binding, Token_Kind kind){
|
|||||||
Postfix: switch(kind){
|
Postfix: switch(kind){
|
||||||
case TK_OpenBracket:
|
case TK_OpenBracket:
|
||||||
case TK_OpenParen:
|
case TK_OpenParen:
|
||||||
return {20, -2};
|
return {21, -2};
|
||||||
default: return{-1,-1};
|
default: return{-1,-1};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,9 @@ unary_test :: ()
|
|||||||
var2: S64 = 20
|
var2: S64 = 20
|
||||||
var_bool: Bool = !var1 == !var2
|
var_bool: Bool = !var1 == !var2
|
||||||
|
|
||||||
|
pointer: *S64
|
||||||
|
pointer += 10
|
||||||
|
// pointer = pointer + pointer
|
||||||
|
|
||||||
// uns: U64 = -int_val
|
// uns: U64 = -int_val
|
||||||
// int_float: S64 = float_val
|
// int_float: S64 = float_val
|
||||||
|
|||||||
28
program.c
28
program.c
@@ -16,20 +16,36 @@ typedef U64 SizeU;
|
|||||||
typedef S64 SizeS;
|
typedef S64 SizeS;
|
||||||
typedef float F32;
|
typedef float F32;
|
||||||
typedef double F64;
|
typedef double F64;
|
||||||
|
typedef S32 Bool;
|
||||||
|
|
||||||
typedef struct String{
|
typedef struct String{
|
||||||
U8 *str;
|
U8 *str;
|
||||||
S64 len;
|
S64 len;
|
||||||
}String;
|
}String;
|
||||||
#define LIT(x) (String){.str=(U8 *)x, .len=sizeof(x)-1}
|
#define LIT(x) (String){.str=(U8 *)x, .len=sizeof(x)-1}
|
||||||
|
|
||||||
struct Lex_Stream{
|
void entry();
|
||||||
U8 *stream;
|
|
||||||
U8 *end;
|
|
||||||
};
|
|
||||||
int main(){
|
int main(){
|
||||||
|
entry();
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct Token{
|
||||||
|
U8 *str;
|
||||||
|
S64 len;
|
||||||
|
}Token;
|
||||||
|
Bool is_numeric(U8 c){
|
||||||
|
Bool result = ((c>=48)&&(c<=57));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
void entry(){
|
||||||
String string_to_lex = LIT("Identifier 2425525 Not_Number");
|
String string_to_lex = LIT("Identifier 2425525 Not_Number");
|
||||||
|
Token t;
|
||||||
for(S64 i = 0;(i<string_to_lex.len);(i+=1)){
|
for(S64 i = 0;(i<string_to_lex.len);(i+=1)){
|
||||||
(string_to_lex.str[0]=64);
|
if(is_numeric((string_to_lex.str[i]))){
|
||||||
|
(t.str=(&(string_to_lex.str[i])));
|
||||||
|
for(;is_numeric((string_to_lex.str[i]));){
|
||||||
|
(i+=1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
22
program.kl
22
program.kl
@@ -1,11 +1,21 @@
|
|||||||
|
|
||||||
Lex_Stream :: struct
|
Token :: struct
|
||||||
stream: *U8
|
str: *U8
|
||||||
end : *U8
|
len: S64
|
||||||
|
|
||||||
main :: (): int
|
|
||||||
|
is_numeric :: (c: U8): Bool
|
||||||
|
result := c >= '0 && c <= '9
|
||||||
|
return result
|
||||||
|
|
||||||
|
entry :: ()
|
||||||
string_to_lex := "Identifier 2425525 Not_Number"
|
string_to_lex := "Identifier 2425525 Not_Number"
|
||||||
|
|
||||||
|
t: Token
|
||||||
for i := 0, i < string_to_lex.len, i+=1
|
for i := 0, i < string_to_lex.len, i+=1
|
||||||
string_to_lex.str[0] = 64
|
if is_numeric(string_to_lex.str[i])
|
||||||
|
t.str = &string_to_lex.str[i]
|
||||||
|
for is_numeric(string_to_lex.str[i])
|
||||||
|
i+=1
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,8 @@ convert_untyped_to_typed(Token *pos, Value a, Ast_Resolved_Type *new_type){
|
|||||||
assert(a.type == untyped_int);
|
assert(a.type == untyped_int);
|
||||||
else if(is_int(a.type) && is_float(new_type))
|
else if(is_int(a.type) && is_float(new_type))
|
||||||
a.f64_val = bigint_as_float(&a.big_int_val); // @leak bigint
|
a.f64_val = bigint_as_float(&a.big_int_val); // @leak bigint
|
||||||
|
else if(is_int(a.type) && is_pointer(new_type))
|
||||||
|
;
|
||||||
else if(is_float(a.type) && is_float(new_type))
|
else if(is_float(a.type) && is_float(new_type))
|
||||||
; // nothing to do
|
; // nothing to do
|
||||||
else if(is_bool(a.type) && is_bool(new_type))
|
else if(is_bool(a.type) && is_bool(new_type))
|
||||||
@@ -67,11 +69,18 @@ convert_untyped_to_typed(Token *pos, Value a, Ast_Resolved_Type *new_type){
|
|||||||
|
|
||||||
function void
|
function void
|
||||||
make_sure_types_are_compatible(Token *pos, Value *a, Value *b){
|
make_sure_types_are_compatible(Token *pos, Value *a, Value *b){
|
||||||
if(is_typed(a->type) && is_typed(b->type)){
|
if((is_pointer(a->type) && is_int(b->type)) || (is_pointer(b->type) && is_int(a->type))){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if(is_pointer(a->type) && is_pointer(b->type)){
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
else if(is_typed(a->type) && is_typed(b->type)){
|
||||||
if(a->type != b->type){
|
if(a->type != b->type){
|
||||||
parsing_error(pos, "Type mismatch in make_sure_types_are_compatible - left: %s right: %s", docname(a->type), docname(b->type));
|
fail: parsing_error(pos, "Type mismatch in make_sure_types_are_compatible - left: %s right: %s", docname(a->type), docname(b->type));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(is_untyped(a->type) && is_typed(b->type)){
|
if(is_untyped(a->type) && is_typed(b->type)){
|
||||||
assert(is_typed(b->type));
|
assert(is_typed(b->type));
|
||||||
*a = convert_untyped_to_typed(pos, *a, b->type);
|
*a = convert_untyped_to_typed(pos, *a, b->type);
|
||||||
@@ -80,7 +89,6 @@ make_sure_types_are_compatible(Token *pos, Value *a, Value *b){
|
|||||||
assert(is_typed(a->type));
|
assert(is_typed(a->type));
|
||||||
*b = convert_untyped_to_typed(pos, *b, a->type);
|
*b = convert_untyped_to_typed(pos, *b, a->type);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if(is_int(a->type) && is_float(b->type)){
|
else if(is_int(a->type) && is_float(b->type)){
|
||||||
*a = value_float(a->big_int_val);
|
*a = value_float(a->big_int_val);
|
||||||
}
|
}
|
||||||
@@ -92,7 +100,7 @@ make_sure_types_are_compatible(Token *pos, Value *a, Value *b){
|
|||||||
function Value
|
function Value
|
||||||
compare_values(Token *pos, Token_Kind op, Value a, Value b, bool is_const){
|
compare_values(Token *pos, Token_Kind op, Value a, Value b, bool is_const){
|
||||||
if(!(is_numeric(a.type) && is_numeric(b.type)))
|
if(!(is_numeric(a.type) && is_numeric(b.type)))
|
||||||
parsing_error(pos, "Constant application of binary %s on values of type %s and %s is not allowed", name(op), docname(a.type), docname(a.type));
|
parsing_error(pos, "Constant application of binary %s on values of type %s and %s is not allowed", name(op), docname(a.type), docname(b.type));
|
||||||
|
|
||||||
make_sure_types_are_compatible(pos, &a, &b);
|
make_sure_types_are_compatible(pos, &a, &b);
|
||||||
|
|
||||||
@@ -146,7 +154,7 @@ eval_binary(Token *pos, Token_Kind op, Value a, Value b, bool is_const){
|
|||||||
return compare_values(pos, op, a, b, is_const);
|
return compare_values(pos, op, a, b, is_const);
|
||||||
|
|
||||||
if(!(is_numeric(a.type) && is_numeric(b.type)))
|
if(!(is_numeric(a.type) && is_numeric(b.type)))
|
||||||
parsing_error(pos, "Constant application of binary %s on values of type %s and %s is not allowed", name(op), docname(a.type), docname(a.type));
|
parsing_error(pos, "Constant application of binary %s on values of type %s and %s is not allowed", name(op), docname(a.type), docname(b.type));
|
||||||
|
|
||||||
make_sure_types_are_compatible(pos, &a, &b);
|
make_sure_types_are_compatible(pos, &a, &b);
|
||||||
|
|
||||||
@@ -261,30 +269,45 @@ eval_unary(Token *pos, Token_Kind op, Value *a, bool is_const){
|
|||||||
}
|
}
|
||||||
|
|
||||||
function void
|
function void
|
||||||
convert_untyped_to_typed_default(Operand *op){
|
try_converting_untyped_to_typed(Operand *op){
|
||||||
if(!op) return;
|
|
||||||
if(is_untyped(op->type)){
|
if(is_untyped(op->type)){
|
||||||
if(op->type->kind == TYPE_UNTYPED_INT) op->type = type_s64;
|
switch(op->type->kind){
|
||||||
else if(op->type->kind == TYPE_UNTYPED_BOOL) op->type = type_bool;
|
case TYPE_UNTYPED_INT: op->type = type_s64; break;
|
||||||
else if(op->type->kind == TYPE_UNTYPED_STRING) op->type = type_string;
|
case TYPE_UNTYPED_BOOL: op->type = type_bool; break;
|
||||||
else if(op->type->kind == TYPE_UNTYPED_FLOAT) op->type = type_f64;
|
case TYPE_UNTYPED_STRING: op->type = type_string; break;
|
||||||
else invalid_codepath;
|
case TYPE_UNTYPED_FLOAT: op->type = type_f64; break;
|
||||||
|
default: invalid_codepath;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum{
|
||||||
|
TYPE_AND_EXPR_REQUIRED = 0,
|
||||||
|
TYPE_CAN_BE_NULL = 1,
|
||||||
|
EXPR_CAN_BE_NULL = 2
|
||||||
|
};
|
||||||
|
|
||||||
function void
|
function void
|
||||||
make_sure_types_are_compatible_for_assignment(Token *pos, Operand *expr, Ast_Resolved_Type *type = 0){
|
make_sure_value_is_compatible_with_type(Token *pos, Operand *expr, Ast_Resolved_Type *type, U64 debug_flag){
|
||||||
if(type == expr->type){
|
if(type == expr->type){
|
||||||
|
assert(type);
|
||||||
assert(expr->type);
|
assert(expr->type);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!type)
|
if(!type){
|
||||||
convert_untyped_to_typed_default(expr);
|
assert(is_flag_set(debug_flag, TYPE_CAN_BE_NULL));
|
||||||
else if(!expr->type)
|
assert(expr->type);
|
||||||
|
try_converting_untyped_to_typed(expr);
|
||||||
|
}
|
||||||
|
else if(!expr->type){
|
||||||
|
assert(is_flag_set(debug_flag, EXPR_CAN_BE_NULL));
|
||||||
|
assert(type);
|
||||||
expr->type = type;
|
expr->type = type;
|
||||||
else if(is_untyped(expr->type))
|
}
|
||||||
|
else if(is_untyped(expr->type)){
|
||||||
expr->value = convert_untyped_to_typed(pos, expr->value, type);
|
expr->value = convert_untyped_to_typed(pos, expr->value, type);
|
||||||
|
}
|
||||||
|
|
||||||
if(type && expr->type != type){
|
if(type && expr->type != type){
|
||||||
parsing_error(pos, "Assigning but incompatible types, expression: %s expected var type: %s", docname(expr->type), docname(type));
|
parsing_error(pos, "Assigning but incompatible types, expression: %s expected var type: %s", docname(expr->type), docname(type));
|
||||||
@@ -362,10 +385,16 @@ resolve_stmt(Ast *ast, Ast_Resolved_Type *ret){
|
|||||||
}
|
}
|
||||||
|
|
||||||
CASE(FOR, For){
|
CASE(FOR, For){
|
||||||
|
if(node->init && node->cond == 0 && node->iter == 0){
|
||||||
|
if(!is_flag_set(node->init->flags, AST_STMT)){
|
||||||
|
node->cond = node->init;
|
||||||
|
node->init = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
resolve_expr(node->init, ret);
|
resolve_expr(node->init, ret);
|
||||||
Operand cond = resolve_expr(node->cond); // @todo: typechecking
|
resolve_expr(node->cond, ret);
|
||||||
resolve_expr(node->iter, ret);
|
resolve_expr(node->iter, ret);
|
||||||
unused(cond);
|
|
||||||
resolve_stmt_block(node->block, ret);
|
resolve_stmt_block(node->block, ret);
|
||||||
BREAK();
|
BREAK();
|
||||||
}
|
}
|
||||||
@@ -392,10 +421,16 @@ resolve_stmt(Ast *ast, Ast_Resolved_Type *ret){
|
|||||||
function Operand
|
function Operand
|
||||||
require_const_int(Ast_Expr *expr, B32 ast_can_be_null){
|
require_const_int(Ast_Expr *expr, B32 ast_can_be_null){
|
||||||
Operand op = resolve_expr(expr);
|
Operand op = resolve_expr(expr);
|
||||||
if(expr == 0 && ast_can_be_null) return op;
|
|
||||||
else if(expr == 0) parsing_error(expr->pos, "This field cannot be null");
|
if(expr == 0 && ast_can_be_null)
|
||||||
if(!op.is_const) parsing_error(expr->pos, "Expected a const value");
|
return op;
|
||||||
if(!is_int(op.type)) parsing_error(expr->pos, "Expected a constant integer got instead %s", docname(op.type));
|
else if(expr == 0)
|
||||||
|
parsing_error(expr->pos, "This field cannot be null");
|
||||||
|
|
||||||
|
if(!op.is_const)
|
||||||
|
parsing_error(expr->pos, "Expected a const value");
|
||||||
|
if(!is_int(op.type))
|
||||||
|
parsing_error(expr->pos, "Expected a constant integer got instead %s", docname(op.type));
|
||||||
|
|
||||||
return op;
|
return op;
|
||||||
}
|
}
|
||||||
@@ -410,7 +445,7 @@ resolve_lambda(Ast_Lambda *lambda, Sym *sym = 0){
|
|||||||
Ast_Resolved_Type *type =
|
Ast_Resolved_Type *type =
|
||||||
resolve_typespec(it->typespec, AST_CANT_BE_NULL);
|
resolve_typespec(it->typespec, AST_CANT_BE_NULL);
|
||||||
Operand default_value = resolve_expr(it->default_value, type);
|
Operand default_value = resolve_expr(it->default_value, type);
|
||||||
make_sure_types_are_compatible_for_assignment(it->pos, &default_value, type);
|
make_sure_value_is_compatible_with_type(it->pos, &default_value, type, EXPR_CAN_BE_NULL);
|
||||||
args.add(type);
|
args.add(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -700,7 +735,9 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res
|
|||||||
}
|
}
|
||||||
else{ parsing_error(node->pos, "Dereferencing expression %s that is not a [Pointer] or [Type]", type_names[value.type->kind]); return {}; }
|
else{ parsing_error(node->pos, "Dereferencing expression %s that is not a [Pointer] or [Type]", type_names[value.type->kind]); return {}; }
|
||||||
}break;
|
}break;
|
||||||
case TK_Dereference:{return operand_lvalue(type_pointer(value.type));}break;
|
case TK_Dereference:{
|
||||||
|
return operand_lvalue(type_pointer(value.type));
|
||||||
|
}break;
|
||||||
case TK_Neg:case TK_Not:case TK_Add:case TK_Sub:{
|
case TK_Neg:case TK_Not:case TK_Add:case TK_Sub:{
|
||||||
Operand op = resolve_expr(node->expr);
|
Operand op = resolve_expr(node->expr);
|
||||||
eval_unary(node->pos, node->op, &op.value, op.is_const);
|
eval_unary(node->pos, node->op, &op.value, op.is_const);
|
||||||
@@ -724,7 +761,7 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res
|
|||||||
assert(node->left->kind == AST_IDENT);
|
assert(node->left->kind == AST_IDENT);
|
||||||
|
|
||||||
Operand right = resolve_expr(node->right);
|
Operand right = resolve_expr(node->right);
|
||||||
make_sure_types_are_compatible_for_assignment(node->pos, &right);
|
make_sure_value_is_compatible_with_type(node->pos, &right, 0, TYPE_CAN_BE_NULL);
|
||||||
assert(right.type);
|
assert(right.type);
|
||||||
|
|
||||||
auto atom = (Ast_Atom *)node->left;
|
auto atom = (Ast_Atom *)node->left;
|
||||||
@@ -840,7 +877,7 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res
|
|||||||
rewrite_into_const(node, Ast_Binary, value);
|
rewrite_into_const(node, Ast_Binary, value);
|
||||||
result = operand_const_rvalue(value);
|
result = operand_const_rvalue(value);
|
||||||
}
|
}
|
||||||
else result = operand_rvalue(left.type);
|
else result = operand_rvalue(value.type);
|
||||||
|
|
||||||
}
|
}
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@@ -903,7 +940,7 @@ resolve_binding(Ast *ast, Sym *sym){
|
|||||||
Ast_Resolved_Type *type = resolve_typespec(node->typespec, AST_CAN_BE_NULL);
|
Ast_Resolved_Type *type = resolve_typespec(node->typespec, AST_CAN_BE_NULL);
|
||||||
Operand expr = resolve_expr(node->expr, type);
|
Operand expr = resolve_expr(node->expr, type);
|
||||||
assert(expr.type != 0 || type != 0);
|
assert(expr.type != 0 || type != 0);
|
||||||
make_sure_types_are_compatible_for_assignment(node->pos, &expr, type);
|
make_sure_value_is_compatible_with_type(node->pos, &expr, type, EXPR_CAN_BE_NULL|TYPE_CAN_BE_NULL);
|
||||||
assert(expr.type);
|
assert(expr.type);
|
||||||
return expr;
|
return expr;
|
||||||
BREAK();
|
BREAK();
|
||||||
|
|||||||
2
types.h
2
types.h
@@ -19,10 +19,10 @@ enum Ast_Resolved_Type_Kind{
|
|||||||
TYPE_U8 ,
|
TYPE_U8 ,
|
||||||
TYPE_F32,
|
TYPE_F32,
|
||||||
TYPE_F64,
|
TYPE_F64,
|
||||||
|
TYPE_POINTER,
|
||||||
TYPE_BOOL, // LAST_NUMERIC
|
TYPE_BOOL, // LAST_NUMERIC
|
||||||
TYPE_STRING,
|
TYPE_STRING,
|
||||||
TYPE_VOID,
|
TYPE_VOID,
|
||||||
TYPE_POINTER,
|
|
||||||
TYPE_ARRAY,
|
TYPE_ARRAY,
|
||||||
TYPE_LAMBDA,
|
TYPE_LAMBDA,
|
||||||
TYPE_STRUCT,
|
TYPE_STRUCT,
|
||||||
|
|||||||
Reference in New Issue
Block a user