ox

The Ox programming language, compiler and tools (WIP)
Log | Files | Refs | README | LICENSE

commit 94c9ed18098ee36420987ef6fddf04b0d15ca9aa
parent 21c72769c79db271ce808cb4ddd87d6f863af369
Author: citbl <citbl@citbl.org>
Date:   Tue, 25 Nov 2025 17:20:08 +1000

add more types

Diffstat:
M.zed/debug.json | 2+-
Moxdesign.ox | 6+++---
Msrc/gen/gen.c | 79++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
Msrc/lexer.c | 9+++++++++
Msrc/parser/parser.c | 2++
Msrc/sem.c | 66++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
Msrc/types.h | 21++++++++++++++++++++-
Mtests/ex-call-args-same-names.ox | 4++--
Mtests/ex-call-args.ox | 4++--
Mtests/ex-call-many-args.ox | 7+++----
Mtests/ex-cond-adv1.ox | 2+-
Mtests/ex11.ox | 4++--
Mtests/ex12.ox | 2+-
Mtests/ex2.ox | 6+++---
14 files changed, 179 insertions(+), 35 deletions(-)

diff --git a/.zed/debug.json b/.zed/debug.json @@ -11,7 +11,7 @@ "cwd": "$ZED_WORKTREE_ROOT" }, "program": "$ZED_WORKTREE_ROOT/oxc", - "args": ["$ZED_WORKTREE_ROOT/tests/ex-closure-args.ox"], + "args": ["$ZED_WORKTREE_ROOT/tests/ex-call-many-args.ox"], "request": "launch", "adapter": "CodeLLDB" } diff --git a/oxdesign.ox b/oxdesign.ox @@ -17,7 +17,7 @@ arr<i32>[16] ages; // fixed slice of 16 vec<i32> bobs; // dynamic list set<str> names; // sets -type Person { +struct Person { i32 age, str name, } @@ -71,9 +71,9 @@ extend Person { } // lambda style main function -fn main => print("hello world"); +fn main() void => print("hello world"); -fn main(i32 argc, arr<str> argv) int = { +fn main(i32 argc, arr<str> argv) int { if argc != 0 { print("usage..."); return 0; diff --git a/src/gen/gen.c b/src/gen/gen.c @@ -10,10 +10,20 @@ #include <sys/param.h> static gcc_jit_type* type_int; -static gcc_jit_type* type_float; +static gcc_jit_type* type_i8; +static gcc_jit_type* type_i16; +static gcc_jit_type* type_i32; +static gcc_jit_type* type_i64; +static gcc_jit_type* type_i128; +static gcc_jit_type* type_u8; +static gcc_jit_type* type_u16; +static gcc_jit_type* type_u32; +static gcc_jit_type* type_u64; +static gcc_jit_type* type_u128; +static gcc_jit_type* type_f32; +static gcc_jit_type* type_f64; +static gcc_jit_type* type_f128; static gcc_jit_type* type_uint; -static gcc_jit_type* type_double; -static gcc_jit_type* type_long; static gcc_jit_type* type_void; static gcc_jit_type* type_cstr; static gcc_jit_type* type_char; @@ -99,10 +109,23 @@ gen_init(Scope* scope, const char* src, Node* node, bool quiet) /*0-3 for O3*/ 0); type_int = gcc_jit_context_get_type(ctx, GCC_JIT_TYPE_INT64_T); - type_float = gcc_jit_context_get_type(ctx, GCC_JIT_TYPE_BFLOAT16); + type_i8 = gcc_jit_context_get_type(ctx, GCC_JIT_TYPE_INT8_T); + type_i16 = gcc_jit_context_get_type(ctx, GCC_JIT_TYPE_INT16_T); + type_i32 = gcc_jit_context_get_type(ctx, GCC_JIT_TYPE_INT32_T); + type_i64 = gcc_jit_context_get_type(ctx, GCC_JIT_TYPE_INT64_T); + type_i128 = gcc_jit_context_get_type(ctx, GCC_JIT_TYPE_INT128_T); + + type_u8 = gcc_jit_context_get_type(ctx, GCC_JIT_TYPE_UINT8_T); + type_u16 = gcc_jit_context_get_type(ctx, GCC_JIT_TYPE_UINT16_T); + type_u32 = gcc_jit_context_get_type(ctx, GCC_JIT_TYPE_UINT32_T); + type_u64 = gcc_jit_context_get_type(ctx, GCC_JIT_TYPE_UINT64_T); + type_u128 = gcc_jit_context_get_type(ctx, GCC_JIT_TYPE_UINT128_T); + + type_f32 = gcc_jit_context_get_type(ctx, GCC_JIT_TYPE_FLOAT); + type_f64 = gcc_jit_context_get_type(ctx, GCC_JIT_TYPE_DOUBLE); + type_f128 = gcc_jit_context_get_type(ctx, GCC_JIT_TYPE_LONG_DOUBLE); + type_uint = gcc_jit_context_get_type(ctx, GCC_JIT_TYPE_UINT64_T); - type_double = gcc_jit_context_get_type(ctx, GCC_JIT_TYPE_DOUBLE); - type_long = gcc_jit_context_get_type(ctx, GCC_JIT_TYPE_LONG_LONG); type_char = gcc_jit_context_get_type(ctx, GCC_JIT_TYPE_UNSIGNED_CHAR); type_void = gcc_jit_context_get_type(ctx, GCC_JIT_TYPE_VOID); type_cstr = gcc_jit_context_get_type(ctx, GCC_JIT_TYPE_CONST_CHAR_PTR); @@ -222,7 +245,7 @@ handle_ident_call(Gen* gen, Node* node) static gcc_jit_rvalue* handle_expr(Gen*, Node*); static inline int -is_intlike(gcc_jit_context* ctx, gcc_jit_type* t) +is_intlike(gcc_jit_context* ctx, gcc_jit_type* t) // TODO support all new types { return t == gcc_jit_context_get_type(ctx, GCC_JIT_TYPE_INT) || t == gcc_jit_context_get_type(ctx, GCC_JIT_TYPE_UNSIGNED_INT) || t == gcc_jit_context_get_type(ctx, GCC_JIT_TYPE_SHORT) @@ -429,7 +452,7 @@ emit_literal_int(Gen* gen, Node* node) static gcc_jit_rvalue* emit_literal_float(Gen* gen, Node* node) { - return gcc_jit_context_new_rvalue_from_double(gen->ctx, type_double, node->data.number.value); + return gcc_jit_context_new_rvalue_from_double(gen->ctx, type_f32, node->data.number.value); } static void @@ -535,7 +558,7 @@ lower_builtin_print(Gen* gen, Node* node) gcc_jit_type* ty = gcc_jit_rvalue_get_type(arg); if (ty == type_int) { arg = gcc_jit_context_new_cast(gen->ctx, loc_from_node(gen, node), arg, type_cstr); - } else if (ty == type_double) { + } else if (ty == type_f32) { // TODO print() for other types // variadics already promote float→double; // double is } else if (ty == type_cstr) { @@ -691,10 +714,44 @@ ox_type_to_c_type(Gen* gen, Node* node) if (strcmp(type_name, "int") == 0) { return type_int; - } else if (strcmp(type_name, "string") == 0) { + + } else if (strcmp(type_name, "i8") == 0) { + return type_i8; + } else if (strcmp(type_name, "i16") == 0) { + return type_i16; + } else if (strcmp(type_name, "i32") == 0) { + return type_i32; + } else if (strcmp(type_name, "i64") == 0) { + return type_i64; + } else if (strcmp(type_name, "i128") == 0) { + return type_i128; + + } else if (strcmp(type_name, "u8") == 0) { + return type_u8; + } else if (strcmp(type_name, "u16") == 0) { + return type_u16; + } else if (strcmp(type_name, "u32") == 0) { + return type_u32; + } else if (strcmp(type_name, "u64") == 0) { + return type_u64; + } else if (strcmp(type_name, "u128") == 0) { + return type_u128; + + } else if (strcmp(type_name, "f32") == 0) { + return type_f32; + } else if (strcmp(type_name, "f64") == 0) { + return type_f64; + } else if (strcmp(type_name, "f128") == 0) { + return type_f128; + + } else if (strcmp(type_name, "str") == 0) { return type_cstr; } else if (strcmp(type_name, "float") == 0) { - return type_double; + return type_f32; + } else if (strcmp(type_name, "double") == 0) { + return type_f64; + } else if (strcmp(type_name, "longdouble") == 0) { + return type_f128; } else if (strcmp(type_name, "uint") == 0) { return type_uint; } else if (strcmp(type_name, "void") == 0) { diff --git a/src/lexer.c b/src/lexer.c @@ -89,6 +89,15 @@ make_ident(Lexer* lex, size_t pos, size_t line, size_t col) else if ((lex->pos - pos) == 5 && strncmp(lex->src + pos, "while", 5) == 0) type = TOKEN_WHILE; + else if ((lex->pos - pos) == 6 && strncmp(lex->src + pos, "struct", 6) == 0) + type = TOKEN_STRUCT; + else if ((lex->pos - pos) == 6 && strncmp(lex->src + pos, "extend", 6) == 0) + type = TOKEN_EXTEND; + + else if ((lex->pos - pos) == 2 && strncmp(lex->src + pos, "fx", 2) == 0) + type = TOKEN_FX; + else if ((lex->pos - pos) == 2 && strncmp(lex->src + pos, "fn", 2) == 0) + type = TOKEN_FN; // Check for keywords, or a Capitalised CustomType // -- @later do it in the parser, keep types as unprotected names // if (strncmp(lex->src + pos, "int", lex->pos - pos) == 0) diff --git a/src/parser/parser.c b/src/parser/parser.c @@ -1,3 +1,4 @@ + #include "../parser.h" #include "../utils.h" @@ -52,6 +53,7 @@ expect(Parser* par, TokenType type) Token tok = peek(par); if (tok.type != type) { const char* name = range_str(par->src, tok.start, tok.end, (char[IDENTSZ]) { 0 }); + printf("name: %s\n", name); panic("Expected %s, but got '%s' (%d) at %s:%zu:%zu", token_type_str(type), name, tok.type, par->filename, tok.line, tok.col); assert(tok.type == type); } diff --git a/src/sem.c b/src/sem.c @@ -21,7 +21,7 @@ scope_init(Node* node) .len = 0, .ch_cap = CALLOC_SZ, .ch_len = 0, - .depth = BASE_DEPTH, + .depth = BASE_DEPTH, .owner = node, .id = next_id++ }; @@ -97,10 +97,48 @@ scope_var(Scope* scope, Ast* ast, Node* node) type->type = SYMTYPE_FLOAT; } else if (strcmp(type_name, "int") == 0) { type->type = SYMTYPE_INT; - } else if (strcmp(type_name, "string") == 0) { - type->type = SYMTYPE_STRING; } else if (strcmp(type_name, "uint") == 0) { type->type = SYMTYPE_UINT; + + } else if (strcmp(type_name, "str") == 0) { + type->type = SYMTYPE_STR; + } else if (strcmp(type_name, "chr") == 0) { + type->type = SYMTYPE_CHR; + } else if (strcmp(type_name, "bool") == 0) { + type->type = SYMTYPE_BOOL; + + } else if (strcmp(type_name, "struct") == 0) { + type->type = SYMTYPE_STRUCT; + + } else if (strcmp(type_name, "i8") == 0) { + type->type = SYMTYPE_I8; + } else if (strcmp(type_name, "i16") == 0) { + type->type = SYMTYPE_I16; + } else if (strcmp(type_name, "i32") == 0) { + type->type = SYMTYPE_I32; + } else if (strcmp(type_name, "i64") == 0) { + type->type = SYMTYPE_I64; + } else if (strcmp(type_name, "i128") == 0) { + type->type = SYMTYPE_I128; + + } else if (strcmp(type_name, "u8") == 0) { + type->type = SYMTYPE_U8; + } else if (strcmp(type_name, "u16") == 0) { + type->type = SYMTYPE_U16; + } else if (strcmp(type_name, "u32") == 0) { + type->type = SYMTYPE_U32; + } else if (strcmp(type_name, "u64") == 0) { + type->type = SYMTYPE_U64; + } else if (strcmp(type_name, "u128") == 0) { + type->type = SYMTYPE_U128; + + } else if (strcmp(type_name, "f32") == 0) { + type->type = SYMTYPE_F32; + } else if (strcmp(type_name, "f64") == 0) { + type->type = SYMTYPE_F64; + } else if (strcmp(type_name, "f128") == 0) { + type->type = SYMTYPE_F128; + } else { if (type_name[0] >= 'A' && type_name[0] <= 'Z') { type->type = SYMTYPE_USER; @@ -190,9 +228,29 @@ type_kind_str(SymbolType t) static const char* type_strings[] = { [SYMTYPE_VOID] = "TYPE_VOID", [SYMTYPE_INT] = "TYPE_INT", + + [SYMTYPE_I8] = "TYPE_I8", + [SYMTYPE_I16] = "TYPE_I16", + [SYMTYPE_I32] = "TYPE_I32", + [SYMTYPE_I64] = "TYPE_I64", + [SYMTYPE_I128] = "TYPE_I128", [SYMTYPE_UINT] = "TYPE_UINT", + + [SYMTYPE_U8] = "TYPE_U8", + [SYMTYPE_U16] = "TYPE_U16", + [SYMTYPE_U32] = "TYPE_U32", + [SYMTYPE_U64] = "TYPE_U64", + [SYMTYPE_U128] = "TYPE_U128", + + [SYMTYPE_F32] = "TYPE_F32", + [SYMTYPE_F64] = "TYPE_F64", + [SYMTYPE_F128] = "TYPE_F128", [SYMTYPE_FLOAT] = "TYPE_FLOAT", - [SYMTYPE_STRING] = "TYPE_STRING", + + [SYMTYPE_STR] = "TYPE_STR", + [SYMTYPE_CHR] = "TYPE_CHR", + [SYMTYPE_BOOL] = "TYPE_BOOL", + [SYMTYPE_STRUCT] = "TYPE_STRUCT", [SYMTYPE_USER] = "TYPE_USER", [SYMTYPE_FUNC] = "TYPE_FUNC", [SYMTYPE_TODO] = "TYPE_TODO", diff --git a/src/types.h b/src/types.h @@ -16,6 +16,10 @@ typedef enum { TOKEN_SEMICOLON, TOKEN_PERCENT, TOKEN_COMMA, + TOKEN_STRUCT, + TOKEN_EXTEND, + TOKEN_FX, + TOKEN_FN, TOKEN_INT_LITERAL, TOKEN_FLOAT_LITERAL, TOKEN_STRING_LITERAL, @@ -202,9 +206,24 @@ typedef enum { // todo distinguish local/exported/param SYMTYPE_VOID = 108, SYMTYPE_INT, + SYMTYPE_I8, + SYMTYPE_I16, + SYMTYPE_I32, + SYMTYPE_I64, + SYMTYPE_I128, SYMTYPE_UINT, + SYMTYPE_U8, + SYMTYPE_U16, + SYMTYPE_U32, + SYMTYPE_U64, + SYMTYPE_U128, + SYMTYPE_F32, + SYMTYPE_F64, + SYMTYPE_F128, SYMTYPE_FLOAT, - SYMTYPE_STRING, + SYMTYPE_STR, + SYMTYPE_CHR, + SYMTYPE_BOOL, SYMTYPE_STRUCT, SYMTYPE_USER, SYMTYPE_ARRAY, diff --git a/tests/ex-call-args-same-names.ox b/tests/ex-call-args-same-names.ox @@ -1,9 +1,9 @@ -void func1(string message) { +void func1(str message) { print("message was:"); print(message); } -void func2(string message) { +void func2(str message) { print("another message:"); print(message); } diff --git a/tests/ex-call-args.ox b/tests/ex-call-args.ox @@ -1,4 +1,4 @@ -void callee_test(string message) { +void callee_test(str message) { print("message was:"); print(message); } @@ -8,7 +8,7 @@ void callee_test2(int age) { print(age); } -void callee_test3(string message2, int age2) { +void callee_test3(str message2, int age2) { print("summarized:"); print(message2); print(age2); diff --git a/tests/ex-call-many-args.ox b/tests/ex-call-many-args.ox @@ -1,11 +1,10 @@ -int integer(int a, int b, int c, int d, int e, int f, int g, int h, string words) { +int integer(int a, i64 b, i64 c, i64 d, int e, int f, int g, int h, str words) { print(words); return a * b + c * d + e + f - g * h; } - void main() { - int a = 5; - int d = 8; + i64 a = 5; + i64 d = 80000; print(integer(a, 12, 16, d, 4, 7, 10, 4, "this is a test")); } diff --git a/tests/ex-cond-adv1.ox b/tests/ex-cond-adv1.ox @@ -2,7 +2,7 @@ int main() { print("did it work?"); - string password = "123"; + str password = "123"; if (password == "1234") { print("it worked!"); return 0; diff --git a/tests/ex11.ox b/tests/ex11.ox @@ -1,7 +1,7 @@ // variable reassignment to ident after declarations void main() { - string harry = "Harry is Barry."; - string barry = harry; + str harry = "Harry is Barry."; + str barry = harry; print(barry); } diff --git a/tests/ex12.ox b/tests/ex12.ox @@ -1,7 +1,7 @@ // variable reassignment to literal after declaration void main() { - string jake = "before change"; + str jake = "before change"; jake = "expected result"; print(jake); } diff --git a/tests/ex2.ox b/tests/ex2.ox @@ -1,9 +1,9 @@ // test var decl and print void main() { - string steve = "His name is Steeeve"; - string harry = "His name is Harry"; - string jezza = "His name is Jezza"; + str steve = "His name is Steeeve"; + str harry = "His name is Harry"; + str jezza = "His name is Jezza"; int bob = 4; print(harry); }