Add string accessors, working towards first program
This commit is contained in:
25
ccodegen.cpp
25
ccodegen.cpp
@@ -405,7 +405,30 @@ compile_string(String filecontent, String filename = "default_name"_s){
|
||||
|
||||
|
||||
gen(R"==(
|
||||
// Generated
|
||||
|
||||
#include <stdint.h>
|
||||
typedef int8_t S8;
|
||||
typedef int16_t S16;
|
||||
typedef int32_t S32;
|
||||
typedef int64_t S64;
|
||||
typedef uint8_t U8;
|
||||
typedef uint16_t U16;
|
||||
typedef uint32_t U32;
|
||||
typedef uint64_t U64;
|
||||
typedef S8 B8;
|
||||
typedef S16 B16;
|
||||
typedef S32 B32;
|
||||
typedef S64 B64;
|
||||
typedef U64 SizeU;
|
||||
typedef S64 SizeI;
|
||||
typedef float F32;
|
||||
typedef double F64;
|
||||
|
||||
struct String{
|
||||
U8 *str;
|
||||
S64 len;
|
||||
};
|
||||
|
||||
)==");
|
||||
|
||||
F64 resolve_begin = os_time();
|
||||
|
||||
16
lexer.kl
16
lexer.kl
@@ -1,16 +0,0 @@
|
||||
/*
|
||||
Lex_Stream :: struct
|
||||
stream: String
|
||||
offset: Int
|
||||
|
||||
lexc :: (s: *Lex_Stream): String // @todo U8 U S
|
||||
return s.stream + s.offset // s.offset @todo Actual string support
|
||||
|
||||
main :: ()
|
||||
string_to_lex := "Identifier 2425525 Not_Number"
|
||||
s := Lex_Stream(stream=string_to_lex)
|
||||
|
||||
for inf:=0, inf, inf // @todo for
|
||||
pass
|
||||
|
||||
*/
|
||||
28
main.cpp
28
main.cpp
@@ -32,23 +32,26 @@ For now I don't thing it should be overloadable.
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
@todo
|
||||
[ ] - Operators: Bit negation, Not
|
||||
[ ] - Converting from U64 token to S64 Atom introduces unnanounced error (negates) - probably need big int
|
||||
[ ] - Compiling and running a program
|
||||
[ ] - Passing down program to compile through command line
|
||||
[ ] - More for loop variations
|
||||
[ ] - 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
|
||||
[ ] - Switch
|
||||
[ ] - More basic types
|
||||
|
||||
[ ] - Comma notation when declaring variables thing1, thing2: S32
|
||||
[ ] - Array of inferred size
|
||||
[ ] - Add single line lambda expressions
|
||||
[ ] - Ternary operator
|
||||
|
||||
[ ] - Field access rewrite
|
||||
[ ] - Constants embeded in structs should be able to refer to other constants in that namespace without prefix
|
||||
[ ] - Converting from U64 token to S64 Atom introduces unnanounced error (negates) - probably need
|
||||
[ ] - Order independent constants in structs
|
||||
[ ] - Can you even have recursive lambdas in structs, other recursive stuff
|
||||
[ ] - Fix recursive lambdas in structs
|
||||
[ ] - Fixing access to functions/structs, in C we cant have functons inside of structs / functions so we need to rewrite the tree
|
||||
|
||||
[ ] - Casting to basic types by call S64(x)
|
||||
[ ] - Default values in structs??? Should compound stmts bring values from default values?? Maybe not? Whats the alternative
|
||||
[ ] - Type aliases :: should probably be strictly typed, but assigning constant values should work
|
||||
|
||||
@ideas
|
||||
@@ -59,16 +62,19 @@ For now I don't thing it should be overloadable.
|
||||
@donzo
|
||||
[x] - Test new operators, add constant eval for them
|
||||
[x] - lvalue, rvalue concept so we cant assign value to some arbitrary weird expression
|
||||
[x] - More basic types
|
||||
[x] - Add basic support for floats
|
||||
[x] - Add basic setup for new type system
|
||||
[x] - Access through struct names to constants Arena.CONSTANT
|
||||
[x] - Enums
|
||||
[x] - Initial for loop
|
||||
[x] - Enum . access to values
|
||||
[x] - Infinite for loop
|
||||
[x] - in new typesystem: Fix calls, fix all example programs
|
||||
[x] - Fix arithmetic operations in new type system
|
||||
[x] - Init statements, different kinds [+=] [-=] etc.
|
||||
[x] - Struct calls
|
||||
[x] - Operators: Bit negation, Not
|
||||
[x] - Default values in calls
|
||||
[x] - Resolving calls with default values
|
||||
[x] - Pass statement
|
||||
@@ -119,11 +125,11 @@ int main(){
|
||||
result = compile_file("new_types.kl"_s);
|
||||
printf("%s", result.str);
|
||||
|
||||
// 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("program.kl"_s);
|
||||
FILE *f = fopen("program.c", "w");
|
||||
assert(f);
|
||||
fprintf(f, "%.*s", (int)result.len, result.str);
|
||||
fclose(f);
|
||||
|
||||
__debugbreak();
|
||||
}
|
||||
|
||||
@@ -193,11 +193,15 @@ parse_block(){
|
||||
}
|
||||
|
||||
else if(token_match_keyword(keyword_for)){
|
||||
Ast_Expr *expr_first = parse_expr();
|
||||
Ast_Expr *init = parse_init_stmt(expr_first);
|
||||
|
||||
Ast_Expr *init = 0;
|
||||
Ast_Expr *cond = 0;
|
||||
Ast_Expr *iter = 0;
|
||||
|
||||
if(!token_is(OPEN_SCOPE)){
|
||||
Ast_Expr *expr_first = parse_expr();
|
||||
init = parse_init_stmt(expr_first);
|
||||
|
||||
|
||||
if(token_match(TK_Comma)){
|
||||
cond = parse_expr();
|
||||
if(token_match(TK_Comma)){
|
||||
@@ -205,6 +209,7 @@ parse_block(){
|
||||
iter = parse_init_stmt(iter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ast_Block *for_block = parse_block();
|
||||
stmts.add(ast_for(token, init, cond, iter, for_block));
|
||||
@@ -345,7 +350,7 @@ binding_power(Binding binding, Token_Kind kind){
|
||||
case TK_Mod:
|
||||
return {17,18};
|
||||
case TK_Dot:
|
||||
return {20,19};
|
||||
return {24,23};
|
||||
default: return {};
|
||||
}
|
||||
Postfix: switch(kind){
|
||||
|
||||
@@ -47,11 +47,11 @@ basic_type_assignment :: ()
|
||||
float_var := float_val
|
||||
|
||||
|
||||
|
||||
compounds :: ()
|
||||
custom_data := Custom_Data(thing = 23)
|
||||
|
||||
|
||||
Custom_Data :: struct
|
||||
thing: S32
|
||||
|
||||
// compounds :: ()
|
||||
// custom_data := Custom_Data(23)
|
||||
// constant_proc :: ()
|
||||
// constant_proc()
|
||||
|
||||
38
program.c
38
program.c
@@ -1,6 +1,36 @@
|
||||
|
||||
//-------------------------------
|
||||
#define NULL_POINTER 0
|
||||
#define NULL_LAMBDA 0
|
||||
//-------------------------------
|
||||
|
||||
#include <stdint.h>
|
||||
typedef int8_t S8;
|
||||
typedef int16_t S16;
|
||||
typedef int32_t S32;
|
||||
typedef int64_t S64;
|
||||
typedef uint8_t U8;
|
||||
typedef uint16_t U16;
|
||||
typedef uint32_t U32;
|
||||
typedef uint64_t U64;
|
||||
typedef S8 B8;
|
||||
typedef S16 B16;
|
||||
typedef S32 B32;
|
||||
typedef S64 B64;
|
||||
typedef U64 SizeU;
|
||||
typedef S64 SizeI;
|
||||
typedef float F32;
|
||||
typedef double F64;
|
||||
|
||||
struct String{
|
||||
U8 *str;
|
||||
S64 len;
|
||||
};
|
||||
|
||||
|
||||
struct Lex_Stream{
|
||||
U8 *stream;
|
||||
U8 *end;
|
||||
};
|
||||
static Void main(){
|
||||
String string_to_lex = LIT("Identifier 2425525 Not_Number");
|
||||
for(S64 i = 0;(i<string_to_lex.len);(i+=1)){
|
||||
(string_to_lex.str[0]=64);
|
||||
}
|
||||
}
|
||||
11
program.kl
Normal file
11
program.kl
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
Lex_Stream :: struct
|
||||
stream: *U8
|
||||
end : *U8
|
||||
|
||||
main :: ()
|
||||
string_to_lex := "Identifier 2425525 Not_Number"
|
||||
|
||||
|
||||
for i := 0, i < string_to_lex.len, i+=1
|
||||
string_to_lex.str[0] = 64
|
||||
@@ -278,7 +278,7 @@ function void
|
||||
try_untyping(Operand *op){
|
||||
if(!op) return;
|
||||
if(is_untyped(op->type)){
|
||||
if(op->type->kind == TYPE_UNTYPED_INT) op->type = type_int;
|
||||
if(op->type->kind == TYPE_UNTYPED_INT) op->type = type_s64;
|
||||
else if(op->type->kind == TYPE_UNTYPED_BOOL) op->type = type_bool;
|
||||
else if(op->type->kind == TYPE_UNTYPED_STRING) op->type = type_string;
|
||||
else if(op->type->kind == TYPE_UNTYPED_FLOAT) op->type = type_f64;
|
||||
@@ -394,11 +394,6 @@ resolve_stmt(Ast *ast, Ast_Resolved_Type *ret){
|
||||
BREAK();
|
||||
}
|
||||
|
||||
CASE(BINARY, Binary){
|
||||
resolve_expr(node);
|
||||
BREAK();
|
||||
}
|
||||
|
||||
CASE(PASS, Pass){
|
||||
unused(node);
|
||||
BREAK();
|
||||
@@ -422,7 +417,12 @@ resolve_stmt(Ast *ast, Ast_Resolved_Type *ret){
|
||||
BREAK();
|
||||
}
|
||||
|
||||
invalid_default_case;
|
||||
default:{
|
||||
if(is_flag_set(ast->flags, AST_EXPR)){
|
||||
resolve_expr((Ast_Expr *)ast);
|
||||
}
|
||||
else invalid_codepath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -486,6 +486,19 @@ resolve_lambda(Ast_Lambda *lambda, Sym *sym = 0){
|
||||
return result;
|
||||
}
|
||||
|
||||
function Operand
|
||||
field_access_string(Ast_Expr *right){
|
||||
if(right->kind == AST_BINARY) invalid_codepath; // @todo entire field access needs a rework
|
||||
assert(right->kind == AST_IDENT);
|
||||
|
||||
auto a = (Ast_Atom *)right;
|
||||
if(a->intern_val == pctx->intern("len"_s)){
|
||||
return operand_lvalue(type_s64);
|
||||
} else if(a->intern_val == pctx->intern("str"_s)){
|
||||
return operand_lvalue(type_pointer(type_u8));
|
||||
} else invalid_return;
|
||||
}
|
||||
|
||||
function Operand
|
||||
resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_resolve){
|
||||
if(!ast) return {}; // @todo: add option for better error prevention
|
||||
@@ -533,7 +546,7 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res
|
||||
CASE(INDEX, Index){
|
||||
Operand left = resolve_expr(node->expr);
|
||||
Operand index = resolve_expr(node->index);
|
||||
if(left.type->kind != TYPE_ARRAY) parsing_error(node->pos, "Indexing variable that is not an array, it's of type %s instead", docname(left.type));
|
||||
if(left.type->kind != TYPE_ARRAY && left.type->kind != TYPE_POINTER) parsing_error(node->pos, "Indexing variable that is not an [Array] or [Pointer], it's of type %s instead", docname(left.type));
|
||||
if(!is_int(index.type)) type_error(node->pos, type_int, index.type,"Trying to index the array with invalid type, expected int");
|
||||
return operand_lvalue(left.type->arr.base);
|
||||
BREAK();
|
||||
@@ -695,10 +708,7 @@ 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 {}; }
|
||||
}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);
|
||||
if(!is_numeric(op.type)) parsing_error(node->pos, "Unary [%s] cant be applied to value of type %s", token_kind_string(node->op).str, docname(op.type));
|
||||
if(op.is_const){
|
||||
@@ -735,7 +745,8 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res
|
||||
Operand left = resolve_expr(node->left);
|
||||
if(!left.is_lvalue) parsing_error(node->pos, "Assigning to rvalue");
|
||||
Operand right = resolve_expr(node->right);
|
||||
try_untyping(&right);
|
||||
|
||||
right.value = convert_untyped(node->pos, right.value, left.type);
|
||||
if(left.type != right.type) parsing_error(node->pos, "Can't assign value when left is %s and right is %s", docname(left.type), docname(right.type));
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -754,9 +765,14 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res
|
||||
}
|
||||
// @copy_paste
|
||||
if(is_pointer(type)) type = type->base;
|
||||
|
||||
sym_var({}, resolved_ident.type, node->left);
|
||||
if(is_string(type) && !required_to_be_const){
|
||||
result = field_access_string(node->right);
|
||||
}
|
||||
else{
|
||||
type_complete(type);
|
||||
if(!(is_struct(type) || is_enum(type))) parsing_error(node->pos, "Trying to access inside a value that is not a struct or enum");
|
||||
sym_var({}, resolved_ident.type, node->left);
|
||||
|
||||
// This happens only on binary nodes which further chain with dots and require lookups
|
||||
// This part cant happen on enums
|
||||
@@ -818,6 +834,7 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res
|
||||
invalid_codepath;
|
||||
}
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -881,7 +898,7 @@ resolve_const(Ast_Expr *ast, Sym *sym){
|
||||
value = op.int_val + 1;
|
||||
}
|
||||
else{
|
||||
op.type = type_int;
|
||||
op.type = type_s64;
|
||||
op.int_val = value++;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user