Compare commits

...

4 Commits

Author SHA1 Message Date
Luna ac5d29819c split access modifier parsing into own func
- revamp parsing of access modifiers so it is correct
2019-08-26 21:43:58 -03:00
Luna 96d48f8762 tokens: add pub TokenType 2019-08-26 21:32:10 -03:00
Luna fc4b84b51c scanner: add pub keyword 2019-08-26 21:31:57 -03:00
Luna a706f077cb add pub/mut modifiers to struct fields 2019-08-26 21:31:01 -03:00
6 changed files with 87 additions and 5 deletions

View File

@ -54,3 +54,16 @@ fn main(a int) int {
}
fn (v Typ) voidfunc() {}
struct Foo {
a int
mut:
b int
c int
pub:
d int
pub mut:
e int
pub mut mut:
f int
}

View File

@ -227,8 +227,10 @@ pub const FieldList = std.ArrayList(StructField);
pub const StructField = struct {
name: Token,
typ: Token,
mutable: bool = true,
public: bool = true,
mutable: bool = false,
public: bool = false,
mutable_outside: bool = false,
};
pub const Struct = struct {

View File

@ -107,6 +107,10 @@ pub fn printNode(node: *Node, ident: usize) void {
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, "))\n");

View File

@ -18,6 +18,12 @@ const Stmt = ast.Stmt;
const TokenList = std.ArrayList(Token);
const FieldState = struct {
public: bool = false,
mutable: bool = false,
mutable_outside: bool = false,
};
pub const Parser = struct {
allocator: *Allocator,
scanner: *Scanner,
@ -405,8 +411,6 @@ pub const Parser = struct {
while (self.peek().ttype != .RightParen) {
const param_name = try self.consumeSingle(.Identifier);
// TODO dedicated function to consume a type?
const param_type = try self.consumeSingle(.Identifier);
try param_list.append(ast.ParamDecl{
@ -495,14 +499,25 @@ pub const Parser = struct {
_ = try self.consumeSingle(.LeftBrace);
var field_state = FieldState{};
while (!self.check(.RightBrace)) {
// TODO mut and pub
try self.parseFieldModifiers(&field_state);
const field_name = try self.consumeSingle(.Identifier);
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,
});
}
@ -511,6 +526,51 @@ 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().ttype) {
.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 parseTopDecl(self: *@This()) !*Node {
return switch (self.peek().ttype) {
.Fn => try self.parseFnDecl(),

View File

@ -51,6 +51,7 @@ const keywords = [_][]const u8{
"None",
"println",
"loop",
"pub",
};
const keyword_ttypes = [_]TokenType{
@ -80,6 +81,7 @@ const keyword_ttypes = [_]TokenType{
.None,
.Println,
.Loop,
.Pub,
};
fn getKeyword(keyword: []const u8) ?TokenType {

View File

@ -75,6 +75,7 @@ pub const TokenType = enum {
None,
Println,
Pub,
EOF,
};