From 83f0c228e9808abc333090e283e8e97c7c339640 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Tue, 4 Feb 2020 09:54:15 +0100 Subject: [PATCH] v2: parse builtin.v, cfns.v float.v --- vlib/builtin/builtin_nix.v | 4 +-- vlib/builtin/cfns.v | 5 ++- vlib/builtin/int.v | 4 +-- vlib/compiler/fn.v | 3 +- vlib/v/ast/ast.v | 16 +++++++-- vlib/v/parser/fn.v | 74 ++++++++++++++++++++++++-------------- vlib/v/parser/parse_type.v | 8 +++-- vlib/v/parser/parser.v | 33 +++++++++++++++-- vlib/v/table/atypes.v | 5 +++ vlib/v/table/table.v | 7 ++++ vlib/v/token/token.v | 7 ++-- 11 files changed, 122 insertions(+), 44 deletions(-) diff --git a/vlib/builtin/builtin_nix.v b/vlib/builtin/builtin_nix.v index c8a9f2240c..6642a2fe81 100644 --- a/vlib/builtin/builtin_nix.v +++ b/vlib/builtin/builtin_nix.v @@ -30,7 +30,7 @@ pub fn println(s string) { // C.syscall(/* sys_write */ 1, /* stdout_value */ 1, snl.str, s.len+1) // return // } - // } + // } C.printf('%.*s\n', s.len, s.str) } @@ -118,7 +118,7 @@ fn print_backtrace_skipping_top_frames_linux(skipframes int) bool { if output in ['??:0:', '??:?:'] { output = '' } - println('${output:-46s} | ${addr:14s} | $beforeaddr') + //println('${output:-46s} | ${addr:14s} | $beforeaddr') // QTODO } // C.backtrace_symbols_fd(*voidptr(&buffer[skipframes]), nr_actual_frames, 1) return true diff --git a/vlib/builtin/cfns.v b/vlib/builtin/cfns.v index 14befde820..581030afeb 100644 --- a/vlib/builtin/cfns.v +++ b/vlib/builtin/cfns.v @@ -11,7 +11,7 @@ fn C.realloc(a byteptr, b int) byteptr fn C.qsort(voidptr, int, int, voidptr) -fn C.sprintf(a ...voidptr) byteptr +fn C.sprintf(a ...voidptr) int fn C.strlen(s byteptr) int @@ -23,8 +23,7 @@ fn C.popen(c byteptr, t byteptr) voidptr // fn backtrace(a voidptr, b int) int - -fn backtrace_symbols(voidptr, int) &byteptr +fn backtrace_symbols(voidptr, int) &byteptr fn backtrace_symbols_fd(voidptr, int, int) diff --git a/vlib/builtin/int.v b/vlib/builtin/int.v index 7ef16406be..49912dce26 100644 --- a/vlib/builtin/int.v +++ b/vlib/builtin/int.v @@ -155,14 +155,14 @@ pub fn (n int) hex() string { pub fn (n i64) hex() string { len := if n >= i64(0) { n.str().len + 3 } else { 19 } hex := malloc(len) - count := int(C.sprintf(charptr(hex), '0x%'C.PRIx64, n)) + count := C.sprintf(charptr(hex), '0x%'C.PRIx64, n) return tos(hex, count) } pub fn (n u64) hex() string { len := if n >= u64(0) { n.str().len + 3 } else { 19 } hex := malloc(len) - count := int(C.sprintf(charptr(hex), '0x%'C.PRIx64, n)) + count := C.sprintf(charptr(hex), '0x%'C.PRIx64, n) return tos(hex, count) } diff --git a/vlib/compiler/fn.v b/vlib/compiler/fn.v index 4a81a9b4a9..84ae81b061 100644 --- a/vlib/compiler/fn.v +++ b/vlib/compiler/fn.v @@ -903,7 +903,8 @@ fn (p mut Parser) fn_args(f mut Fn) { } // `(int, string, int)` // Just register fn arg types - types_only := p.tok == .mul || p.tok == .amp || (p.peek() == .comma && p.table.known_type(p.lit)) || p.peek() == .rpar // (int, string) + types_only := p.tok == .mul || p.tok == .amp || (p.peek() == .comma && +p.table.known_type(p.lit)) || p.peek() == .rpar // (int, string) if types_only { for p.tok != .rpar { typ := p.get_type() diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 7f809ad1e5..f572fa48db 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -8,12 +8,13 @@ import ( v.table ) -pub type Expr = InfixExpr | IfExpr | StringLiteral | IntegerLiteral | +pub type Expr = InfixExpr | IfExpr | StringLiteral | IntegerLiteral | CharLiteral | FloatLiteral | Ident | CallExpr | BoolLiteral | StructInit | ArrayInit | SelectorExpr | PostfixExpr | AssignExpr | PrefixExpr | MethodCallExpr | IndexExpr | RangeExpr pub type Stmt = VarDecl | GlobalDecl | FnDecl | Return | Module | Import | ExprStmt | -ForStmt | StructDecl | ForCStmt | ForInStmt | CompIf | ConstDecl | Attr | BranchStmt +ForStmt | StructDecl | ForCStmt | ForInStmt | CompIf | ConstDecl | Attr | BranchStmt | +HashStmt // | IncDecStmt k // Stand-alone expression in a statement list. pub struct ExprStmt { @@ -38,6 +39,11 @@ pub: val string } +pub struct CharLiteral { +pub: + val string +} + pub struct BoolLiteral { pub: val bool @@ -304,6 +310,12 @@ pub struct ReturnStmt { results []Expr } +// #include etc +pub struct HashStmt { +pub: + name string +} + /* pub struct AssignStmt { pub: diff --git a/vlib/v/parser/fn.v b/vlib/v/parser/fn.v index 3bf0b19162..3237091152 100644 --- a/vlib/v/parser/fn.v +++ b/vlib/v/parser/fn.v @@ -50,13 +50,19 @@ pub fn (p mut Parser) call_args() []ast.Expr { return args // ,table.void_ti } -fn (p mut Parser) fn_decl(/*high bool*/) ast.FnDecl { +fn (p mut Parser) fn_decl() ast.FnDecl { is_pub := p.tok.kind == .key_pub if is_pub { p.next() } p.table.clear_vars() p.check(.key_fn) + // C. + is_c := p.tok.kind == .name && p.tok.lit == 'C' + if is_c { + p.next() + p.check(.dot) + } // Receiver? mut rec_name := '' mut is_method := false @@ -91,37 +97,50 @@ fn (p mut Parser) fn_decl(/*high bool*/) ast.FnDecl { // Args mut args := []table.Var mut ast_args := []ast.Arg - for p.tok.kind != .rpar { - mut arg_names := [p.check_name()] - // `a, b, c int` - for p.tok.kind == .comma { - p.check(.comma) - arg_names << p.check_name() - } - ti := p.parse_type() - for arg_name in arg_names { - arg := table.Var{ - name: arg_name - typ: ti - } - args << arg - p.table.register_var(arg) - ast_args << ast.Arg{ - ti: ti - name: arg_name - } - if ti.kind == .variadic && p.tok.kind == .comma { - p.error('cannot use ...(variadic) with non-final parameter $arg_name') + // `int, int, string` (no names, just types) + types_only := p.tok.kind == .amp || (p.peek_tok.kind == .comma && p.table.known_type(p.tok.lit)) || p.peek_tok.kind == .rpar + if types_only { + p.warn('types only') + for p.tok.kind != .rpar { + p.parse_type() + if p.tok.kind == .comma { + p.next() } } - if p.tok.kind != .rpar { - p.check(.comma) + } + else { + for p.tok.kind != .rpar { + mut arg_names := [p.check_name()] + // `a, b, c int` + for p.tok.kind == .comma { + p.check(.comma) + arg_names << p.check_name() + } + ti := p.parse_type() + for arg_name in arg_names { + arg := table.Var{ + name: arg_name + typ: ti + } + args << arg + p.table.register_var(arg) + ast_args << ast.Arg{ + ti: ti + name: arg_name + } + if ti.kind == .variadic && p.tok.kind == .comma { + p.error('cannot use ...(variadic) with non-final parameter $arg_name') + } + } + if p.tok.kind != .rpar { + p.check(.comma) + } } } p.check(.rpar) // Return type mut typ := table.void_type - if p.tok.kind in [.name, .lpar] { + if p.tok.kind in [.name, .lpar, .amp] { typ = p.parse_type() p.return_type = typ } @@ -145,7 +164,10 @@ fn (p mut Parser) fn_decl(/*high bool*/) ast.FnDecl { return_type: typ }) } - stmts := p.parse_block() + mut stmts := []ast.Stmt + if p.tok.kind == .lcbr { + stmts = p.parse_block() + } return ast.FnDecl{ name: name stmts: stmts diff --git a/vlib/v/parser/parse_type.v b/vlib/v/parser/parse_type.v index d5dcb64943..bdd2dc9b3d 100644 --- a/vlib/v/parser/parse_type.v +++ b/vlib/v/parser/parse_type.v @@ -2,7 +2,6 @@ module parser // Copyright (c) 2019-2020 Alexander Medvednikov. All rights reserved. // Use of this source code is governed by an MIT license // that can be found in the LICENSE file. - import ( v.table ) @@ -66,7 +65,7 @@ pub fn (p mut Parser) parse_variadic_ti() table.Type { } pub fn (p mut Parser) parse_fn_type() table.Type { - //p.check(.key_fn) + // p.check(.key_fn) p.fn_decl() return table.int_type } @@ -77,6 +76,10 @@ pub fn (p mut Parser) parse_type() table.Type { p.check(.amp) nr_muls++ } + if p.tok.lit == 'C' { + p.next() + p.check(.dot) + } name := p.tok.lit match p.tok.kind { // func @@ -173,4 +176,3 @@ pub fn (p mut Parser) parse_type() table.Type { } } } - diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 9a0833d353..fa0edc4462 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -195,8 +195,11 @@ pub fn (p mut Parser) top_stmt() ast.Stmt { .dollar { return p.comp_if() } + .hash { + return p.hash() + } else { - p.error('bad top level statement') + p.error('parser: bad top level statement') return ast.Stmt{} } } @@ -457,8 +460,15 @@ pub fn (p mut Parser) expr(precedence int) (ast.Expr,table.Type) { .str { node,typ = p.string_expr() } - // -1, -a etc - .minus, .amp, .mul { + .chartoken { + typ = table.byte_type + node = ast.CharLiteral{ + val: p.tok.lit + } + p.next() + } + // -1, -a, !x, &x etc + .minus, .amp, .mul, .not { node,typ = p.prefix_expr() } // .amp { @@ -485,6 +495,13 @@ pub fn (p mut Parser) expr(precedence int) (ast.Expr,table.Type) { .lsbr { node,typ = p.array_init() } + .key_sizeof { + p.next() + p.check(.lpar) + p.next() + p.check(.rpar) + typ = table.int_type + } else { p.error('pexpr(): bad token `$p.tok.str()`') } @@ -755,6 +772,9 @@ fn (p mut Parser) string_expr() (ast.Expr,table.Type) { } p.check(.str_dollar) p.expr(0) + if p.tok.kind == .semicolon { + p.next() + } } return node,table.string_type } @@ -994,6 +1014,13 @@ fn (p mut Parser) var_decl() ast.VarDecl { return node } +fn (p mut Parser) hash() ast.HashStmt { + p.next() + return ast.HashStmt{ + name: p.tok.lit + } +} + 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') diff --git a/vlib/v/table/atypes.v b/vlib/v/table/atypes.v index 360d47f48a..abdfb8d38e 100644 --- a/vlib/v/table/atypes.v +++ b/vlib/v/table/atypes.v @@ -92,6 +92,11 @@ pub const ( name: 'bool' idx: bool_type_idx } + byte_type = Type{ + kind: .byte + name: 'byte' + idx: byte_type_idx + } ) /* pub fn (t Type) str() string { diff --git a/vlib/v/table/table.v b/vlib/v/table/table.v index c36f28692d..6df0e2f775 100644 --- a/vlib/v/table/table.v +++ b/vlib/v/table/table.v @@ -251,6 +251,13 @@ pub fn (t mut Table) register_type(typ Type) int { return idx } +pub fn (t &Table) known_type(name string) bool { + _ = t.find_type(name) or { + return false + } + return true +} + pub fn (t mut Table) find_or_register_map(key_typ &Type, value_typ &Type) (int,string) { name := 'map_${key_typ.name}_${value_typ.name}' // existing diff --git a/vlib/v/token/token.v b/vlib/v/token/token.v index 5bbdc95a15..a490244949 100644 --- a/vlib/v/token/token.v +++ b/vlib/v/token/token.v @@ -372,7 +372,7 @@ pub fn (tok Token) precedence() int { return 7 } // `*` | `/` | `%` | `<<` | `>>` | `&` - .mul, .div, .left_shift, .righ_shift, .amp { + .mul, .div, .mod, .left_shift, .righ_shift, .amp { return 6 } // `+` | `-` | `|` | `^` @@ -391,6 +391,9 @@ pub fn (tok Token) precedence() int { .logical_or, .assign, .plus_assign, .minus_assign, .div_assign, .mult_assign { return 2 } + .key_in { + return 1 + } // /.plus_assign { // /return 2 // /} @@ -456,5 +459,5 @@ pub fn (tok Kind) is_relational() bool { } pub fn (kind Kind) is_infix() bool { - return kind in [.plus, .minus, .mod, .mul, .div, .eq, .ne, .gt, .lt, .ge, .le, .logical_or, .and, .dot, .pipe, .left_shift] + return kind in [.plus, .minus, .mod, .mul, .div, .eq, .ne, .gt, .lt, .key_in, .ge, .le, .logical_or, .and, .dot, .pipe, .left_shift] }