From 6f7628cb67990c61a897e1432b8f38da79df0874 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Wed, 27 May 2020 03:20:22 +0200 Subject: [PATCH] parser: comptime call fixes --- vlib/v/ast/ast.v | 39 ++++++++++++++++++++------------------- vlib/v/gen/js/js.v | 6 +++--- vlib/v/parser/comptime.v | 18 +++++++++++++----- vlib/v/parser/parser.v | 17 ++++++++++++++--- 4 files changed, 50 insertions(+), 30 deletions(-) diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 2580c495a3..8c62460d79 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -10,15 +10,15 @@ import v.errors pub type TypeDecl = AliasTypeDecl | FnTypeDecl | SumTypeDecl pub type Expr = AnonFn | ArrayInit | AsCast | AssignExpr | Assoc | BoolLiteral | CallExpr | - CastExpr | CharLiteral | ConcatExpr | EnumVal | FloatLiteral | Ident | IfExpr | IfGuardExpr | - IndexExpr | InfixExpr | IntegerLiteral | MapInit | MatchExpr | None | OrExpr | ParExpr | PostfixExpr | - PrefixExpr | RangeExpr | SelectorExpr | SizeOf | StringInterLiteral | StringLiteral | StructInit | - Type | TypeOf + CastExpr | CharLiteral | ComptimeCall | ConcatExpr | EnumVal | FloatLiteral | Ident | IfExpr | + IfGuardExpr | IndexExpr | InfixExpr | IntegerLiteral | MapInit | MatchExpr | None | OrExpr | + ParExpr | PostfixExpr | PrefixExpr | RangeExpr | SelectorExpr | SizeOf | StringInterLiteral | + StringLiteral | StructInit | Type | TypeOf -pub type Stmt = AssertStmt | AssignStmt | Attr | Block | BranchStmt | Comment | CompIf | ComptimeCall | - ConstDecl | DeferStmt | EnumDecl | ExprStmt | FnDecl | ForCStmt | ForInStmt | ForStmt | GlobalDecl | - GoStmt | GotoLabel | GotoStmt | HashStmt | Import | InterfaceDecl | Module | Return | StructDecl | - TypeDecl | UnsafeStmt +pub type Stmt = AssertStmt | AssignStmt | Attr | Block | BranchStmt | Comment | CompIf | ConstDecl | + DeferStmt | EnumDecl | ExprStmt | FnDecl | ForCStmt | ForInStmt | ForStmt | GlobalDecl | GoStmt | + GotoLabel | GotoStmt | HashStmt | Import | InterfaceDecl | Module | Return | StructDecl | TypeDecl | + UnsafeStmt pub type ScopeObject = ConstField | GlobalDecl | Var @@ -530,14 +530,14 @@ pub: pub struct AssignStmt { pub: - right []Expr - op token.Kind - pos token.Position + right []Expr + op token.Kind + pos token.Position pub mut: - left []Ident - left_types []table.Type - right_types []table.Type - is_static bool // for translated code only + left []Ident + left_types []table.Type + right_types []table.Type + is_static bool // for translated code only has_cross_var bool } @@ -576,11 +576,11 @@ pub: pub struct EnumDecl { pub: - name string - is_pub bool + name string + is_pub bool is_flag bool // true when the enum has [flag] tag - fields []EnumField - pos token.Position + fields []EnumField + pos token.Position } pub struct AliasTypeDecl { @@ -776,6 +776,7 @@ pub mut: pub struct ComptimeCall { name string + left Expr } pub struct None { diff --git a/vlib/v/gen/js/js.v b/vlib/v/gen/js/js.v index 12c8a0ac86..7555ca1c4a 100644 --- a/vlib/v/gen/js/js.v +++ b/vlib/v/gen/js/js.v @@ -402,9 +402,6 @@ fn (mut g JsGen) stmt(node ast.Stmt) { ast.CompIf { // skip: JS has no compile time if } - ast.ComptimeCall { - // TODO - } ast.ConstDecl { g.gen_const_decl(it) } @@ -595,6 +592,9 @@ fn (mut g JsGen) expr(node ast.Expr) { g.gen_typeof_expr(it) // TODO: Should this print the V type or the JS type? } + ast.ComptimeCall { + // TODO + } /* else { println(term.red('jsgen.expr(): unhandled node "${typeof(node)}"')) diff --git a/vlib/v/parser/comptime.v b/vlib/v/parser/comptime.v index 512c33be32..645ed4a6c6 100644 --- a/vlib/v/parser/comptime.v +++ b/vlib/v/parser/comptime.v @@ -66,9 +66,9 @@ fn (mut p Parser) vweb() ast.ComptimeCall { fn (mut p Parser) comp_if() ast.Stmt { pos := p.tok.position() p.next() - if p.tok.kind == .name && p.tok.lit == 'vweb' { - return p.vweb() - } + // if p.tok.kind == .name && p.tok.lit == 'vweb' { + // return p.vweb() + // } p.check(.key_if) is_not := p.tok.kind == .not if is_not { @@ -191,11 +191,14 @@ fn os_from_string(os string) pref.OS { return .linux } -// `user.$method()` (`method` is a string) -fn (mut p Parser) comptime_method_call(typ table.Type) { +// `app.$action()` (`action` is a string) +// `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) method_name := p.check_name() _ = method_name + /* mut j := 0 sym := p.table.get_type_symbol(typ) if sym.kind != .struct_ { @@ -219,6 +222,7 @@ fn (mut p Parser) comptime_method_call(typ table.Type) { */ j++ } + */ p.check(.lpar) p.check(.rpar) if p.tok.kind == .key_orelse { @@ -227,4 +231,8 @@ fn (mut p Parser) comptime_method_call(typ table.Type) { p.check(.lcbr) // p.statements() } + return ast.ComptimeCall{ + left: left + name: method_name + } } diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index ab3301f098..60c4e2862e 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -386,7 +386,13 @@ pub fn (mut p Parser) top_stmt() ast.Stmt { return p.struct_decl() } .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 { 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()') // 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() mut name := p.tok.lit 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 { p.next() + if p.tok.kind == .dollar { + return p.comptime_method_call(left) + } mut name_pos := p.tok.position() field_name := p.check_name() is_filter := field_name in ['filter', 'map'] @@ -1244,7 +1254,8 @@ fn (mut p Parser) const_decl() ast.ConstDecl { pos := p.tok.position() name := p.check_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) // name := p.check_name()