mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-13 06:41:26 -07:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e86c990b75 |
+8
-4
@@ -72,6 +72,12 @@ syntax :: proc() {
|
|||||||
// `odin build_dll demo.odin`
|
// `odin build_dll demo.odin`
|
||||||
|
|
||||||
|
|
||||||
|
// New vector syntax
|
||||||
|
v: [vector 3]f32;
|
||||||
|
v[0] = 123;
|
||||||
|
v.x = 123; // valid for all vectors with count 1 to 4
|
||||||
|
|
||||||
|
|
||||||
// Next part
|
// Next part
|
||||||
prefixes();
|
prefixes();
|
||||||
}
|
}
|
||||||
@@ -189,14 +195,14 @@ loops :: proc() {
|
|||||||
for i in 0..<123 { // 123 exclusive
|
for i in 0..<123 { // 123 exclusive
|
||||||
}
|
}
|
||||||
|
|
||||||
for i in 0..122 { // 122 inclusive
|
for i in 0...122 { // 122 inclusive
|
||||||
}
|
}
|
||||||
|
|
||||||
for val, idx in 12..<16 {
|
for val, idx in 12..<16 {
|
||||||
fmt.println(val, idx);
|
fmt.println(val, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
primes := [..]int{2, 3, 5, 7, 11, 13, 17, 19};
|
primes := [...]int{2, 3, 5, 7, 11, 13, 17, 19};
|
||||||
|
|
||||||
for p in primes {
|
for p in primes {
|
||||||
fmt.println(p);
|
fmt.println(p);
|
||||||
@@ -224,8 +230,6 @@ loops :: proc() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
procedure_overloading();
|
procedure_overloading();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-2
@@ -398,8 +398,7 @@ run :: proc(user_init, user_step: proc(c: ^Core)) {
|
|||||||
ShowWindow(win32_window, SW_SHOW);
|
ShowWindow(win32_window, SW_SHOW);
|
||||||
|
|
||||||
window_buffer := new_slice(u32, CANVAS_WIDTH * CANVAS_HEIGHT);
|
window_buffer := new_slice(u32, CANVAS_WIDTH * CANVAS_HEIGHT);
|
||||||
assert(window_buffer.data != nil);
|
defer free(window_buffer);
|
||||||
defer free(window_buffer.data);
|
|
||||||
|
|
||||||
|
|
||||||
for i := 0; i < window_buffer.count; i += 1 {
|
for i := 0; i < window_buffer.count; i += 1 {
|
||||||
|
|||||||
+1
-1
@@ -164,7 +164,7 @@ alloc_align :: proc(size, alignment: int) -> rawptr #inline {
|
|||||||
return a.procedure(a.data, Allocator_Mode.ALLOC, size, alignment, nil, 0, 0);
|
return a.procedure(a.data, Allocator_Mode.ALLOC, size, alignment, nil, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
free :: proc(ptr: rawptr) #inline {
|
free_ptr :: proc(ptr: rawptr) #inline {
|
||||||
__check_context();
|
__check_context();
|
||||||
a := context.allocator;
|
a := context.allocator;
|
||||||
if ptr != nil {
|
if ptr != nil {
|
||||||
|
|||||||
+15
-15
@@ -58,38 +58,38 @@ Fmt_Info :: struct {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
fprint :: proc(fd: os.Handle, args: ..any) -> int {
|
fprint :: proc(fd: os.Handle, args: ...any) -> int {
|
||||||
data: [DEFAULT_BUFFER_SIZE]byte;
|
data: [DEFAULT_BUFFER_SIZE]byte;
|
||||||
buf := Buffer{data[:], 0};
|
buf := Buffer{data[:], 0};
|
||||||
bprint(^buf, ..args);
|
bprint(^buf, ...args);
|
||||||
os.write(fd, buf.data[:buf.length]);
|
os.write(fd, buf.data[:buf.length]);
|
||||||
return buf.length;
|
return buf.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintln :: proc(fd: os.Handle, args: ..any) -> int {
|
fprintln :: proc(fd: os.Handle, args: ...any) -> int {
|
||||||
data: [DEFAULT_BUFFER_SIZE]byte;
|
data: [DEFAULT_BUFFER_SIZE]byte;
|
||||||
buf := Buffer{data[:], 0};
|
buf := Buffer{data[:], 0};
|
||||||
bprintln(^buf, ..args);
|
bprintln(^buf, ...args);
|
||||||
os.write(fd, buf.data[:buf.length]);
|
os.write(fd, buf.data[:buf.length]);
|
||||||
return buf.length;
|
return buf.length;
|
||||||
}
|
}
|
||||||
fprintf :: proc(fd: os.Handle, fmt: string, args: ..any) -> int {
|
fprintf :: proc(fd: os.Handle, fmt: string, args: ...any) -> int {
|
||||||
data: [DEFAULT_BUFFER_SIZE]byte;
|
data: [DEFAULT_BUFFER_SIZE]byte;
|
||||||
buf := Buffer{data[:], 0};
|
buf := Buffer{data[:], 0};
|
||||||
bprintf(^buf, fmt, ..args);
|
bprintf(^buf, fmt, ...args);
|
||||||
os.write(fd, buf.data[:buf.length]);
|
os.write(fd, buf.data[:buf.length]);
|
||||||
return buf.length;
|
return buf.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
print :: proc(args: ..any) -> int {
|
print :: proc(args: ...any) -> int {
|
||||||
return fprint(os.stdout, ..args);
|
return fprint(os.stdout, ...args);
|
||||||
}
|
}
|
||||||
println :: proc(args: ..any) -> int {
|
println :: proc(args: ...any) -> int {
|
||||||
return fprintln(os.stdout, ..args);
|
return fprintln(os.stdout, ...args);
|
||||||
}
|
}
|
||||||
printf :: proc(fmt: string, args: ..any) -> int {
|
printf :: proc(fmt: string, args: ...any) -> int {
|
||||||
return fprintf(os.stdout, fmt, ..args);
|
return fprintf(os.stdout, fmt, ...args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -225,7 +225,7 @@ buffer_write_type :: proc(buf: ^Buffer, ti: ^Type_Info) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bprint :: proc(buf: ^Buffer, args: ..any) -> int {
|
bprint :: proc(buf: ^Buffer, args: ...any) -> int {
|
||||||
fi: Fmt_Info;
|
fi: Fmt_Info;
|
||||||
fi.buf = buf;
|
fi.buf = buf;
|
||||||
|
|
||||||
@@ -241,7 +241,7 @@ bprint :: proc(buf: ^Buffer, args: ..any) -> int {
|
|||||||
return buf.length;
|
return buf.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
bprintln :: proc(buf: ^Buffer, args: ..any) -> int {
|
bprintln :: proc(buf: ^Buffer, args: ...any) -> int {
|
||||||
fi: Fmt_Info;
|
fi: Fmt_Info;
|
||||||
fi.buf = buf;
|
fi.buf = buf;
|
||||||
|
|
||||||
@@ -888,7 +888,7 @@ fmt_arg :: proc(fi: ^Fmt_Info, arg: any, verb: rune) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bprintf :: proc(b: ^Buffer, fmt: string, args: ..any) -> int {
|
bprintf :: proc(b: ^Buffer, fmt: string, args: ...any) -> int {
|
||||||
fi := Fmt_Info{};
|
fi := Fmt_Info{};
|
||||||
end := fmt.count;
|
end := fmt.count;
|
||||||
arg_index := 0;
|
arg_index := 0;
|
||||||
|
|||||||
+2
-2
@@ -123,8 +123,8 @@ init_arena_from_context :: proc(using a: ^Arena, size: int) {
|
|||||||
free_arena :: proc(using a: ^Arena) {
|
free_arena :: proc(using a: ^Arena) {
|
||||||
if backing.procedure != nil {
|
if backing.procedure != nil {
|
||||||
push_allocator backing {
|
push_allocator backing {
|
||||||
free(memory.data);
|
free(memory);
|
||||||
memory = memory[0:0];
|
memory = nil;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -235,7 +235,7 @@ read_entire_file :: proc(name: string) -> ([]byte, bool) {
|
|||||||
|
|
||||||
win32.ReadFile(cast(win32.HANDLE)fd, ^data[total_read], to_read, ^single_read_length, nil);
|
win32.ReadFile(cast(win32.HANDLE)fd, ^data[total_read], to_read, ^single_read_length, nil);
|
||||||
if single_read_length <= 0 {
|
if single_read_length <= 0 {
|
||||||
free(data.data);
|
free(data);
|
||||||
return nil, false;
|
return nil, false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+28
-6
@@ -1519,12 +1519,7 @@ void check_unary_expr(Checker *c, Operand *o, Token op, AstNode *node) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_value =
|
if (!is_operand_value(*o) || is_type_untyped(t)) {
|
||||||
o->mode == Addressing_Variable ||
|
|
||||||
o->mode == Addressing_Value ||
|
|
||||||
o->mode == Addressing_Constant;
|
|
||||||
|
|
||||||
if (!is_value || is_type_untyped(t)) {
|
|
||||||
if (ast_node_expect(node, AstNode_UnaryExpr)) {
|
if (ast_node_expect(node, AstNode_UnaryExpr)) {
|
||||||
ast_node(ue, UnaryExpr, node);
|
ast_node(ue, UnaryExpr, node);
|
||||||
gbString str = expr_to_string(ue->expr);
|
gbString str = expr_to_string(ue->expr);
|
||||||
@@ -2536,6 +2531,8 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
|
|||||||
// TODO(bill): This is the rule I need?
|
// TODO(bill): This is the rule I need?
|
||||||
if (sel.indirect || operand->mode != Addressing_Value) {
|
if (sel.indirect || operand->mode != Addressing_Value) {
|
||||||
operand->mode = Addressing_Variable;
|
operand->mode = Addressing_Variable;
|
||||||
|
} else {
|
||||||
|
operand->mode = Addressing_Value;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Entity_TypeName:
|
case Entity_TypeName:
|
||||||
@@ -2645,6 +2642,31 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
|||||||
operand->type = make_type_slice(c->allocator, type);
|
operand->type = make_type_slice(c->allocator, type);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case BuiltinProc_free: {
|
||||||
|
// free :: proc(^Type)
|
||||||
|
// free :: proc([]Type)
|
||||||
|
// free :: proc(string)
|
||||||
|
Type *type = operand->type;
|
||||||
|
bool ok = false;
|
||||||
|
if (is_type_pointer(type)) {
|
||||||
|
ok = true;
|
||||||
|
} else if (is_type_slice(type)) {
|
||||||
|
ok = true;
|
||||||
|
} else if (is_type_string(type)) {
|
||||||
|
ok = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ok) {
|
||||||
|
gbString type_str = type_to_string(type);
|
||||||
|
error_node(operand->expr, "You can only free pointers, slices, and strings, got `%s`", type_str);
|
||||||
|
gb_string_free(type_str);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
operand->mode = Addressing_NoValue;
|
||||||
|
} break;
|
||||||
|
|
||||||
case BuiltinProc_size_of: {
|
case BuiltinProc_size_of: {
|
||||||
// size_of :: proc(Type) -> untyped int
|
// size_of :: proc(Type) -> untyped int
|
||||||
Type *type = check_type(c, ce->args.e[0]);
|
Type *type = check_type(c, ce->args.e[0]);
|
||||||
|
|||||||
+5
-3
@@ -5,8 +5,8 @@ typedef enum AddressingMode {
|
|||||||
Addressing_Invalid,
|
Addressing_Invalid,
|
||||||
|
|
||||||
Addressing_NoValue,
|
Addressing_NoValue,
|
||||||
Addressing_Value, // R-value
|
Addressing_Value,
|
||||||
Addressing_Variable, // L-value
|
Addressing_Variable,
|
||||||
Addressing_Constant,
|
Addressing_Constant,
|
||||||
Addressing_Type,
|
Addressing_Type,
|
||||||
Addressing_Builtin,
|
Addressing_Builtin,
|
||||||
@@ -123,6 +123,7 @@ typedef enum BuiltinProcId {
|
|||||||
|
|
||||||
BuiltinProc_new,
|
BuiltinProc_new,
|
||||||
BuiltinProc_new_slice,
|
BuiltinProc_new_slice,
|
||||||
|
BuiltinProc_free,
|
||||||
|
|
||||||
BuiltinProc_size_of,
|
BuiltinProc_size_of,
|
||||||
BuiltinProc_size_of_val,
|
BuiltinProc_size_of_val,
|
||||||
@@ -165,7 +166,8 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_Count] = {
|
|||||||
{STR_LIT(""), 0, false, Expr_Stmt},
|
{STR_LIT(""), 0, false, Expr_Stmt},
|
||||||
|
|
||||||
{STR_LIT("new"), 1, false, Expr_Expr},
|
{STR_LIT("new"), 1, false, Expr_Expr},
|
||||||
{STR_LIT("new_slice"), 2, false, Expr_Expr},
|
{STR_LIT("new_slice"), 2, false, Expr_Expr},
|
||||||
|
{STR_LIT("free"), 1, false, Expr_Stmt},
|
||||||
|
|
||||||
{STR_LIT("size_of"), 1, false, Expr_Expr},
|
{STR_LIT("size_of"), 1, false, Expr_Expr},
|
||||||
{STR_LIT("size_of_val"), 1, false, Expr_Expr},
|
{STR_LIT("size_of_val"), 1, false, Expr_Expr},
|
||||||
|
|||||||
+3
-7
@@ -4819,14 +4819,10 @@ GB_ALLOCATOR_PROC(gb_heap_allocator_proc) {
|
|||||||
#else
|
#else
|
||||||
// TODO(bill): *nix version that's decent
|
// TODO(bill): *nix version that's decent
|
||||||
case gbAllocation_Alloc: {
|
case gbAllocation_Alloc: {
|
||||||
gbAllocationHeader *header;
|
ptr = aligned_alloc(alignment, size);
|
||||||
isize total_size = size + alignment + gb_size_of(gbAllocationHeader);
|
if (flags & gbAllocatorFlag_ClearToZero) {
|
||||||
ptr = malloc(total_size);
|
|
||||||
header = cast(gbAllocationHeader *)ptr;
|
|
||||||
ptr = gb_align_forward(header+1, alignment);
|
|
||||||
gb_allocation_header_fill(header, ptr, size);
|
|
||||||
if (flags & gbAllocatorFlag_ClearToZero)
|
|
||||||
gb_zero_size(ptr, size);
|
gb_zero_size(ptr, size);
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case gbAllocation_Free: {
|
case gbAllocation_Free: {
|
||||||
|
|||||||
@@ -2909,6 +2909,37 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv
|
|||||||
return ir_emit_load(proc, slice);
|
return ir_emit_load(proc, slice);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case BuiltinProc_free: {
|
||||||
|
ir_emit_comment(proc, str_lit("free"));
|
||||||
|
|
||||||
|
gbAllocator allocator = proc->module->allocator;
|
||||||
|
|
||||||
|
AstNode *node = ce->args.e[0];
|
||||||
|
TypeAndValue tav = *type_and_value_of_expression(proc->module->info, node);
|
||||||
|
Type *type = base_type(tav.type);
|
||||||
|
irValue *val = ir_build_expr(proc, node);
|
||||||
|
irValue *ptr = NULL;
|
||||||
|
if (is_type_pointer(type)) {
|
||||||
|
ptr = val;
|
||||||
|
} else if (is_type_slice(type)) {
|
||||||
|
ptr = ir_slice_elem(proc, val);
|
||||||
|
} else if (is_type_string(type)) {
|
||||||
|
ptr = ir_string_elem(proc, val);
|
||||||
|
} else {
|
||||||
|
GB_PANIC("Invalid type to `free`");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ptr == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr = ir_emit_conv(proc, ptr, t_rawptr);
|
||||||
|
|
||||||
|
irValue **args = gb_alloc_array(allocator, irValue *, 1);
|
||||||
|
args[0] = ptr;
|
||||||
|
return ir_emit_global_call(proc, "free_ptr", args, 1);
|
||||||
|
} break;
|
||||||
|
|
||||||
case BuiltinProc_assert: {
|
case BuiltinProc_assert: {
|
||||||
ir_emit_comment(proc, str_lit("assert"));
|
ir_emit_comment(proc, str_lit("assert"));
|
||||||
irValue *cond = ir_build_expr(proc, ce->args.e[0]);
|
irValue *cond = ir_build_expr(proc, ce->args.e[0]);
|
||||||
|
|||||||
+12
-5
@@ -149,7 +149,7 @@ AST_NODE_KIND(_ExprBegin, "", i32) \
|
|||||||
AST_NODE_KIND(DemaybeExpr, "demaybe expression", struct { Token op; AstNode *expr; }) \
|
AST_NODE_KIND(DemaybeExpr, "demaybe expression", struct { Token op; AstNode *expr; }) \
|
||||||
AST_NODE_KIND(SliceExpr, "slice expression", struct { \
|
AST_NODE_KIND(SliceExpr, "slice expression", struct { \
|
||||||
AstNode *expr; \
|
AstNode *expr; \
|
||||||
Token open, close; \
|
Token open, close, interval; \
|
||||||
AstNode *low, *high; \
|
AstNode *low, *high; \
|
||||||
}) \
|
}) \
|
||||||
AST_NODE_KIND(CallExpr, "call expression", struct { \
|
AST_NODE_KIND(CallExpr, "call expression", struct { \
|
||||||
@@ -716,11 +716,12 @@ AstNode *make_index_expr(AstFile *f, AstNode *expr, AstNode *index, Token open,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
AstNode *make_slice_expr(AstFile *f, AstNode *expr, Token open, Token close, AstNode *low, AstNode *high) {
|
AstNode *make_slice_expr(AstFile *f, AstNode *expr, Token open, Token close, Token interval, AstNode *low, AstNode *high) {
|
||||||
AstNode *result = make_node(f, AstNode_SliceExpr);
|
AstNode *result = make_node(f, AstNode_SliceExpr);
|
||||||
result->SliceExpr.expr = expr;
|
result->SliceExpr.expr = expr;
|
||||||
result->SliceExpr.open = open;
|
result->SliceExpr.open = open;
|
||||||
result->SliceExpr.close = close;
|
result->SliceExpr.close = close;
|
||||||
|
result->SliceExpr.interval = interval;
|
||||||
result->SliceExpr.low = low;
|
result->SliceExpr.low = low;
|
||||||
result->SliceExpr.high = high;
|
result->SliceExpr.high = high;
|
||||||
return result;
|
return result;
|
||||||
@@ -1970,19 +1971,25 @@ AstNode *parse_atom_expr(AstFile *f, bool lhs) {
|
|||||||
if (lhs) {
|
if (lhs) {
|
||||||
// TODO(bill): Handle this
|
// TODO(bill): Handle this
|
||||||
}
|
}
|
||||||
Token open, close;
|
Token open = {0}, close = {0}, interval = {0};
|
||||||
AstNode *indices[2] = {0};
|
AstNode *indices[2] = {0};
|
||||||
|
|
||||||
f->expr_level++;
|
f->expr_level++;
|
||||||
open = expect_token(f, Token_OpenBracket);
|
open = expect_token(f, Token_OpenBracket);
|
||||||
|
|
||||||
|
// if (f->curr_token.kind != Token_Ellipsis &&
|
||||||
|
// f->curr_token.kind != Token_HalfOpenRange) {
|
||||||
if (f->curr_token.kind != Token_Colon) {
|
if (f->curr_token.kind != Token_Colon) {
|
||||||
indices[0] = parse_expr(f, false);
|
indices[0] = parse_expr(f, false);
|
||||||
}
|
}
|
||||||
bool is_index = true;
|
bool is_index = true;
|
||||||
|
|
||||||
if (allow_token(f, Token_Colon)) {
|
// if (f->curr_token.kind == Token_Ellipsis ||
|
||||||
|
// f->curr_token.kind == Token_HalfOpenRange) {
|
||||||
|
if (f->curr_token.kind == Token_Colon) {
|
||||||
is_index = false;
|
is_index = false;
|
||||||
|
interval = f->curr_token;
|
||||||
|
next_token(f);
|
||||||
if (f->curr_token.kind != Token_CloseBracket &&
|
if (f->curr_token.kind != Token_CloseBracket &&
|
||||||
f->curr_token.kind != Token_EOF) {
|
f->curr_token.kind != Token_EOF) {
|
||||||
indices[1] = parse_expr(f, false);
|
indices[1] = parse_expr(f, false);
|
||||||
@@ -1995,7 +2002,7 @@ AstNode *parse_atom_expr(AstFile *f, bool lhs) {
|
|||||||
if (is_index) {
|
if (is_index) {
|
||||||
operand = make_index_expr(f, operand, indices[0], open, close);
|
operand = make_index_expr(f, operand, indices[0], open, close);
|
||||||
} else {
|
} else {
|
||||||
operand = make_slice_expr(f, operand, open, close, indices[0], indices[1]);
|
operand = make_slice_expr(f, operand, open, close, interval, indices[0], indices[1]);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
|||||||
+4
-2
@@ -75,7 +75,7 @@ TOKEN_KIND(Token__ComparisonEnd, "_ComparisonEnd"), \
|
|||||||
TOKEN_KIND(Token_Semicolon, ";"), \
|
TOKEN_KIND(Token_Semicolon, ";"), \
|
||||||
TOKEN_KIND(Token_Period, "."), \
|
TOKEN_KIND(Token_Period, "."), \
|
||||||
TOKEN_KIND(Token_Comma, ","), \
|
TOKEN_KIND(Token_Comma, ","), \
|
||||||
TOKEN_KIND(Token_Ellipsis, ".."), \
|
TOKEN_KIND(Token_Ellipsis, "..."), \
|
||||||
TOKEN_KIND(Token_HalfOpenRange, "..<"), \
|
TOKEN_KIND(Token_HalfOpenRange, "..<"), \
|
||||||
TOKEN_KIND(Token__OperatorEnd, "_OperatorEnd"), \
|
TOKEN_KIND(Token__OperatorEnd, "_OperatorEnd"), \
|
||||||
\
|
\
|
||||||
@@ -847,10 +847,12 @@ Token tokenizer_get_token(Tokenizer *t) {
|
|||||||
token.kind = Token_Period; // Default
|
token.kind = Token_Period; // Default
|
||||||
if (t->curr_rune == '.') { // Could be an ellipsis
|
if (t->curr_rune == '.') { // Could be an ellipsis
|
||||||
advance_to_next_rune(t);
|
advance_to_next_rune(t);
|
||||||
token.kind = Token_Ellipsis;
|
|
||||||
if (t->curr_rune == '<') {
|
if (t->curr_rune == '<') {
|
||||||
advance_to_next_rune(t);
|
advance_to_next_rune(t);
|
||||||
token.kind = Token_HalfOpenRange;
|
token.kind = Token_HalfOpenRange;
|
||||||
|
} else if (t->curr_rune == '.') {
|
||||||
|
advance_to_next_rune(t);
|
||||||
|
token.kind = Token_Ellipsis;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user