Compare commits
3 Commits
bb1e689c5a
...
77af4d067b
Author | SHA1 | Date |
---|---|---|
kayomn | 77af4d067b | |
kayomn | c4916a4195 | |
kayomn | 08a63489b0 |
|
@ -1,12 +1,20 @@
|
||||||
|
|
||||||
i = 0
|
i = 0
|
||||||
|
|
||||||
while i < 5 do
|
while i < 5:
|
||||||
@print("hello, world")
|
@print("hello, world")
|
||||||
|
|
||||||
i = i + 1
|
i = i + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if i > 6:
|
||||||
|
@print("`i` greater than `6`")
|
||||||
|
elif i == 4:
|
||||||
|
@print("`i` is equal to `4`")
|
||||||
|
else:
|
||||||
|
@print("i'unno")
|
||||||
|
end
|
||||||
|
|
||||||
return {
|
return {
|
||||||
.title = "Game",
|
.title = "Game",
|
||||||
.width = 1280,
|
.width = 1280,
|
||||||
|
|
|
@ -36,6 +36,7 @@ pub const RuntimeEnv = struct {
|
||||||
};
|
};
|
||||||
|
|
||||||
const Opcode = union (enum) {
|
const Opcode = union (enum) {
|
||||||
|
pop,
|
||||||
push_nil,
|
push_nil,
|
||||||
push_true,
|
push_true,
|
||||||
push_false,
|
push_false,
|
||||||
|
@ -135,9 +136,9 @@ pub const RuntimeEnv = struct {
|
||||||
.subtraction => .sub,
|
.subtraction => .sub,
|
||||||
.multiplication => .mul,
|
.multiplication => .mul,
|
||||||
.divsion => .div,
|
.divsion => .div,
|
||||||
.greater_equals_comparison => .eql,
|
.greater_equals_comparison => .cge,
|
||||||
.greater_than_comparison => .cgt,
|
.greater_than_comparison => .cgt,
|
||||||
.equals_comparison => .cge,
|
.equals_comparison => .eql,
|
||||||
.less_than_comparison => .clt,
|
.less_than_comparison => .clt,
|
||||||
.less_equals_comparison => .cle,
|
.less_equals_comparison => .cle,
|
||||||
});
|
});
|
||||||
|
@ -263,13 +264,19 @@ pub const RuntimeEnv = struct {
|
||||||
fn compile_statement(self: *CompilationUnit, chunk: *Chunk, statement: ast.Statement) RuntimeError!void {
|
fn compile_statement(self: *CompilationUnit, chunk: *Chunk, statement: ast.Statement) RuntimeError!void {
|
||||||
switch (statement) {
|
switch (statement) {
|
||||||
.@"return" => |@"return"| {
|
.@"return" => |@"return"| {
|
||||||
if (@"return".expression) |expression| {
|
if (@"return") |expression| {
|
||||||
try self.compile_expression(chunk, expression);
|
try self.compile_expression(chunk, expression);
|
||||||
} else {
|
} else {
|
||||||
try chunk.opcodes.push_one(.push_nil);
|
try chunk.opcodes.push_one(.push_nil);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
.block => |block| {
|
||||||
|
for (block.values) |block_statement| {
|
||||||
|
try self.compile_statement(chunk, block_statement);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
.@"while" => |@"while"| {
|
.@"while" => |@"while"| {
|
||||||
try self.compile_expression(chunk, @"while".condition_expression);
|
try self.compile_expression(chunk, @"while".condition_expression);
|
||||||
try chunk.opcodes.push_one(.{.jf = 0});
|
try chunk.opcodes.push_one(.{.jf = 0});
|
||||||
|
@ -280,8 +287,6 @@ pub const RuntimeEnv = struct {
|
||||||
try self.compile_statement(chunk, block_statement);
|
try self.compile_statement(chunk, block_statement);
|
||||||
}
|
}
|
||||||
|
|
||||||
coral.debug.assert(chunk.opcodes.values.len < coral.math.max_int(@typeInfo(u32).Int));
|
|
||||||
|
|
||||||
chunk.opcodes.values[origin_index].jf = @intCast(chunk.opcodes.values.len - 1);
|
chunk.opcodes.values[origin_index].jf = @intCast(chunk.opcodes.values.len - 1);
|
||||||
|
|
||||||
try self.compile_expression(chunk, @"while".condition_expression);
|
try self.compile_expression(chunk, @"while".condition_expression);
|
||||||
|
@ -298,12 +303,20 @@ pub const RuntimeEnv = struct {
|
||||||
try self.compile_statement(chunk, block_statement);
|
try self.compile_statement(chunk, block_statement);
|
||||||
}
|
}
|
||||||
|
|
||||||
coral.debug.assert(chunk.opcodes.values.len < coral.math.max_int(@typeInfo(u32).Int));
|
|
||||||
|
|
||||||
chunk.opcodes.values[origin_index].jf = @intCast(chunk.opcodes.values.len - 1);
|
chunk.opcodes.values[origin_index].jf = @intCast(chunk.opcodes.values.len - 1);
|
||||||
|
|
||||||
|
if (@"if".else_statement) |else_statement| {
|
||||||
|
try self.compile_statement(chunk, else_statement.*);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
.expression => |expression| try self.compile_expression(chunk, expression),
|
.expression => |expression| {
|
||||||
|
try self.compile_expression(chunk, expression);
|
||||||
|
|
||||||
|
if (expression == .invoke) {
|
||||||
|
try chunk.opcodes.push_one(.pop);
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,10 +339,10 @@ pub const RuntimeEnv = struct {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
fn compile(self: *Chunk, statements: *const ast.StatementList) RuntimeError!void {
|
fn compile(self: *Chunk, statements: []const ast.Statement) RuntimeError!void {
|
||||||
var unit = CompilationUnit{};
|
var unit = CompilationUnit{};
|
||||||
|
|
||||||
for (statements.values) |statement| {
|
for (statements) |statement| {
|
||||||
try unit.compile_statement(self, statement);
|
try unit.compile_statement(self, statement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -364,6 +377,12 @@ pub const RuntimeEnv = struct {
|
||||||
|
|
||||||
while (opcode_cursor < self.opcodes.values.len) : (opcode_cursor += 1) {
|
while (opcode_cursor < self.opcodes.values.len) : (opcode_cursor += 1) {
|
||||||
switch (self.opcodes.values[opcode_cursor]) {
|
switch (self.opcodes.values[opcode_cursor]) {
|
||||||
|
.pop => {
|
||||||
|
if (try self.pop_local()) |ref| {
|
||||||
|
self.env.discard(ref);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
.push_nil => try self.env.locals.push_one(null),
|
.push_nil => try self.env.locals.push_one(null),
|
||||||
.push_true => try self.env.locals.push_one(try self.env.new_boolean(true)),
|
.push_true => try self.env.locals.push_one(try self.env.new_boolean(true)),
|
||||||
.push_false => try self.env.locals.push_one(try self.env.new_boolean(false)),
|
.push_false => try self.env.locals.push_one(try self.env.new_boolean(false)),
|
||||||
|
|
|
@ -118,9 +118,11 @@ pub const Expression = union (enum) {
|
||||||
|
|
||||||
invoke: struct {
|
invoke: struct {
|
||||||
object_expression: *Expression,
|
object_expression: *Expression,
|
||||||
argument_expressions: ExpressionList,
|
argument_expressions: List,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
const List = coral.list.Stack(Expression);
|
||||||
|
|
||||||
const TableLiteral = coral.list.Stack(struct {
|
const TableLiteral = coral.list.Stack(struct {
|
||||||
key_expression: Expression,
|
key_expression: Expression,
|
||||||
value_expression: Expression,
|
value_expression: Expression,
|
||||||
|
@ -129,37 +131,38 @@ pub const Expression = union (enum) {
|
||||||
|
|
||||||
const ExpressionBuilder = fn (self: *Tree) ParseError!Expression;
|
const ExpressionBuilder = fn (self: *Tree) ParseError!Expression;
|
||||||
|
|
||||||
pub const ExpressionList = coral.list.Stack(Expression);
|
|
||||||
|
|
||||||
pub const ParseError = error {
|
pub const ParseError = error {
|
||||||
OutOfMemory,
|
OutOfMemory,
|
||||||
BadSyntax,
|
BadSyntax,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Statement = union (enum) {
|
pub const Statement = union (enum) {
|
||||||
@"return": struct {
|
@"return": ?Expression,
|
||||||
expression: ?Expression,
|
|
||||||
|
@"if": struct {
|
||||||
|
condition_expression: Expression,
|
||||||
|
block_statements: List,
|
||||||
|
else_statement: ?*Statement,
|
||||||
},
|
},
|
||||||
|
|
||||||
@"if": ConditionalBlock,
|
@"while": struct {
|
||||||
@"while": ConditionalBlock,
|
condition_expression: Expression,
|
||||||
|
block_statements: List,
|
||||||
|
},
|
||||||
|
|
||||||
|
block: List,
|
||||||
expression: Expression,
|
expression: Expression,
|
||||||
|
|
||||||
const ConditionalBlock = struct {
|
const List = coral.list.Stack(Statement);
|
||||||
condition_expression: Expression,
|
|
||||||
block_statements: StatementList,
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const StatementList = coral.list.Stack(Statement);
|
|
||||||
|
|
||||||
pub const Tree = struct {
|
pub const Tree = struct {
|
||||||
name: []const coral.io.Byte,
|
name: []const coral.io.Byte,
|
||||||
allocator: coral.io.Allocator,
|
allocator: coral.io.Allocator,
|
||||||
arena: coral.arena.Stacking,
|
arena: coral.arena.Stacking,
|
||||||
error_buffer: coral.list.ByteStack,
|
error_buffer: coral.list.ByteStack,
|
||||||
tokenizer: tokens.Tokenizer,
|
tokenizer: tokens.Tokenizer,
|
||||||
parsed_statements: StatementList,
|
parsed_statements: Statement.List,
|
||||||
has_returned: bool,
|
has_returned: bool,
|
||||||
|
|
||||||
pub fn error_message(self: Tree) []const coral.io.Byte {
|
pub fn error_message(self: Tree) []const coral.io.Byte {
|
||||||
|
@ -176,7 +179,7 @@ pub const Tree = struct {
|
||||||
return .{
|
return .{
|
||||||
.arena = coral.arena.Stacking.make(allocator, 4096),
|
.arena = coral.arena.Stacking.make(allocator, 4096),
|
||||||
.error_buffer = coral.list.ByteStack.make(allocator),
|
.error_buffer = coral.list.ByteStack.make(allocator),
|
||||||
.parsed_statements = StatementList.make(allocator),
|
.parsed_statements = Statement.List.make(allocator),
|
||||||
.tokenizer = .{.source = ""},
|
.tokenizer = .{.source = ""},
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
.name = ast_name,
|
.name = ast_name,
|
||||||
|
@ -184,19 +187,19 @@ pub const Tree = struct {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse(self: *Tree, data: []const coral.io.Byte) ParseError!*const StatementList {
|
pub fn parse(self: *Tree, data: []const coral.io.Byte) ParseError![]const Statement {
|
||||||
|
self.free();
|
||||||
|
|
||||||
self.tokenizer = .{.source = data};
|
self.tokenizer = .{.source = data};
|
||||||
self.has_returned = false;
|
self.has_returned = false;
|
||||||
|
|
||||||
self.parsed_statements.free();
|
self.tokenizer.skip_newlines();
|
||||||
|
|
||||||
self.parsed_statements = try self.parse_statements();
|
while (self.tokenizer.token != .end) {
|
||||||
|
try self.parsed_statements.push_one(try self.parse_statement());
|
||||||
if (self.tokenizer.token == .keyword_end) {
|
|
||||||
return self.report("unexpected `end` without matching `do` block");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return &self.parsed_statements;
|
return self.parsed_statements.values;
|
||||||
}
|
}
|
||||||
|
|
||||||
const parse_additive = BinaryOperator.builder(parse_equality, &.{
|
const parse_additive = BinaryOperator.builder(parse_equality, &.{
|
||||||
|
@ -204,6 +207,74 @@ pub const Tree = struct {
|
||||||
.subtraction,
|
.subtraction,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
fn parse_branch(self: *Tree) ParseError!Statement {
|
||||||
|
const allocator = self.arena.as_allocator();
|
||||||
|
|
||||||
|
defer self.tokenizer.skip_newlines();
|
||||||
|
|
||||||
|
self.tokenizer.step();
|
||||||
|
|
||||||
|
const condition_expression = try self.parse_expression();
|
||||||
|
|
||||||
|
if (self.tokenizer.token != .symbol_colon) {
|
||||||
|
return self.report("expected `:` after `if` statement condition");
|
||||||
|
}
|
||||||
|
|
||||||
|
var statements = Statement.List.make(allocator);
|
||||||
|
|
||||||
|
self.tokenizer.skip_newlines();
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
switch (self.tokenizer.token) {
|
||||||
|
.keyword_end => {
|
||||||
|
return .{
|
||||||
|
.@"if" = .{
|
||||||
|
.condition_expression = condition_expression,
|
||||||
|
.block_statements = statements,
|
||||||
|
.else_statement = null,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
.keyword_else => {
|
||||||
|
self.tokenizer.step();
|
||||||
|
|
||||||
|
if (self.tokenizer.token != .symbol_colon) {
|
||||||
|
return self.report("expected `:` after `if` statement condition");
|
||||||
|
}
|
||||||
|
|
||||||
|
var else_statements = Statement.List.make(allocator);
|
||||||
|
|
||||||
|
self.tokenizer.skip_newlines();
|
||||||
|
|
||||||
|
while (self.tokenizer.token != .keyword_end) {
|
||||||
|
try else_statements.push_one(try self.parse_statement());
|
||||||
|
}
|
||||||
|
|
||||||
|
return .{
|
||||||
|
.@"if" = .{
|
||||||
|
.else_statement = try coral.io.allocate_one(allocator, Statement{.block = else_statements}),
|
||||||
|
.condition_expression = condition_expression,
|
||||||
|
.block_statements = statements,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
.keyword_elif => {
|
||||||
|
return .{
|
||||||
|
.@"if" = .{
|
||||||
|
.else_statement = try coral.io.allocate_one(allocator, try self.parse_branch()),
|
||||||
|
.condition_expression = condition_expression,
|
||||||
|
.block_statements = statements,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
else => try statements.push_one(try self.parse_statement()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const parse_comparison = BinaryOperator.builder(parse_term, &.{
|
const parse_comparison = BinaryOperator.builder(parse_term, &.{
|
||||||
.greater_than_comparison,
|
.greater_than_comparison,
|
||||||
.greater_equals_comparison,
|
.greater_equals_comparison,
|
||||||
|
@ -486,7 +557,7 @@ pub const Tree = struct {
|
||||||
},
|
},
|
||||||
|
|
||||||
.symbol_paren_left => {
|
.symbol_paren_left => {
|
||||||
var argument_expressions = ExpressionList.make(allocator);
|
var argument_expressions = Expression.List.make(allocator);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
self.tokenizer.skip_newlines();
|
self.tokenizer.skip_newlines();
|
||||||
|
@ -526,25 +597,21 @@ pub const Tree = struct {
|
||||||
return expression;
|
return expression;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_statements(self: *Tree) ParseError!StatementList {
|
fn parse_statement(self: *Tree) ParseError!Statement {
|
||||||
var statements = StatementList.make(self.arena.as_allocator());
|
const allocator = self.arena.as_allocator();
|
||||||
|
|
||||||
self.tokenizer.skip_newlines();
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
try statements.push_one(parse_statement: {
|
|
||||||
switch (self.tokenizer.token) {
|
switch (self.tokenizer.token) {
|
||||||
.end, .keyword_end => return statements,
|
|
||||||
|
|
||||||
.keyword_return => {
|
.keyword_return => {
|
||||||
|
defer self.tokenizer.skip_newlines();
|
||||||
|
|
||||||
if (self.has_returned) {
|
if (self.has_returned) {
|
||||||
return self.report("multiple returns in function scope but expected only one");
|
return self.report("multiple returns in lambda scope but expected only one");
|
||||||
}
|
}
|
||||||
|
|
||||||
self.tokenizer.step();
|
self.tokenizer.step();
|
||||||
|
|
||||||
if (self.tokenizer.token != .end and self.tokenizer.token != .newline) {
|
if (self.tokenizer.token != .end and self.tokenizer.token != .newline) {
|
||||||
break: parse_statement .{.@"return" = .{.expression = try self.parse_expression()}};
|
return .{.@"return" = try self.parse_expression()};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self.tokenizer.token != .end and self.tokenizer.token != .newline) {
|
if (self.tokenizer.token != .end and self.tokenizer.token != .newline) {
|
||||||
|
@ -553,66 +620,38 @@ pub const Tree = struct {
|
||||||
|
|
||||||
self.has_returned = true;
|
self.has_returned = true;
|
||||||
|
|
||||||
break: parse_statement .{.@"return" = .{.expression = null}};
|
return .{.@"return" = null};
|
||||||
},
|
},
|
||||||
|
|
||||||
.keyword_while => {
|
.keyword_while => {
|
||||||
|
defer self.tokenizer.skip_newlines();
|
||||||
|
|
||||||
self.tokenizer.step();
|
self.tokenizer.step();
|
||||||
|
|
||||||
const condition_expression = try self.parse_expression();
|
const condition_expression = try self.parse_expression();
|
||||||
|
|
||||||
if (self.tokenizer.token != .keyword_do) {
|
if (self.tokenizer.token != .symbol_colon) {
|
||||||
return self.report("expected `do` block after `while` statement");
|
return self.report("expected `:` after `while` statement");
|
||||||
}
|
}
|
||||||
|
|
||||||
self.tokenizer.step();
|
var statements = Statement.List.make(allocator);
|
||||||
|
|
||||||
const while_statement = Statement{
|
self.tokenizer.skip_newlines();
|
||||||
|
|
||||||
|
while (self.tokenizer.token != .keyword_end) {
|
||||||
|
try statements.push_one(try self.parse_statement());
|
||||||
|
}
|
||||||
|
|
||||||
|
return .{
|
||||||
.@"while" = .{
|
.@"while" = .{
|
||||||
.block_statements = try self.parse_statements(),
|
.block_statements = statements,
|
||||||
.condition_expression = condition_expression,
|
.condition_expression = condition_expression,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (self.tokenizer.token != .keyword_end) {
|
|
||||||
return self.report("expected `end` after block");
|
|
||||||
}
|
|
||||||
|
|
||||||
self.tokenizer.skip_newlines();
|
|
||||||
|
|
||||||
break: parse_statement while_statement;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
.keyword_if => {
|
.keyword_if => return self.parse_branch(),
|
||||||
self.tokenizer.step();
|
else => return .{.expression = try self.parse_expression()},
|
||||||
|
|
||||||
const condition_expression = try self.parse_expression();
|
|
||||||
|
|
||||||
if (self.tokenizer.token != .keyword_do) {
|
|
||||||
return self.report("expected `do` block after `if` statement");
|
|
||||||
}
|
|
||||||
|
|
||||||
self.tokenizer.step();
|
|
||||||
|
|
||||||
const if_statement = Statement{
|
|
||||||
.@"if" = .{
|
|
||||||
.block_statements = try self.parse_statements(),
|
|
||||||
.condition_expression = condition_expression,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
if (self.tokenizer.token != .keyword_end) {
|
|
||||||
return self.report("expected `end` after block");
|
|
||||||
}
|
|
||||||
|
|
||||||
self.tokenizer.skip_newlines();
|
|
||||||
|
|
||||||
break: parse_statement if_statement;
|
|
||||||
},
|
|
||||||
|
|
||||||
else => break: parse_statement .{.expression = try self.parse_expression()},
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ pub const Token = union(enum) {
|
||||||
symbol_bracket_left,
|
symbol_bracket_left,
|
||||||
symbol_bracket_right,
|
symbol_bracket_right,
|
||||||
symbol_period,
|
symbol_period,
|
||||||
symbol_lambda,
|
symbol_colon,
|
||||||
symbol_less_than,
|
symbol_less_than,
|
||||||
symbol_less_equals,
|
symbol_less_equals,
|
||||||
symbol_greater_than,
|
symbol_greater_than,
|
||||||
|
@ -42,6 +42,8 @@ pub const Token = union(enum) {
|
||||||
keyword_do,
|
keyword_do,
|
||||||
keyword_end,
|
keyword_end,
|
||||||
keyword_while,
|
keyword_while,
|
||||||
|
keyword_else,
|
||||||
|
keyword_elif,
|
||||||
|
|
||||||
pub fn text(self: Token) []const coral.io.Byte {
|
pub fn text(self: Token) []const coral.io.Byte {
|
||||||
return switch (self) {
|
return switch (self) {
|
||||||
|
@ -66,7 +68,7 @@ pub const Token = union(enum) {
|
||||||
.symbol_bracket_left => "[",
|
.symbol_bracket_left => "[",
|
||||||
.symbol_bracket_right => "]",
|
.symbol_bracket_right => "]",
|
||||||
.symbol_period => ".",
|
.symbol_period => ".",
|
||||||
.symbol_lambda => "=>",
|
.symbol_colon => ":",
|
||||||
.symbol_less_than => "<",
|
.symbol_less_than => "<",
|
||||||
.symbol_less_equals => "<=",
|
.symbol_less_equals => "<=",
|
||||||
.symbol_greater_than => ">",
|
.symbol_greater_than => ">",
|
||||||
|
@ -87,6 +89,8 @@ pub const Token = union(enum) {
|
||||||
.keyword_do => "do",
|
.keyword_do => "do",
|
||||||
.keyword_end => "end",
|
.keyword_end => "end",
|
||||||
.keyword_while => "while",
|
.keyword_while => "while",
|
||||||
|
.keyword_elif => "elif",
|
||||||
|
.keyword_else => "else",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -94,7 +98,7 @@ pub const Token = union(enum) {
|
||||||
pub const Tokenizer = struct {
|
pub const Tokenizer = struct {
|
||||||
source: []const coral.io.Byte,
|
source: []const coral.io.Byte,
|
||||||
lines_stepped: usize = 1,
|
lines_stepped: usize = 1,
|
||||||
token: Token = .end,
|
token: Token = .newline,
|
||||||
|
|
||||||
pub fn skip_newlines(self: *Tokenizer) void {
|
pub fn skip_newlines(self: *Tokenizer) void {
|
||||||
self.step();
|
self.step();
|
||||||
|
@ -190,6 +194,18 @@ pub const Tokenizer = struct {
|
||||||
},
|
},
|
||||||
|
|
||||||
'e' => {
|
'e' => {
|
||||||
|
if (coral.io.ends_with(identifier, "lse")) {
|
||||||
|
self.token = .keyword_else;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (coral.io.ends_with(identifier, "lif")) {
|
||||||
|
self.token = .keyword_elif;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (coral.io.ends_with(identifier, "nd")) {
|
if (coral.io.ends_with(identifier, "nd")) {
|
||||||
self.token = .keyword_end;
|
self.token = .keyword_end;
|
||||||
|
|
||||||
|
@ -378,6 +394,13 @@ pub const Tokenizer = struct {
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
':' => {
|
||||||
|
self.token = .symbol_colon;
|
||||||
|
cursor += 1;
|
||||||
|
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
|
||||||
'=' => {
|
'=' => {
|
||||||
cursor += 1;
|
cursor += 1;
|
||||||
|
|
||||||
|
@ -390,13 +413,6 @@ pub const Tokenizer = struct {
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
|
|
||||||
'>' => {
|
|
||||||
cursor += 1;
|
|
||||||
self.token = .symbol_lambda;
|
|
||||||
|
|
||||||
return;
|
|
||||||
},
|
|
||||||
|
|
||||||
else => {},
|
else => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue