- Adds '.onyx' to the end of the file name list
- Only searches in current directory for now
- [ ] Completely overhaul the type system
+ [X] Completely overhaul the type system
- Keep the builtins
- Add pointers
- Add structs
- [ ] Output 'drop' instruction for functions whose return value isn't used
+ [X] Output 'drop' instruction for functions whose return value isn't used
[ ] Devise and implement a simple set of implicit type casting rules.
- Numeric literals always type cast to whatever type is needed (very flexible).
- [ ] Strings should work as pointers to data.
+ [X] Strings should work as pointers to data.
- Literals should be placed in data section with pointers to the start.
- Should strings be null-terminated or a length at the start of the string?
+ [ ] Struct splatting in arguments and parameters
+
+ [X] UFC syntax for structs
+
+ [ ] Enum types
+
+ [ ] Procedures as arguments
+
[ ] Start work on evaluating compile time known values.
- An expression marked COMPTIME will be reduced to its value in the parse tree.
-
N :: 5
-Vec3 :: struct {
- x : f32;
- y : f32;
- z : f32;
-}
-
Foo :: struct {
v : Vec3;
i : i32;
return ^fooarr[i];
}
-proc #export "main3" {
- // foo := foo_make();
- // other_foo := foo_make();
- // other_foo.i = 1234;
-
- // foo.foo = other_foo;
- // print(foo.foo.i);
- foo1 := foo_make();
- foo1.v.y = 123.0f;
- print(foo1.v.y);
-
- foo := alloc(sizeof [N]Foo) as [N]Foo;
-
- for i: 1, 6 {
- foo[i - 1].v.x = (i + 3) as f32;
- foo[i - 1].v.y = (i + 4) as f32;
-
- foo[i - 1].i = i;
- foo[i - 1].l = (i * 10) as i64;
- foo[i - 1].f = (i * 100) as f32;
- foo[i - 1].d = (i * 1000) as f64;
-
- foo[i - 1].foo = foo as ^Foo;
- }
-
- print(foo[3].v.x); // 7
- print(foo[4].i); // 5
- print(foo[2].d); // 3000.0
- print(foo[3].f); // 400.0
- print(foo[0].l); // 10
-
- print(foo as i32);
- print((^(foo[3].l)) as i32); // 84
-
- print(foo[2].foo[4].foo[3].f); // 400.0
-
- foo_get(foo, 2).f = 1234.5f;
- print(foo[2].f);
-
- print(1000000000000);
- link_test();
-
- print(foo[3].v.x); // 7
- print(foo[4].i); // 5
- print(foo[2].d); // 3000.0
- print(foo[3].f); // 400.0
- print(foo[0].l); // 10
-}
-
Mut1 :: struct {
bar : i32;
other : Mut2;
y : i32;
}
+Vec3 :: struct {
+ x : i32;
+ y : i32;
+ z : i32;
+}
+
+v2magnitude :: proc (v: ^Vec2) -> f32 {
+ return sqrt_f32((v.x * v.x + v.y * v.y) as f32);
+}
+
+v3magnitude :: proc (v: ^Vec3) -> f32 {
+ return sqrt_f32((v.x * v.x + v.y * v.y + v.z * v.z) as f32);
+}
+
+magnitude :: proc #overloaded { v2magnitude, v3magnitude };
+
+minus :: proc (n: i32, k: i32) -> i32 {
+ return n - k;
+}
+
+foo :: proc (f: (i32, i32) -> i32) -> i32 {
+ return f(5, 6);
+}
+
+proc #export "main" {
+ v2 := alloc(sizeof Vec2) as ^Vec2;
+ v2.x = 5;
+ v2.y = 12;
+ print(v2.magnitude());
+
+ v3 := alloc(sizeof Vec3) as ^Vec3;
+ v3.x = 1;
+ v3.y = 1;
+ v3.z = 1;
+ print(v3.magnitude());
+
+ print((1).minus(2));
+}
+
SOA :: struct {
positions : [10] Vec2;
velocities : [10] Vec2;
v.y = 5678;
}
-soa_test :: proc #export "main" {
+soa_test :: proc #export "main9" {
// print(sizeof SOA); // 240
vec2_set(^(soa.positions[6]));
vec2_set(soa.things[2]);
+ print((^(soa.positions[6])).v2magnitude());
+
print(soa.positions[5].y);
print(soa.velocities[2].x);
print(soa.things[2].x);
m_arr[y][x] = x + y * 5;
}
}
-
+
for i: 0, 25 print((m_arr as [] i32)[i]);
}
\ No newline at end of file
}
static void print_detailed_message(Message* msg, bh_file_contents* fc) {
- bh_printf("(%s:%l:%l) %s\n", msg->pos.filename, msg->pos.line, msg->pos.column, msg->text);
+ bh_printf("(%s:%l,%l) %s\n", msg->pos.filename, msg->pos.line, msg->pos.column, msg->text);
i32 linelength = 0;
char* walker = msg->pos.line_start;
while (*walker != '\n') linelength++, walker++;
- bh_printf("| %b\n", msg->pos.line_start, linelength);
+ i32 numlen = bh_printf(" %d |", msg->pos.line);
+ bh_printf("%b\n", msg->pos.line_start, linelength);
- char* pointer_str = bh_alloc_array(global_scratch_allocator, char, linelength);
- memset(pointer_str, ' ', linelength);
- memset(pointer_str + msg->pos.column, '~', msg->pos.length - 1);
- pointer_str[msg->pos.column - 1] = '^';
- pointer_str[msg->pos.column + msg->pos.length - 1] = 0;
+ char* pointer_str = bh_alloc_array(global_scratch_allocator, char, linelength + numlen);
+ memset(pointer_str, ' ', linelength + numlen);
+ memset(pointer_str + msg->pos.column + numlen, '~', msg->pos.length - 1);
+ pointer_str[msg->pos.column + numlen - 1] = '^';
+ pointer_str[msg->pos.column + numlen + msg->pos.length - 1] = 0;
- bh_printf("| %s\n", pointer_str);
+ bh_printf("%s\n", pointer_str);
}
void onyx_message_print() {
print_detailed_message(msg, fc);
} else {
- bh_printf("(%l:%l) %s\n", msg->pos.line, msg->pos.column, msg->text);
+ bh_printf("(%l,%l) %s\n", msg->pos.line, msg->pos.column, msg->text);
}
msg = msg->next;
}
AstTyped* sym_node = make_node(AstTyped, Ast_Kind_Symbol);
sym_node->token = sym_token;
- if (parser->curr->type != '(') {
- retval = sym_node;
- break;
- }
-
- // NOTE: Function call
- AstCall* call_node = make_node(AstCall, Ast_Kind_Call);
- call_node->token = expect_token(parser, '(');
- call_node->callee = (AstNode *) sym_node;
- call_node->arg_count = 0;
-
- AstArgument** prev = &call_node->arguments;
- AstArgument* curr = NULL;
- while (parser->curr->type != ')') {
- curr = make_node(AstArgument, Ast_Kind_Argument);
- curr->token = parser->curr;
- curr->value = parse_expression(parser);
-
- if (curr != NULL && curr->kind != Ast_Kind_Error) {
- *prev = curr;
- prev = (AstArgument **) &curr->next;
-
- call_node->arg_count++;
- }
-
- if (parser->curr->type == ')')
- break;
-
- if (parser->curr->type != ',') {
- onyx_message_add(Msg_Type_Expected_Token,
- parser->curr->pos,
- token_name(','),
- token_name(parser->curr->type));
- return (AstTyped *) &error_node;
- }
-
- consume_token(parser);
- }
- consume_token(parser);
-
- retval = (AstTyped *) call_node;
+ retval = sym_node;
break;
}
}
while (parser->curr->type == '[' || parser->curr->type == Token_Type_Keyword_Cast
- || parser->curr->type == '.') {
+ || parser->curr->type == '.' || parser->curr->type == '(') {
switch ((u16) parser->curr->type) {
case '[': {
retval = (AstTyped *) cast_node;
break;
}
+
+ case '(': {
+ AstCall* call_node = make_node(AstCall, Ast_Kind_Call);
+ call_node->token = expect_token(parser, '(');
+ call_node->callee = (AstNode *) retval;
+ call_node->arg_count = 0;
+
+ AstArgument** prev = &call_node->arguments;
+ AstArgument* curr = NULL;
+ while (parser->curr->type != ')') {
+ curr = make_node(AstArgument, Ast_Kind_Argument);
+ curr->token = parser->curr;
+ curr->value = parse_expression(parser);
+
+ if (curr != NULL && curr->kind != Ast_Kind_Error) {
+ *prev = curr;
+ prev = (AstArgument **) &curr->next;
+
+ call_node->arg_count++;
+ }
+
+ if (parser->curr->type == ')')
+ break;
+
+ if (parser->curr->type != ',') {
+ onyx_message_add(Msg_Type_Expected_Token,
+ parser->curr->pos,
+ token_name(','),
+ token_name(parser->curr->type));
+ return (AstTyped *) &error_node;
+ }
+
+ consume_token(parser);
+ }
+ consume_token(parser);
+
+ retval = (AstTyped *) call_node;
+ break;
+ }
}
}
#define BH_DEBUG
#include "onyxsempass.h"
+#include "onyxparser.h"
AstBasicType basic_type_void = { { Ast_Kind_Basic_Type, 0, NULL, "void" }, &basic_types[Basic_Kind_Void] };
AstBasicType basic_type_bool = { { Ast_Kind_Basic_Type, 0, NULL, "bool" }, &basic_types[Basic_Kind_Bool] };
static AstType* symres_type(AstType* type);
static void symres_local(AstLocal** local);
-static void symres_call(AstCall* call);
+static void symres_call(AstCall** pcall);
static void symres_size_of(AstSizeOf* so);
static void symres_expression(AstTyped** expr);
static void symres_return(AstReturn* ret);
symbol_introduce((*local)->token, (AstNode *) *local);
}
-static void symres_call(AstCall* call) {
+static void symres_call(AstCall** pcall) {
+ AstCall* call = *pcall;
+
+ if (call->callee->kind == Ast_Kind_Field_Access) {
+ AstFieldAccess* fa = (AstFieldAccess *) call->callee;
+
+ AstTyped* symbol = onyx_ast_node_new(semstate.node_allocator, sizeof(AstTyped), Ast_Kind_Symbol);
+ symbol->token = fa->token;
+
+ AstArgument* implicit_arg = onyx_ast_node_new(semstate.node_allocator, sizeof(AstArgument), Ast_Kind_Argument);
+ implicit_arg->value = fa->expr;
+ implicit_arg->token = fa->expr->token;
+ implicit_arg->next = (AstNode *) call->arguments;
+
+ (*pcall)->callee = (AstNode *) symbol;
+ (*pcall)->arguments = implicit_arg;
+ (*pcall)->arg_count++;
+
+ call = *pcall;
+ }
+
AstNode* callee = symbol_resolve(call->callee->token);
if (callee)
call->callee = callee;
break;
case Ast_Kind_Unary_Op: symres_unaryop((AstUnaryOp **) expr); break;
- case Ast_Kind_Call: symres_call((AstCall *) *expr); break;
+ case Ast_Kind_Call: symres_call((AstCall **) expr); break;
case Ast_Kind_Block: symres_block((AstBlock *) *expr); break;
case Ast_Kind_Symbol:
case Ast_Kind_If: symres_if((AstIf *) stmt); return 0;
case Ast_Kind_While: symres_while((AstWhile *) stmt); return 0;
case Ast_Kind_For: symres_for((AstFor *) stmt); return 0;
- case Ast_Kind_Call: symres_call((AstCall *) stmt); return 0;
+ case Ast_Kind_Call: symres_call((AstCall **) &stmt); return 0;
case Ast_Kind_Argument: symres_expression((AstTyped **) &((AstArgument *)stmt)->value); return 0;
case Ast_Kind_Block: symres_block((AstBlock *) stmt); return 0;