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 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 {

View File

@ -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)}"'))

View File

@ -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
}
}

View File

@ -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<int>()
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()