mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
v2: consts, $if, attributes, globals, if/for type check, prefs
This commit is contained in:
@@ -50,7 +50,7 @@ pub fn (p mut Parser) call_args() []ast.Expr {
|
||||
return args // ,table.void_ti
|
||||
}
|
||||
|
||||
fn (p mut Parser) fn_decl() ast.FnDecl {
|
||||
fn (p mut Parser) fn_decl(/*high bool*/) ast.FnDecl {
|
||||
is_pub := p.tok.kind == .key_pub
|
||||
if is_pub {
|
||||
p.next()
|
||||
@@ -68,14 +68,18 @@ fn (p mut Parser) fn_decl() ast.FnDecl {
|
||||
if p.tok.kind == .key_mut {
|
||||
p.next()
|
||||
}
|
||||
rec_ti = p.parse_ti()
|
||||
rec_ti = p.parse_type()
|
||||
p.table.register_var(table.Var{
|
||||
name: rec_name
|
||||
typ: rec_ti
|
||||
})
|
||||
p.check(.rpar)
|
||||
}
|
||||
name := p.check_name()
|
||||
mut name := ''
|
||||
if p.tok.kind == .name {
|
||||
// TODO
|
||||
name = p.check_name()
|
||||
}
|
||||
// println('fn decl $name')
|
||||
p.check(.lpar)
|
||||
// Args
|
||||
@@ -88,7 +92,7 @@ fn (p mut Parser) fn_decl() ast.FnDecl {
|
||||
p.check(.comma)
|
||||
arg_names << p.check_name()
|
||||
}
|
||||
ti := p.parse_ti()
|
||||
ti := p.parse_type()
|
||||
for arg_name in arg_names {
|
||||
arg := table.Var{
|
||||
name: arg_name
|
||||
@@ -112,7 +116,7 @@ fn (p mut Parser) fn_decl() ast.FnDecl {
|
||||
// Return type
|
||||
mut typ := table.void_type
|
||||
if p.tok.kind in [.name, .lpar] {
|
||||
typ = p.parse_ti()
|
||||
typ = p.parse_type()
|
||||
p.return_type = typ
|
||||
}
|
||||
else {
|
||||
@@ -144,7 +148,7 @@ fn (p mut Parser) fn_decl() ast.FnDecl {
|
||||
is_pub: is_pub
|
||||
receiver: ast.Field{
|
||||
name: rec_name
|
||||
ti: rec_ti
|
||||
typ: rec_ti
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,13 +13,13 @@ pub fn (p mut Parser) parse_array_ti(nr_muls int) table.Type {
|
||||
if p.tok.kind == .number {
|
||||
size := p.tok.lit.int()
|
||||
p.check(.rsbr)
|
||||
elem_ti := p.parse_ti()
|
||||
elem_ti := p.parse_type()
|
||||
idx,name := p.table.find_or_register_array_fixed(&elem_ti, size, 1)
|
||||
return table.new_type(.array_fixed, name, idx, nr_muls)
|
||||
}
|
||||
// array
|
||||
p.check(.rsbr)
|
||||
elem_ti := p.parse_ti()
|
||||
elem_ti := p.parse_type()
|
||||
mut nr_dims := 1
|
||||
for p.tok.kind == .lsbr {
|
||||
p.check(.lsbr)
|
||||
@@ -33,9 +33,9 @@ pub fn (p mut Parser) parse_array_ti(nr_muls int) table.Type {
|
||||
pub fn (p mut Parser) parse_map_ti(nr_muls int) table.Type {
|
||||
p.next()
|
||||
p.check(.lsbr)
|
||||
key_ti := p.parse_ti()
|
||||
key_ti := p.parse_type()
|
||||
p.check(.rsbr)
|
||||
value_ti := p.parse_ti()
|
||||
value_ti := p.parse_type()
|
||||
idx,name := p.table.find_or_register_map(&key_ti, &value_ti)
|
||||
return table.new_type(.map, name, idx, nr_muls)
|
||||
}
|
||||
@@ -44,7 +44,7 @@ pub fn (p mut Parser) parse_multi_return_ti() table.Type {
|
||||
p.check(.lpar)
|
||||
mut mr_tis := []table.Type
|
||||
for {
|
||||
mr_ti := p.parse_ti()
|
||||
mr_ti := p.parse_type()
|
||||
mr_tis << mr_ti
|
||||
if p.tok.kind == .comma {
|
||||
p.check(.comma)
|
||||
@@ -60,12 +60,18 @@ pub fn (p mut Parser) parse_multi_return_ti() table.Type {
|
||||
|
||||
pub fn (p mut Parser) parse_variadic_ti() table.Type {
|
||||
p.check(.ellipsis)
|
||||
variadic_ti := p.parse_ti()
|
||||
variadic_ti := p.parse_type()
|
||||
idx,name := p.table.find_or_register_variadic(&variadic_ti)
|
||||
return table.new_type(.variadic, name, idx, 0)
|
||||
}
|
||||
|
||||
pub fn (p mut Parser) parse_ti() table.Type {
|
||||
pub fn (p mut Parser) parse_fn_type() table.Type {
|
||||
//p.check(.key_fn)
|
||||
p.fn_decl()
|
||||
return table.int_type
|
||||
}
|
||||
|
||||
pub fn (p mut Parser) parse_type() table.Type {
|
||||
mut nr_muls := 0
|
||||
for p.tok.kind == .amp {
|
||||
p.check(.amp)
|
||||
@@ -73,6 +79,10 @@ pub fn (p mut Parser) parse_ti() table.Type {
|
||||
}
|
||||
name := p.tok.lit
|
||||
match p.tok.kind {
|
||||
// func
|
||||
.key_fn {
|
||||
return p.parse_fn_type()
|
||||
}
|
||||
// array
|
||||
.lsbr {
|
||||
return p.parse_array_ti(nr_muls)
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
v.ast
|
||||
v.token
|
||||
v.table
|
||||
v.pref
|
||||
term
|
||||
os
|
||||
)
|
||||
@@ -35,6 +36,9 @@ mut:
|
||||
//
|
||||
// prefix_parse_fns []PrefixParseFn
|
||||
inside_if bool
|
||||
pref &pref.Preferences // Preferences shared from V struct
|
||||
builtin_mod bool
|
||||
mod string
|
||||
}
|
||||
|
||||
// for tests
|
||||
@@ -59,6 +63,8 @@ pub fn parse_file(path string, table &table.Table) ast.File {
|
||||
scanner: scanner.new_scanner(text)
|
||||
table: table
|
||||
file_name: path
|
||||
pref: &pref.Preferences{}
|
||||
builtin_mod: true
|
||||
}
|
||||
p.read_first_token()
|
||||
// module decl
|
||||
@@ -170,6 +176,12 @@ pub fn (p mut Parser) top_stmt() ast.Stmt {
|
||||
// }
|
||||
}
|
||||
}
|
||||
.lsbr {
|
||||
return p.attr()
|
||||
}
|
||||
.key_global {
|
||||
return p.global_decl()
|
||||
}
|
||||
.key_const {
|
||||
return p.const_decl()
|
||||
}
|
||||
@@ -179,16 +191,12 @@ pub fn (p mut Parser) top_stmt() ast.Stmt {
|
||||
.key_struct {
|
||||
return p.struct_decl()
|
||||
}
|
||||
.lsbr {
|
||||
p.next()
|
||||
p.check(.name)
|
||||
p.check(.rsbr)
|
||||
return ast.Module{}
|
||||
.dollar {
|
||||
return p.comp_if()
|
||||
}
|
||||
else {
|
||||
p.error('bad top level statement')
|
||||
return ast.Module{} // silence C warning
|
||||
// exit(0)
|
||||
return ast.Stmt{}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -204,6 +212,9 @@ pub fn (p mut Parser) stmt() ast.Stmt {
|
||||
.key_return {
|
||||
return p.return_stmt()
|
||||
}
|
||||
.dollar {
|
||||
return p.comp_if()
|
||||
}
|
||||
else {
|
||||
// `x := ...`
|
||||
if p.tok.kind == .name && p.peek_tok.kind == .decl_assign {
|
||||
@@ -218,6 +229,22 @@ pub fn (p mut Parser) stmt() ast.Stmt {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (p mut Parser) comp_if() ast.CompIf {
|
||||
p.next()
|
||||
p.check(.key_if)
|
||||
if p.tok.kind == .not {
|
||||
p.next()
|
||||
}
|
||||
p.check_name()
|
||||
p.parse_block()
|
||||
if p.tok.kind == .dollar && p.peek_tok.kind == .key_else {
|
||||
p.next()
|
||||
p.check(.key_else)
|
||||
p.parse_block()
|
||||
}
|
||||
return ast.CompIf{}
|
||||
}
|
||||
|
||||
pub fn (p mut Parser) assign_expr(left ast.Expr) ast.AssignExpr {
|
||||
op := p.tok.kind
|
||||
p.next()
|
||||
@@ -231,6 +258,15 @@ pub fn (p mut Parser) assign_expr(left ast.Expr) ast.AssignExpr {
|
||||
return node
|
||||
}
|
||||
|
||||
fn (p mut Parser) attr() ast.Attr {
|
||||
p.check(.lsbr)
|
||||
name := p.check_name()
|
||||
p.check(.rsbr)
|
||||
return ast.Attr{
|
||||
name: name
|
||||
}
|
||||
}
|
||||
|
||||
fn (p mut Parser) range_expr(low ast.Expr) ast.Expr {
|
||||
// ,table.Type) {
|
||||
p.next()
|
||||
@@ -310,7 +346,8 @@ pub fn (p mut Parser) name_expr() (ast.Expr,table.Type) {
|
||||
mut node := ast.Expr{}
|
||||
// mut typ := table.void_ti
|
||||
mut typ := table.unresolved_type
|
||||
if p.tok.lit == 'C' {
|
||||
is_c := p.tok.lit == 'C' && p.peek_tok.kind == .dot
|
||||
if is_c {
|
||||
p.next()
|
||||
p.check(.dot)
|
||||
}
|
||||
@@ -327,7 +364,7 @@ pub fn (p mut Parser) name_expr() (ast.Expr,table.Type) {
|
||||
}
|
||||
// struct init
|
||||
else if p.peek_tok.kind == .lcbr && (p.tok.lit[0].is_capital() || p.tok.lit in ['array', 'string']) {
|
||||
typ = p.parse_ti()
|
||||
typ = p.parse_type()
|
||||
// p.warn('struct init typ=$typ.name')
|
||||
p.check(.lcbr)
|
||||
mut field_names := []string
|
||||
@@ -347,13 +384,13 @@ pub fn (p mut Parser) name_expr() (ast.Expr,table.Type) {
|
||||
}
|
||||
p.check(.rcbr)
|
||||
}
|
||||
// variable
|
||||
else {
|
||||
// p.warn('name ')
|
||||
// left := p.parse_ident()
|
||||
mut ident := ast.Ident{
|
||||
name: p.tok.lit
|
||||
}
|
||||
// variable
|
||||
if var := p.table.find_var(p.tok.lit) {
|
||||
typ = var.typ
|
||||
ident.kind = .variable
|
||||
@@ -361,18 +398,40 @@ pub fn (p mut Parser) name_expr() (ast.Expr,table.Type) {
|
||||
typ: typ
|
||||
name: ident.name
|
||||
// expr: p.expr(0)// var.expr
|
||||
|
||||
|
||||
}
|
||||
// ident.ti = ti
|
||||
node = ident
|
||||
p.next()
|
||||
}else{
|
||||
// Function object (not a call), e.g. `onclick(my_click)`
|
||||
p.table.find_fn(p.tok.lit) or {
|
||||
p.error('name expr unknown variable `$p.tok.lit`')
|
||||
exit(0)
|
||||
if is_c {
|
||||
typ = table.int_type
|
||||
ident.info = ast.IdentVar{
|
||||
typ: typ
|
||||
name: ident.name
|
||||
}
|
||||
node = ident
|
||||
p.next()
|
||||
return node,typ
|
||||
}
|
||||
// const
|
||||
if c := p.table.find_const(p.tok.lit) {
|
||||
typ = c.typ
|
||||
ident.kind = .constant
|
||||
ident.info = ast.IdentVar{
|
||||
typ: typ
|
||||
name: ident.name
|
||||
}
|
||||
node = ident
|
||||
p.next()
|
||||
}else{
|
||||
// Function object (not a call), e.g. `onclick(my_click)`
|
||||
p.table.find_fn(p.tok.lit) or {
|
||||
p.error('name expr unknown identifier `$p.tok.lit`')
|
||||
exit(0)
|
||||
}
|
||||
p.next()
|
||||
}
|
||||
p.next()
|
||||
}
|
||||
}
|
||||
return node,typ
|
||||
@@ -505,6 +564,7 @@ fn (p mut Parser) index_expr(left ast.Expr, typ_ table.Type) (ast.Expr,table.Typ
|
||||
node = ast.IndexExpr{
|
||||
left: left
|
||||
index: index_expr
|
||||
typ: typ
|
||||
}
|
||||
// return node
|
||||
return node,typ
|
||||
@@ -572,6 +632,7 @@ fn (p mut Parser) for_statement() ast.Stmt {
|
||||
stmts := p.parse_block()
|
||||
return ast.ForStmt{
|
||||
stmts: stmts
|
||||
pos: p.tok.position()
|
||||
}
|
||||
}
|
||||
else if p.tok.kind == .key_mut {
|
||||
@@ -600,9 +661,6 @@ fn (p mut Parser) for_statement() ast.Stmt {
|
||||
if p.tok.kind != .semicolon {
|
||||
mut typ := table.Type{}
|
||||
cond,typ = p.expr(0)
|
||||
if typ.kind != .bool {
|
||||
p.error('non-bool used as for condition')
|
||||
}
|
||||
}
|
||||
p.check(.semicolon)
|
||||
if p.tok.kind != .lcbr {
|
||||
@@ -630,6 +688,7 @@ fn (p mut Parser) for_statement() ast.Stmt {
|
||||
// println('nr stmts=$stmts.len')
|
||||
return ast.ForStmt{
|
||||
stmts: stmts
|
||||
pos: p.tok.position()
|
||||
}
|
||||
}
|
||||
// `for cond {`
|
||||
@@ -641,6 +700,7 @@ fn (p mut Parser) for_statement() ast.Stmt {
|
||||
return ast.ForStmt{
|
||||
cond: cond
|
||||
stmts: stmts
|
||||
pos: p.tok.position()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -650,12 +710,8 @@ fn (p mut Parser) if_expr() (ast.Expr,table.Type) {
|
||||
// }
|
||||
mut node := ast.Expr{}
|
||||
p.check(.key_if)
|
||||
cond,cond_ti := p.expr(0)
|
||||
cond,_ := p.expr(0)
|
||||
p.inside_if = false
|
||||
// if !p.table.check(table.bool_ti, cond_ti) {
|
||||
if cond_ti.kind != .bool {
|
||||
p.error('non-bool (`$cond_ti.name`) used as if condition')
|
||||
}
|
||||
stmts := p.parse_block()
|
||||
mut else_stmts := []ast.Stmt
|
||||
if p.tok.kind == .key_else {
|
||||
@@ -679,8 +735,9 @@ fn (p mut Parser) if_expr() (ast.Expr,table.Type) {
|
||||
stmts: stmts
|
||||
else_stmts: else_stmts
|
||||
ti: ti
|
||||
pos: p.tok.position()
|
||||
// left: left
|
||||
|
||||
|
||||
}
|
||||
return node,ti
|
||||
}
|
||||
@@ -708,19 +765,19 @@ fn (p mut Parser) string_expr() (ast.Expr,table.Type) {
|
||||
|
||||
fn (p mut Parser) array_init() (ast.Expr,table.Type) {
|
||||
p.check(.lsbr)
|
||||
mut val_ti := table.void_type
|
||||
mut val_type := table.void_type
|
||||
mut exprs := []ast.Expr
|
||||
for i := 0; p.tok.kind != .rsbr; i++ {
|
||||
expr,ti := p.expr(0)
|
||||
expr,typ := p.expr(0)
|
||||
exprs << expr
|
||||
if i == 0 {
|
||||
val_ti = ti
|
||||
val_type = typ
|
||||
}
|
||||
if p.tok.kind == .comma {
|
||||
p.check(.comma)
|
||||
}
|
||||
}
|
||||
type_idx,type_name := p.table.find_or_register_array(val_ti, 1)
|
||||
type_idx,type_name := p.table.find_or_register_array(val_type, 1)
|
||||
array_ti := table.new_type(.array, type_name, type_idx, 0)
|
||||
mut node := ast.Expr{}
|
||||
node = ast.ArrayInit{
|
||||
@@ -792,20 +849,31 @@ fn (p mut Parser) import_stmt() []ast.Import {
|
||||
return imports
|
||||
}
|
||||
|
||||
// TODO
|
||||
// fn (p mut Parser) const_decl() ast... {
|
||||
fn (p mut Parser) const_decl() ast.Stmt {
|
||||
fn (p mut Parser) const_decl() ast.ConstDecl {
|
||||
p.check(.key_const)
|
||||
p.check(.lpar)
|
||||
mut fields := []ast.Field
|
||||
mut exprs := []ast.Expr
|
||||
for p.tok.kind != .rpar {
|
||||
name := p.check_name()
|
||||
println('const: $name')
|
||||
p.check(.assign)
|
||||
_,_ := p.expr(0)
|
||||
// expr, ti := p.expr(0)
|
||||
expr,typ := p.expr(0)
|
||||
fields << ast.Field{
|
||||
name: name
|
||||
typ: typ
|
||||
}
|
||||
exprs << expr
|
||||
p.table.register_const(table.Var{
|
||||
name: name
|
||||
typ: typ
|
||||
})
|
||||
}
|
||||
p.check(.rpar)
|
||||
return ast.Stmt{}
|
||||
return ast.ConstDecl{
|
||||
fields: fields
|
||||
exprs: exprs
|
||||
}
|
||||
}
|
||||
|
||||
fn (p mut Parser) struct_decl() ast.StructDecl {
|
||||
@@ -824,15 +892,15 @@ fn (p mut Parser) struct_decl() ast.StructDecl {
|
||||
p.check(.colon)
|
||||
}
|
||||
field_name := p.check_name()
|
||||
ti := p.parse_ti()
|
||||
ti := p.parse_type()
|
||||
ast_fields << ast.Field{
|
||||
name: field_name
|
||||
ti: ti
|
||||
typ: ti
|
||||
}
|
||||
fields << table.Field{
|
||||
name: field_name
|
||||
// type_idx: ti.idx
|
||||
|
||||
|
||||
ti: ti
|
||||
}
|
||||
}
|
||||
@@ -905,7 +973,7 @@ fn (p mut Parser) var_decl() ast.VarDecl {
|
||||
name: name
|
||||
is_mut: is_mut
|
||||
// expr: expr
|
||||
|
||||
|
||||
typ: typ
|
||||
})
|
||||
p.warn('var decl name=$name typ=$typ.name')
|
||||
@@ -913,7 +981,7 @@ fn (p mut Parser) var_decl() ast.VarDecl {
|
||||
node := ast.VarDecl{
|
||||
name: name
|
||||
expr: expr // p.expr(token.lowest_prec)
|
||||
|
||||
|
||||
is_mut: is_mut
|
||||
typ: typ
|
||||
pos: p.tok.position()
|
||||
@@ -921,6 +989,40 @@ fn (p mut Parser) var_decl() ast.VarDecl {
|
||||
return node
|
||||
}
|
||||
|
||||
fn (p mut Parser) global_decl() ast.GlobalDecl {
|
||||
if !p.pref.translated && !p.pref.is_live && !p.builtin_mod && !p.pref.building_v && p.mod != 'ui' && p.mod != 'gg2' && p.mod != 'uiold' && !os.getwd().contains('/volt') && !p.pref.enable_globals {
|
||||
p.error('use `v --enable-globals ...` to enable globals')
|
||||
}
|
||||
p.next()
|
||||
name := p.check_name()
|
||||
println(name)
|
||||
typ := p.parse_type()
|
||||
if p.tok.kind == .assign {
|
||||
p.next()
|
||||
p.expr(0)
|
||||
}
|
||||
p.table.register_global(name, typ)
|
||||
// p.genln(p.table.cgen_name_type_pair(name, typ))
|
||||
/*
|
||||
mut g := p.table.cgen_name_type_pair(name, typ)
|
||||
if p.tok == .assign {
|
||||
p.next()
|
||||
g += ' = '
|
||||
_,expr := p.tmp_expr()
|
||||
g += expr
|
||||
}
|
||||
// p.genln('; // global')
|
||||
g += '; // global'
|
||||
if !p.cgen.nogen {
|
||||
p.cgen.consts << g
|
||||
}
|
||||
*/
|
||||
|
||||
return ast.GlobalDecl{
|
||||
name: name
|
||||
}
|
||||
}
|
||||
|
||||
fn verror(s string) {
|
||||
println(s)
|
||||
exit(1)
|
||||
|
||||
Reference in New Issue
Block a user