Compare commits

...

3 Commits

Author SHA1 Message Date
Luna 9869cca2ae remove mutability/publicability
i may implement those in a better way, which isn't V's
2019-09-28 18:09:58 -03:00
Luna c7920246a5 codegen: add emitting of unary exprs 2019-09-28 17:58:17 -03:00
Luna 3d47c0cca8 parser: fix unary operators causing stack overflow 2019-09-28 17:52:30 -03:00
6 changed files with 26 additions and 116 deletions

View File

@ -36,11 +36,14 @@ fn func_refer_param(b: i32) i32 {
}
fn multwo(num: i32, double_flag: bool) i32 {
if (!double_flag) {
var value = 32;
return value;
}
if (double_flag) {
var truthy = true;
return num * 2;
} else {
var falsey = false;
return num;
}
}

View File

@ -214,9 +214,9 @@ pub const TypeSolver = struct {
};
},
// for now, unary operators only have .Not
.Unary => |unary| {
var right_type = try self.resolveExprType(ctx, unary.right);
return switch (unary.op) {
.Negate => right_type,
.Not => right_type,

View File

@ -29,7 +29,6 @@ pub const ParamDecl = struct {
pub const MethodData = struct {
variable: Token,
typ: Token,
mutable: bool,
};
pub const FnDecl = struct {
@ -288,10 +287,6 @@ pub const FieldList = std.ArrayList(StructField);
pub const StructField = struct {
name: Token,
typ: Token,
mutable: bool = false,
public: bool = false,
mutable_outside: bool = false,
};
pub const Struct = struct {

View File

@ -48,11 +48,7 @@ pub fn printNode(node: *const Node, ident: usize) void {
const vari = method.variable.lexeme;
const typ = method.typ.lexeme;
if (method.mutable) {
warn("(method mut {} {} {} {} (", vari, typ, name, ret_type);
} else {
warn("(method {} {} {} {} (", vari, typ, name, ret_type);
}
warn("(method {} {} {} {} (", vari, typ, name, ret_type);
} else {
warn("(fn {} {} (", name, ret_type);
}
@ -112,22 +108,7 @@ pub fn printNode(node: *const Node, ident: usize) void {
.Struct => |struc| {
print(ident, "(struct {} (\n", struc.name.lexeme);
for (struc.fields.toSlice()) |field| {
printIdent(ident + 1);
if (field.mutable) {
std.debug.warn("(mut ");
} else {
std.debug.warn("(");
}
if (field.public) {
std.debug.warn("pub ");
}
if (field.mutable_outside) {
std.debug.warn("MUT_OUT ");
}
std.debug.warn("{} {})\n", field.name.lexeme, field.typ.lexeme);
print(ident + 1, "({} {})\n", field.name.lexeme, field.typ.lexeme);
}
print(ident, "))\n");
},

View File

@ -132,6 +132,15 @@ pub const Codegen = struct {
};
},
.Unary => |unary| {
var right = try self.emitExpr(builder, unary.right);
return switch (unary.op) {
.Negate => llvm.LLVMBuildNeg(builder, right, c"neg_tmp"),
.Not => llvm.LLVMBuildNot(builder, right, c"neg_tmp"),
};
},
.Binary => |binary| {
var left = try self.emitExpr(builder, binary.left);
var right = try self.emitExpr(builder, binary.right);

View File

@ -23,12 +23,6 @@ const Stmt = ast.Stmt;
const TokenList = std.ArrayList(Token);
const FieldState = struct {
public: bool = false,
mutable: bool = false,
mutable_outside: bool = false,
};
const operator_tokens = [_][]const u8{
"+", "-", "*", "/", "%", ">", ">=", "<", "<=", "==",
};
@ -511,19 +505,12 @@ pub const Parser = struct {
);
}
/// parse the (v [mut] T) part of the method (defined here
/// parse the (v T) part of the method (defined here
/// as a premethod)
fn parsePreMethod(self: *@This()) !?*ast.MethodData {
_ = try self.consumeSingle(.LeftParen);
var mutable_ref: bool = false;
const variable = try self.consumeSingle(.Identifier);
if (self.check(.Mut)) {
_ = try self.consumeSingle(.Mut);
mutable_ref = true;
}
const typ = try self.consumeSingle(.Identifier);
_ = try self.consumeSingle(.RightParen);
@ -533,7 +520,6 @@ pub const Parser = struct {
method.* = ast.MethodData{
.variable = variable,
.typ = typ,
.mutable = mutable_ref,
};
return method;
@ -581,27 +567,14 @@ pub const Parser = struct {
_ = try self.consumeSingle(.LeftBrace);
var field_state = FieldState{};
while (!self.check(.RightBrace)) {
try self.parseFieldModifiers(&field_state);
const field_name = try self.consumeSingle(.Identifier);
self.setErrContext("struct {} field {}", name, field_name);
const field_type = try self.consumeSingle(.Identifier);
// we could create a FieldState on the heap and copy our current
// field state into a StructField.state, but copying via this makes
// things so much nicer.
try fields.append(ast.StructField{
.name = field_name,
.typ = field_type,
.mutable = field_state.mutable,
.public = field_state.public,
.mutable_outside = field_state.mutable_outside,
});
}
@ -610,51 +583,6 @@ pub const Parser = struct {
return Node.mkStructDecl(self.allocator, name, fields);
}
fn parseFieldModifiers(self: *@This(), field_state: *FieldState) !void {
// there are five access modifiers:
// - none (private immutable)
// - mut (private mutable)
// - pub (public immutable)
// - pub mut (public mutable only in module)
// - pub mut mut (public mutable everywhere)
// this function takes care of that by changing the current FieldState
// to what the modifiers dictate.
switch (self.peek().typ) {
.Mut => {
// There are no oher modifiers that start with mut, so we
// can just go the way of marking it as mutable
_ = try self.consumeSingle(.Mut);
_ = try self.consumeSingle(.Colon);
field_state.mutable = true;
},
// 'pub', 'pub mut', and 'pub mut mut' are all handled here
.Pub => {
_ = try self.consumeSingle(.Pub);
field_state.public = true;
if (self.check(.Mut)) {
_ = try self.consumeSingle(.Mut);
field_state.mutable = true;
if (self.check(.Mut)) {
_ = try self.consumeSingle(.Mut);
field_state.mutable_outside = true;
}
}
_ = try self.consumeSingle(.Colon);
},
// if it isn't mut or pub we're likely in an identifier, just
// ignore it.
else => return,
}
}
fn parseEnumDecl(self: *@This()) !*Node {
var fields = ast.TokenList.init(self.allocator);
errdefer fields.deinit();
@ -848,29 +776,22 @@ pub const Parser = struct {
// there can be two assignments coming out of this function:
// - an assignment to a variable with =
// - an update to a variable with +=, -=
// one is a statement, other is an expression. since the normal result
// of this is an Expr, we wrap variable assignments in an Expr as well.
var mutable: bool = false;
if (self.check(.Mut)) {
_ = try self.consumeSingle(.Mut);
mutable = true;
}
var expr = try self.parseOr();
if (self.compareAnyOf(&[_]TokenType{
.Equal, .PlusEqual, .MinusEqual, .StarEqual,
.SlashEqual,
})) {
return try self.finishAssignment(expr, mutable);
return try self.finishAssignment(expr);
}
return expr;
}
fn finishAssignment(self: *@This(), expr: *Expr, mutable: bool) !*Expr {
fn finishAssignment(
self: *@This(),
expr: *Expr,
) !*Expr {
var op_tok = self.peek();
_ = try self.nextToken();
@ -1033,8 +954,9 @@ pub const Parser = struct {
fn parseUnary(self: *@This()) anyerror!*Expr {
if (self.compareAnyOf(&[_]TokenType{ .Bang, .Minus })) {
var op = self.previous();
var right = try self.parseUnary();
var op = self.peek();
_ = try self.nextToken();
var right = try self.parseCall();
return try self.mkUnary(try toUnaryOperator(op), right);
}