parser: comptime call fixes

pull/4971/head
Alexander Medvednikov 2020-05-27 03:20:22 +02:00
parent b02ec8cbf9
commit 6f7628cb67
4 changed files with 50 additions and 30 deletions

View File

@ -10,15 +10,15 @@ import v.errors
pub type TypeDecl = AliasTypeDecl | FnTypeDecl | SumTypeDecl pub type TypeDecl = AliasTypeDecl | FnTypeDecl | SumTypeDecl
pub type Expr = AnonFn | ArrayInit | AsCast | AssignExpr | Assoc | BoolLiteral | CallExpr | pub type Expr = AnonFn | ArrayInit | AsCast | AssignExpr | Assoc | BoolLiteral | CallExpr |
CastExpr | CharLiteral | ConcatExpr | EnumVal | FloatLiteral | Ident | IfExpr | IfGuardExpr | CastExpr | CharLiteral | ComptimeCall | ConcatExpr | EnumVal | FloatLiteral | Ident | IfExpr |
IndexExpr | InfixExpr | IntegerLiteral | MapInit | MatchExpr | None | OrExpr | ParExpr | PostfixExpr | IfGuardExpr | IndexExpr | InfixExpr | IntegerLiteral | MapInit | MatchExpr | None | OrExpr |
PrefixExpr | RangeExpr | SelectorExpr | SizeOf | StringInterLiteral | StringLiteral | StructInit | ParExpr | PostfixExpr | PrefixExpr | RangeExpr | SelectorExpr | SizeOf | StringInterLiteral |
Type | TypeOf StringLiteral | StructInit | Type | TypeOf
pub type Stmt = AssertStmt | AssignStmt | Attr | Block | BranchStmt | Comment | CompIf | ComptimeCall | pub type Stmt = AssertStmt | AssignStmt | Attr | Block | BranchStmt | Comment | CompIf | ConstDecl |
ConstDecl | DeferStmt | EnumDecl | ExprStmt | FnDecl | ForCStmt | ForInStmt | ForStmt | GlobalDecl | DeferStmt | EnumDecl | ExprStmt | FnDecl | ForCStmt | ForInStmt | ForStmt | GlobalDecl | GoStmt |
GoStmt | GotoLabel | GotoStmt | HashStmt | Import | InterfaceDecl | Module | Return | StructDecl | GotoLabel | GotoStmt | HashStmt | Import | InterfaceDecl | Module | Return | StructDecl | TypeDecl |
TypeDecl | UnsafeStmt UnsafeStmt
pub type ScopeObject = ConstField | GlobalDecl | Var pub type ScopeObject = ConstField | GlobalDecl | Var
@ -530,14 +530,14 @@ pub:
pub struct AssignStmt { pub struct AssignStmt {
pub: pub:
right []Expr right []Expr
op token.Kind op token.Kind
pos token.Position pos token.Position
pub mut: pub mut:
left []Ident left []Ident
left_types []table.Type left_types []table.Type
right_types []table.Type right_types []table.Type
is_static bool // for translated code only is_static bool // for translated code only
has_cross_var bool has_cross_var bool
} }
@ -576,11 +576,11 @@ pub:
pub struct EnumDecl { pub struct EnumDecl {
pub: pub:
name string name string
is_pub bool is_pub bool
is_flag bool // true when the enum has [flag] tag is_flag bool // true when the enum has [flag] tag
fields []EnumField fields []EnumField
pos token.Position pos token.Position
} }
pub struct AliasTypeDecl { pub struct AliasTypeDecl {
@ -776,6 +776,7 @@ pub mut:
pub struct ComptimeCall { pub struct ComptimeCall {
name string name string
left Expr
} }
pub struct None { pub struct None {

View File

@ -402,9 +402,6 @@ fn (mut g JsGen) stmt(node ast.Stmt) {
ast.CompIf { ast.CompIf {
// skip: JS has no compile time if // skip: JS has no compile time if
} }
ast.ComptimeCall {
// TODO
}
ast.ConstDecl { ast.ConstDecl {
g.gen_const_decl(it) g.gen_const_decl(it)
} }
@ -595,6 +592,9 @@ fn (mut g JsGen) expr(node ast.Expr) {
g.gen_typeof_expr(it) g.gen_typeof_expr(it)
// TODO: Should this print the V type or the JS type? // TODO: Should this print the V type or the JS type?
} }
ast.ComptimeCall {
// TODO
}
/* /*
else { else {
println(term.red('jsgen.expr(): unhandled node "${typeof(node)}"')) println(term.red('jsgen.expr(): unhandled node "${typeof(node)}"'))

View File

@ -66,9 +66,9 @@ fn (mut p Parser) vweb() ast.ComptimeCall {
fn (mut p Parser) comp_if() ast.Stmt { fn (mut p Parser) comp_if() ast.Stmt {
pos := p.tok.position() pos := p.tok.position()
p.next() p.next()
if p.tok.kind == .name && p.tok.lit == 'vweb' { // if p.tok.kind == .name && p.tok.lit == 'vweb' {
return p.vweb() // return p.vweb()
} // }
p.check(.key_if) p.check(.key_if)
is_not := p.tok.kind == .not is_not := p.tok.kind == .not
if is_not { if is_not {
@ -191,11 +191,14 @@ fn os_from_string(os string) pref.OS {
return .linux return .linux
} }
// `user.$method()` (`method` is a string) // `app.$action()` (`action` is a string)
fn (mut p Parser) comptime_method_call(typ table.Type) { // `typ` is `App` in this example
// fn (mut p Parser) comptime_method_call(typ table.Type) ast.ComptimeCall {
fn (mut p Parser) comptime_method_call(left ast.Expr) ast.ComptimeCall {
p.check(.dollar) p.check(.dollar)
method_name := p.check_name() method_name := p.check_name()
_ = method_name _ = method_name
/*
mut j := 0 mut j := 0
sym := p.table.get_type_symbol(typ) sym := p.table.get_type_symbol(typ)
if sym.kind != .struct_ { if sym.kind != .struct_ {
@ -219,6 +222,7 @@ fn (mut p Parser) comptime_method_call(typ table.Type) {
*/ */
j++ j++
} }
*/
p.check(.lpar) p.check(.lpar)
p.check(.rpar) p.check(.rpar)
if p.tok.kind == .key_orelse { if p.tok.kind == .key_orelse {
@ -227,4 +231,8 @@ fn (mut p Parser) comptime_method_call(typ table.Type) {
p.check(.lcbr) p.check(.lcbr)
// p.statements() // p.statements()
} }
return ast.ComptimeCall{
left: left
name: method_name
}
} }

View File

@ -386,7 +386,13 @@ pub fn (mut p Parser) top_stmt() ast.Stmt {
return p.struct_decl() return p.struct_decl()
} }
.dollar { .dollar {
return p.comp_if() if p.peek_tok.kind == .key_if {
return p.comp_if()
} else if p.peek_tok.kind == .name {
return ast.ExprStmt{
expr: p.vweb()
}
}
} }
.hash { .hash {
return p.hash() return p.hash()
@ -827,7 +833,8 @@ pub fn (mut p Parser) name_expr() ast.Expr {
} }
// p.warn('name expr $p.tok.lit $p.peek_tok.str()') // p.warn('name expr $p.tok.lit $p.peek_tok.str()')
// fn call or type cast // fn call or type cast
if p.peek_tok.kind == .lpar || (p.peek_tok.kind == .lt && p.peek_tok2.kind == .name && p.peek_tok3.kind == .gt ){ if p.peek_tok.kind == .lpar || (p.peek_tok.kind == .lt && p.peek_tok2.kind == .name &&
p.peek_tok3.kind == .gt) {
// foo() or foo<int>() // foo() or foo<int>()
mut name := p.tok.lit mut name := p.tok.lit
if mod.len > 0 { if mod.len > 0 {
@ -966,6 +973,9 @@ fn (mut p Parser) scope_register_it() {
fn (mut p Parser) dot_expr(left ast.Expr) ast.Expr { fn (mut p Parser) dot_expr(left ast.Expr) ast.Expr {
p.next() p.next()
if p.tok.kind == .dollar {
return p.comptime_method_call(left)
}
mut name_pos := p.tok.position() mut name_pos := p.tok.position()
field_name := p.check_name() field_name := p.check_name()
is_filter := field_name in ['filter', 'map'] is_filter := field_name in ['filter', 'map']
@ -1244,7 +1254,8 @@ fn (mut p Parser) const_decl() ast.ConstDecl {
pos := p.tok.position() pos := p.tok.position()
name := p.check_name() name := p.check_name()
if util.contains_capital(name) { if util.contains_capital(name) {
p.warn_with_pos('const names cannot contain uppercase letters, use snake_case instead', pos) p.warn_with_pos('const names cannot contain uppercase letters, use snake_case instead',
pos)
} }
full_name := p.prepend_mod(name) full_name := p.prepend_mod(name)
// name := p.check_name() // name := p.check_name()