Compare commits
No commits in common. "1ac63cdbef725f202483d5b2f684a2fe3a9404d2" and "013aafa8a436d4b73ad0c3ac61dccccbbda930b9" have entirely different histories.
1ac63cdbef
...
013aafa8a4
6 changed files with 81 additions and 168 deletions
|
@ -1,11 +1,7 @@
|
||||||
// import std;
|
// import std;
|
||||||
|
|
||||||
fn add(a: i32, b: i32) i32 {
|
fn add() i32 {
|
||||||
return 69 + 69;
|
return 1 + 1;
|
||||||
}
|
|
||||||
|
|
||||||
fn and_fn() bool {
|
|
||||||
return true and false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// type is void by default
|
// type is void by default
|
||||||
|
|
34
src/ast.zig
34
src/ast.zig
|
@ -44,38 +44,20 @@ pub const SingleConst = struct {
|
||||||
expr: *Expr,
|
expr: *Expr,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const BinaryOperator = enum {
|
|
||||||
|
|
||||||
// numeric
|
|
||||||
Add,
|
|
||||||
Sub,
|
|
||||||
Mul,
|
|
||||||
Div,
|
|
||||||
Mod,
|
|
||||||
|
|
||||||
// numeric -> bool
|
|
||||||
Greater,
|
|
||||||
GreaterEqual,
|
|
||||||
Less,
|
|
||||||
LessEqual,
|
|
||||||
|
|
||||||
// booleans
|
|
||||||
Equal,
|
|
||||||
And,
|
|
||||||
Or,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const BinaryExpr = struct {
|
pub const BinaryExpr = struct {
|
||||||
left: *Expr,
|
left: *Expr,
|
||||||
op: BinaryOperator,
|
op: Token,
|
||||||
right: *Expr,
|
right: *Expr,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const UnaryOperator = enum {
|
pub const UnaryExpr = struct {
|
||||||
Not,
|
op: Token,
|
||||||
|
right: *Expr,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const UnaryExpr = struct {
|
// looks like a BinaryExpr, but is not a BinaryExpr
|
||||||
|
pub const LogicalExpr = struct {
|
||||||
|
left: *Expr,
|
||||||
op: Token,
|
op: Token,
|
||||||
right: *Expr,
|
right: *Expr,
|
||||||
};
|
};
|
||||||
|
@ -101,6 +83,7 @@ pub const ExprType = enum {
|
||||||
|
|
||||||
Binary,
|
Binary,
|
||||||
Unary,
|
Unary,
|
||||||
|
Logical,
|
||||||
Literal,
|
Literal,
|
||||||
Variable,
|
Variable,
|
||||||
Call,
|
Call,
|
||||||
|
@ -151,6 +134,7 @@ pub const Expr = union(ExprType) {
|
||||||
|
|
||||||
Binary: BinaryExpr,
|
Binary: BinaryExpr,
|
||||||
Unary: UnaryExpr,
|
Unary: UnaryExpr,
|
||||||
|
Logical: LogicalExpr,
|
||||||
Literal: LiteralExpr,
|
Literal: LiteralExpr,
|
||||||
Struct: StructExpr,
|
Struct: StructExpr,
|
||||||
|
|
||||||
|
|
|
@ -155,37 +155,8 @@ fn printTwoExprs(expr_a: *const Expr, expr_b: *const Expr) void {
|
||||||
printExpr(expr_b);
|
printExpr(expr_b);
|
||||||
}
|
}
|
||||||
|
|
||||||
const operator_tokens = [_][]const u8{
|
|
||||||
"+", "-", "*", "/", "%", ">", ">=", "<", "<=", "==", "&&", "||",
|
|
||||||
};
|
|
||||||
|
|
||||||
const operator_values = [_]BinaryOperator{
|
|
||||||
.Add,
|
|
||||||
.Sub,
|
|
||||||
.Mul,
|
|
||||||
.Div,
|
|
||||||
.Mod,
|
|
||||||
|
|
||||||
.Greater,
|
|
||||||
.GreaterEqual,
|
|
||||||
.Less,
|
|
||||||
.LessEqual,
|
|
||||||
|
|
||||||
.Equal,
|
|
||||||
.And,
|
|
||||||
.Or,
|
|
||||||
};
|
|
||||||
|
|
||||||
fn binOpToStr(op: BinaryOperator) ?[]const u8 {
|
|
||||||
inline for (operator_values) |val, idx| {
|
|
||||||
if (val == op) return operator_tokens[idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn printBinOp(inner: var) void {
|
fn printBinOp(inner: var) void {
|
||||||
std.debug.warn("({}", binOpToStr(inner.op));
|
std.debug.warn("({}", inner.op.lexeme);
|
||||||
printTwoExprs(inner.left, inner.right);
|
printTwoExprs(inner.left, inner.right);
|
||||||
std.debug.warn(")");
|
std.debug.warn(")");
|
||||||
}
|
}
|
||||||
|
@ -199,6 +170,7 @@ fn printSingleOp(tok: []const u8, applied: *const Expr) void {
|
||||||
pub fn printExpr(expr: *const Expr) void {
|
pub fn printExpr(expr: *const Expr) void {
|
||||||
switch (expr.*) {
|
switch (expr.*) {
|
||||||
.Binary => |binary| printBinOp(binary),
|
.Binary => |binary| printBinOp(binary),
|
||||||
|
.Logical => |logical| printBinOp(logical),
|
||||||
|
|
||||||
.Unary => |unary| printSingleOp(unary.op.lexeme, unary.right),
|
.Unary => |unary| printSingleOp(unary.op.lexeme, unary.right),
|
||||||
.Grouping => |expr_ptr| printSingleOp("group", expr_ptr),
|
.Grouping => |expr_ptr| printSingleOp("group", expr_ptr),
|
||||||
|
|
|
@ -10,22 +10,8 @@ fn sliceify(non_slice: ?[*]const u8) []const u8 {
|
||||||
pub const CompileError = error{
|
pub const CompileError = error{
|
||||||
LLVMError,
|
LLVMError,
|
||||||
EmitError,
|
EmitError,
|
||||||
TypeError,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Does not account for custom types e.g structs, better type resolution
|
|
||||||
/// should be found
|
|
||||||
fn basicTypeToLLVM(ret_type: []const u8) !llvm.LLVMTypeRef {
|
|
||||||
if (std.mem.eql(u8, ret_type, "i32")) {
|
|
||||||
return llvm.LLVMInt32Type();
|
|
||||||
} else if (std.mem.eql(u8, ret_type, "bool")) {
|
|
||||||
return llvm.LLVMInt1Type();
|
|
||||||
} else {
|
|
||||||
std.debug.warn("Invalid return type: {}\n", ret_type);
|
|
||||||
return CompileError.TypeError;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const Codegen = struct {
|
pub const Codegen = struct {
|
||||||
allocator: *std.mem.Allocator,
|
allocator: *std.mem.Allocator,
|
||||||
|
|
||||||
|
@ -55,32 +41,20 @@ pub const Codegen = struct {
|
||||||
var val_cstr = try std.cstr.addNullByte(self.allocator, val);
|
var val_cstr = try std.cstr.addNullByte(self.allocator, val);
|
||||||
break :blk2 llvm.LLVMConstRealOfString(llvm.LLVMDoubleType(), val_cstr.ptr);
|
break :blk2 llvm.LLVMConstRealOfString(llvm.LLVMDoubleType(), val_cstr.ptr);
|
||||||
},
|
},
|
||||||
.Bool => |val| blk2: {
|
|
||||||
if (val) {
|
|
||||||
break :blk2 llvm.LLVMConstInt(llvm.LLVMInt1Type(), 1, 1);
|
|
||||||
} else {
|
|
||||||
break :blk2 llvm.LLVMConstInt(llvm.LLVMInt1Type(), 0, 1);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
.Binary => |binary| {
|
.Binary => |binary| {
|
||||||
var left = try self.emitExpr(builder, binary.left);
|
var left = try self.emitExpr(builder, binary.left);
|
||||||
var right = try self.emitExpr(builder, binary.right);
|
var right = try self.emitExpr(builder, binary.right);
|
||||||
|
|
||||||
return switch (binary.op) {
|
return switch (binary.op.lexeme[0]) {
|
||||||
.Add => llvm.LLVMBuildAdd(builder, left, right, c"addtmp"),
|
// TODO other operators
|
||||||
.Sub => llvm.LLVMBuildSub(builder, left, right, c"subtmp"),
|
'+' => llvm.LLVMBuildAdd(builder, left, right, c"addtmp"),
|
||||||
.Mul => llvm.LLVMBuildMul(builder, left, right, c"multmp"),
|
|
||||||
|
|
||||||
//.Div => llvm.LLVMBuildDiv(builder, left, right, c"divtmp"),
|
|
||||||
.And => llvm.LLVMBuildAnd(builder, left, right, c"andtmp"),
|
|
||||||
.Or => llvm.LLVMBuildOr(builder, left, right, c"ortmp"),
|
|
||||||
|
|
||||||
|
// TODO codegen errors
|
||||||
else => {
|
else => {
|
||||||
std.debug.warn("Unexpected binary operator: '{}'\n", binary.op);
|
std.debug.warn("Unexpected binary operator: '{}'\n", binary.op.lexeme);
|
||||||
return CompileError.EmitError;
|
return CompileError.EmitError;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -120,24 +94,23 @@ pub const Codegen = struct {
|
||||||
const name_cstr = try std.cstr.addNullByte(self.allocator, name);
|
const name_cstr = try std.cstr.addNullByte(self.allocator, name);
|
||||||
errdefer self.allocator.free(name_cstr);
|
errdefer self.allocator.free(name_cstr);
|
||||||
|
|
||||||
const fn_ret_type = decl.return_type.lexeme;
|
//const ret_type = decl.return_type.lexeme;
|
||||||
|
|
||||||
var param_types = llvm.LLVMTypeList.init(self.allocator);
|
var param_types = llvm.LLVMTypeList.init(self.allocator);
|
||||||
errdefer param_types.deinit();
|
errdefer param_types.deinit();
|
||||||
|
|
||||||
for (decl.params.toSlice()) |param| {
|
for (decl.params.toSlice()) |param| {
|
||||||
// TODO better type resolution
|
try param_types.append(llvm.LLVMInt32Type());
|
||||||
try param_types.append(try basicTypeToLLVM(param.typ.lexeme));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var llvm_ret_type = llvm.LLVMFunctionType(
|
var ret_type = llvm.LLVMFunctionType(
|
||||||
try basicTypeToLLVM(fn_ret_type),
|
llvm.LLVMInt32Type(),
|
||||||
param_types.toSlice().ptr,
|
param_types.toSlice().ptr,
|
||||||
@intCast(c_uint, param_types.len),
|
@intCast(c_uint, param_types.len),
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
|
|
||||||
var func = llvm.LLVMAddFunction(mod, name_cstr.ptr, llvm_ret_type);
|
var func = llvm.LLVMAddFunction(mod, name_cstr.ptr, ret_type);
|
||||||
var entry = llvm.LLVMAppendBasicBlock(func, c"entry");
|
var entry = llvm.LLVMAppendBasicBlock(func, c"entry");
|
||||||
|
|
||||||
var builder = llvm.LLVMCreateBuilder();
|
var builder = llvm.LLVMCreateBuilder();
|
||||||
|
|
124
src/parsers.zig
124
src/parsers.zig
|
@ -11,10 +11,7 @@ const Scanner = scanners.Scanner;
|
||||||
const Token = tokens.Token;
|
const Token = tokens.Token;
|
||||||
const TokenType = tokens.TokenType;
|
const TokenType = tokens.TokenType;
|
||||||
|
|
||||||
pub const ParseError = error{
|
pub const ParseError = error{CompileError};
|
||||||
CompileError,
|
|
||||||
UnknownOperator,
|
|
||||||
};
|
|
||||||
|
|
||||||
const Node = ast.Node;
|
const Node = ast.Node;
|
||||||
const Expr = ast.Expr;
|
const Expr = ast.Expr;
|
||||||
|
@ -28,39 +25,6 @@ const FieldState = struct {
|
||||||
mutable_outside: bool = false,
|
mutable_outside: bool = false,
|
||||||
};
|
};
|
||||||
|
|
||||||
const operator_tokens = [_][]const u8{
|
|
||||||
"+", "-", "*", "/", "%", ">", ">=", "<", "<=", "==",
|
|
||||||
};
|
|
||||||
|
|
||||||
const operator_values = [_]ast.BinaryOperator{
|
|
||||||
.Add,
|
|
||||||
.Sub,
|
|
||||||
.Mul,
|
|
||||||
.Div,
|
|
||||||
.Mod,
|
|
||||||
|
|
||||||
.Greater,
|
|
||||||
.GreaterEqual,
|
|
||||||
.Less,
|
|
||||||
.LessEqual,
|
|
||||||
|
|
||||||
.Equal,
|
|
||||||
};
|
|
||||||
|
|
||||||
fn toBinaryOperator(op: Token) !ast.BinaryOperator {
|
|
||||||
const lex = op.lexeme;
|
|
||||||
|
|
||||||
inline for (operator_tokens) |op_str, idx| {
|
|
||||||
if (std.mem.eql(u8, lex, op_str)) return operator_values[idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
// special cases: && + and => .And and || + or => .Or
|
|
||||||
if (std.mem.eql(u8, lex, "&&") or std.mem.eql(u8, lex, "and")) return .And;
|
|
||||||
if (std.mem.eql(u8, lex, "||") or std.mem.eql(u8, lex, "or")) return .Or;
|
|
||||||
|
|
||||||
return ParseError.UnknownOperator;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const Parser = struct {
|
pub const Parser = struct {
|
||||||
allocator: *Allocator,
|
allocator: *Allocator,
|
||||||
scanner: *Scanner,
|
scanner: *Scanner,
|
||||||
|
@ -254,7 +218,7 @@ pub const Parser = struct {
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mkBinary(self: *Parser, left: *Expr, op: ast.BinaryOperator, right: *Expr) !*Expr {
|
fn mkBinary(self: *Parser, left: *Expr, op: Token, right: *Expr) !*Expr {
|
||||||
var expr = try self.allocator.create(Expr);
|
var expr = try self.allocator.create(Expr);
|
||||||
expr.* = Expr{
|
expr.* = Expr{
|
||||||
.Binary = ast.BinaryExpr{
|
.Binary = ast.BinaryExpr{
|
||||||
|
@ -267,6 +231,19 @@ pub const Parser = struct {
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mkLogical(self: *Parser, left: *Expr, op: Token, right: *Expr) !*Expr {
|
||||||
|
var expr = try self.allocator.create(Expr);
|
||||||
|
expr.* = Expr{
|
||||||
|
.Logical = ast.LogicalExpr{
|
||||||
|
.left = left,
|
||||||
|
.op = op,
|
||||||
|
.right = right,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
|
||||||
fn mkAssign(self: *Parser, name: Token, value: *Expr) !*Expr {
|
fn mkAssign(self: *Parser, name: Token, value: *Expr) !*Expr {
|
||||||
var expr = try self.allocator.create(Expr);
|
var expr = try self.allocator.create(Expr);
|
||||||
expr.* = Expr{
|
expr.* = Expr{
|
||||||
|
@ -845,41 +822,55 @@ pub const Parser = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn finishAssignment(self: *@This(), expr: *Expr, mutable: bool) !*Expr {
|
fn finishAssignment(self: *@This(), expr: *Expr, mutable: bool) !*Expr {
|
||||||
var op_tok = self.peek();
|
var op = self.peek();
|
||||||
_ = try self.nextToken();
|
_ = try self.nextToken();
|
||||||
|
|
||||||
var value = try self.parseAssignment();
|
var value = try self.parseAssignment();
|
||||||
|
|
||||||
// expr can be a (Variable|Set)
|
// TODO convert binary's op field from Token to
|
||||||
// op_tok can be one of three categories:
|
// something else, maybe enum'd
|
||||||
// - ColonEqual, parses to VarDecl (only when expr = Variable)
|
|
||||||
// - Equal, parses to (Assign|Set)
|
|
||||||
// - Inplace (+=, -=, *=, /=), parses to (Assign|Set)
|
|
||||||
|
|
||||||
// however, when dealing with inplace operators, we want those to parse
|
const new_op_ttype: TokenType = switch (op.typ) {
|
||||||
// to an assign/set with a binary expression with the undelying operator
|
.ColonEqual => TokenType.ColonEqual,
|
||||||
// instead of the infix operator.
|
.Equal => .Equal,
|
||||||
// e.g 'x += 1' parses down to 'x = x + 1'
|
|
||||||
|
|
||||||
// TODO do we add %=?
|
.PlusEqual => .Plus,
|
||||||
const binop: ?ast.BinaryOperator = switch (op_tok.typ) {
|
.MinusEqual => .Minus,
|
||||||
.PlusEqual => ast.BinaryOperator.Add,
|
.StarEqual => .Star,
|
||||||
.MinusEqual => .Sub,
|
.SlashEqual => .Slash,
|
||||||
.StarEqual => .Mul,
|
|
||||||
.SlashEqual => .Div,
|
else => unreachable,
|
||||||
else => null,
|
};
|
||||||
|
|
||||||
|
// we create new_lexeme so that
|
||||||
|
// the AST printer properly prints
|
||||||
|
// x += 1
|
||||||
|
// as
|
||||||
|
// (set x (+ x 1))
|
||||||
|
// and not
|
||||||
|
// (set x (+= x 1))
|
||||||
|
const new_lexeme: []const u8 = switch (op.typ) {
|
||||||
|
.ColonEqual => ":=",
|
||||||
|
.Equal => "=",
|
||||||
|
|
||||||
|
.PlusEqual => "+",
|
||||||
|
.MinusEqual => "-",
|
||||||
|
.StarEqual => "*",
|
||||||
|
.SlashEqual => "/",
|
||||||
|
|
||||||
|
else => unreachable,
|
||||||
};
|
};
|
||||||
|
|
||||||
switch (expr.*) {
|
switch (expr.*) {
|
||||||
.Variable => {
|
.Variable => {
|
||||||
switch (op_tok.typ) {
|
switch (op.typ) {
|
||||||
.ColonEqual => return try self.mkVarDecl(expr.Variable, value, mutable),
|
.ColonEqual => return try self.mkVarDecl(expr.Variable, value, mutable),
|
||||||
.Equal => return try self.mkAssign(expr.Variable, value),
|
.Equal => return try self.mkAssign(expr.Variable, value),
|
||||||
|
|
||||||
.PlusEqual, .MinusEqual, .StarEqual, .SlashEqual => {
|
.PlusEqual, .MinusEqual, .StarEqual, .SlashEqual => {
|
||||||
|
var new_op = try self.mkToken(new_op_ttype, new_lexeme, op.line);
|
||||||
return try self.mkAssign(
|
return try self.mkAssign(
|
||||||
expr.Variable,
|
expr.Variable,
|
||||||
try self.mkBinary(expr, binop.?, value),
|
try self.mkBinary(expr, new_op, value),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -888,7 +879,7 @@ pub const Parser = struct {
|
||||||
},
|
},
|
||||||
|
|
||||||
.Get => |get| {
|
.Get => |get| {
|
||||||
switch (op_tok.typ) {
|
switch (op.typ) {
|
||||||
.ColonEqual => {
|
.ColonEqual => {
|
||||||
return self.doError("can not initialize struct field");
|
return self.doError("can not initialize struct field");
|
||||||
},
|
},
|
||||||
|
@ -896,10 +887,11 @@ pub const Parser = struct {
|
||||||
.Equal => return try self.mkSet(get.struc, get.name, value),
|
.Equal => return try self.mkSet(get.struc, get.name, value),
|
||||||
|
|
||||||
.PlusEqual, .MinusEqual, .StarEqual, .SlashEqual => {
|
.PlusEqual, .MinusEqual, .StarEqual, .SlashEqual => {
|
||||||
|
var new_op = try self.mkToken(new_op_ttype, new_lexeme, op.line);
|
||||||
return try self.mkSet(
|
return try self.mkSet(
|
||||||
get.struc,
|
get.struc,
|
||||||
get.name,
|
get.name,
|
||||||
try self.mkBinary(expr, binop.?, value),
|
try self.mkBinary(expr, new_op, value),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -921,7 +913,7 @@ pub const Parser = struct {
|
||||||
_ = try self.nextToken();
|
_ = try self.nextToken();
|
||||||
|
|
||||||
var right = try self.parseAnd();
|
var right = try self.parseAnd();
|
||||||
expr = try self.mkBinary(expr, try toBinaryOperator(op), right);
|
expr = try self.mkLogical(expr, op, right);
|
||||||
}
|
}
|
||||||
|
|
||||||
return expr;
|
return expr;
|
||||||
|
@ -935,7 +927,7 @@ pub const Parser = struct {
|
||||||
_ = try self.nextToken();
|
_ = try self.nextToken();
|
||||||
|
|
||||||
var right = try self.parseEquality();
|
var right = try self.parseEquality();
|
||||||
expr = try self.mkBinary(expr, try toBinaryOperator(op), right);
|
expr = try self.mkLogical(expr, op, right);
|
||||||
}
|
}
|
||||||
|
|
||||||
return expr;
|
return expr;
|
||||||
|
@ -949,7 +941,7 @@ pub const Parser = struct {
|
||||||
_ = try self.nextToken();
|
_ = try self.nextToken();
|
||||||
|
|
||||||
var right = try self.parseComparison();
|
var right = try self.parseComparison();
|
||||||
expr = try self.mkBinary(expr, .Equal, right);
|
expr = try self.mkBinary(expr, op, right);
|
||||||
}
|
}
|
||||||
|
|
||||||
return expr;
|
return expr;
|
||||||
|
@ -968,7 +960,7 @@ pub const Parser = struct {
|
||||||
_ = try self.nextToken();
|
_ = try self.nextToken();
|
||||||
|
|
||||||
var right = try self.parseAddition();
|
var right = try self.parseAddition();
|
||||||
expr = try self.mkBinary(expr, try toBinaryOperator(op), right);
|
expr = try self.mkBinary(expr, op, right);
|
||||||
}
|
}
|
||||||
|
|
||||||
return expr;
|
return expr;
|
||||||
|
@ -984,7 +976,7 @@ pub const Parser = struct {
|
||||||
_ = try self.nextToken();
|
_ = try self.nextToken();
|
||||||
|
|
||||||
var right = try self.parseMultiplication();
|
var right = try self.parseMultiplication();
|
||||||
expr = try self.mkBinary(expr, try toBinaryOperator(op), right);
|
expr = try self.mkBinary(expr, op, right);
|
||||||
}
|
}
|
||||||
|
|
||||||
return expr;
|
return expr;
|
||||||
|
@ -1000,7 +992,7 @@ pub const Parser = struct {
|
||||||
_ = try self.nextToken();
|
_ = try self.nextToken();
|
||||||
var right = try self.parseUnary();
|
var right = try self.parseUnary();
|
||||||
|
|
||||||
expr = try self.mkBinary(expr, try toBinaryOperator(op), right);
|
expr = try self.mkBinary(expr, op, right);
|
||||||
}
|
}
|
||||||
|
|
||||||
return expr;
|
return expr;
|
||||||
|
|
|
@ -52,8 +52,6 @@ const keywords = [_][]const u8{
|
||||||
"println",
|
"println",
|
||||||
"loop",
|
"loop",
|
||||||
"pub",
|
"pub",
|
||||||
"and",
|
|
||||||
"or",
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const keyword_ttypes = [_]TokenType{
|
const keyword_ttypes = [_]TokenType{
|
||||||
|
@ -84,8 +82,6 @@ const keyword_ttypes = [_]TokenType{
|
||||||
.Println,
|
.Println,
|
||||||
.Loop,
|
.Loop,
|
||||||
.Pub,
|
.Pub,
|
||||||
.And,
|
|
||||||
.Or,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
fn getKeyword(keyword: []const u8) ?TokenType {
|
fn getKeyword(keyword: []const u8) ?TokenType {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue