more vfmt fixes
parent
30481a36dc
commit
3d4f85069f
|
@ -89,8 +89,10 @@ fn (p mut Parser) comp_time() {
|
|||
p.returns = false
|
||||
//p.gen('/* returns $p.returns */')
|
||||
if p.tok == .dollar && p.peek() == .key_else {
|
||||
p.fspace()
|
||||
p.next()
|
||||
p.next()
|
||||
p.fspace() // spaces before and after $else
|
||||
p.check(.lcbr)
|
||||
p.genln('#else')
|
||||
p.statements_no_rcbr()
|
||||
|
|
|
@ -58,10 +58,11 @@ fn (p mut Parser) bterm() string {
|
|||
if tok in [.eq, .gt, .lt, .le, .ge, .ne] {
|
||||
//TODO: remove when array comparing is supported
|
||||
if is_array {
|
||||
p.error('Array comparing is not supported yet')
|
||||
p.error('array comparing is not supported yet')
|
||||
}
|
||||
|
||||
p.fgen(' ${p.tok.str()} ')
|
||||
p.fspace()
|
||||
//p.fgen(' ${p.tok.str()} ')
|
||||
if (is_float || is_str || is_ustr) && !p.is_js {
|
||||
p.gen(',')
|
||||
}
|
||||
|
@ -72,6 +73,7 @@ fn (p mut Parser) bterm() string {
|
|||
p.gen(tok.str())
|
||||
}
|
||||
p.next()
|
||||
p.fspace()
|
||||
// `id == user.id` => `id == $1`, `user.id`
|
||||
if p.is_sql {
|
||||
p.sql_i++
|
||||
|
@ -140,7 +142,6 @@ fn (p mut Parser) name_expr() string {
|
|||
p.string_expr()
|
||||
return 'string'
|
||||
}
|
||||
p.fgen(name)
|
||||
// known_type := p.table.known_type(name)
|
||||
orig_name := name
|
||||
is_c := name == 'C' && p.peek() == .dot
|
||||
|
@ -190,7 +191,6 @@ fn (p mut Parser) name_expr() string {
|
|||
p.next()
|
||||
p.check(.dot)
|
||||
name = p.lit
|
||||
p.fgen(name)
|
||||
name = prepend_mod(mod_gen_name(mod), name)
|
||||
}
|
||||
// Unknown name, try prepending the module name to it
|
||||
|
@ -484,10 +484,11 @@ fn (p mut Parser) term() string {
|
|||
is_mul := tok == .mul
|
||||
is_div := tok == .div
|
||||
is_mod := tok == .mod
|
||||
p.fspace()
|
||||
p.next()
|
||||
p.gen(tok.str())// + ' /*op2*/ ')
|
||||
oph := p.cgen.add_placeholder()
|
||||
p.fgen(' ' + tok.str() + ' ')
|
||||
p.fspace()
|
||||
if (is_div || is_mod) && p.tok == .number && p.lit == '0' {
|
||||
p.error('division or modulo by zero')
|
||||
}
|
||||
|
@ -575,11 +576,9 @@ fn (p mut Parser) factor() string {
|
|||
p.error('constant `$p.lit` overflows `$p.expected_type`')
|
||||
}
|
||||
p.gen(p.lit)
|
||||
p.fgen(p.lit)
|
||||
}
|
||||
.minus {
|
||||
p.gen('-')
|
||||
p.fgen('-')
|
||||
p.next()
|
||||
return p.factor()
|
||||
// Variable
|
||||
|
|
|
@ -179,8 +179,7 @@ fn (p mut Parser) clear_vars() {
|
|||
// Function signatures are added to the top of the .c file in the first run.
|
||||
fn (p mut Parser) fn_decl() {
|
||||
p.clear_vars() // clear local vars every time a new fn is started
|
||||
|
||||
//defer { p.fgenln('\n') }
|
||||
defer { p.fgenln2('\n') }
|
||||
// If we are in the first pass, create a new function.
|
||||
// In the second pass fetch the one we created.
|
||||
/*
|
||||
|
@ -206,6 +205,7 @@ fn (p mut Parser) fn_decl() {
|
|||
}
|
||||
if is_pub {
|
||||
p.next()
|
||||
p.fspace()
|
||||
}
|
||||
p.returns = false
|
||||
//p.gen('/* returns $p.returns */')
|
||||
|
@ -218,10 +218,12 @@ fn (p mut Parser) fn_decl() {
|
|||
f.is_method = true
|
||||
p.check(.lpar)
|
||||
receiver_name := p.check_name()
|
||||
p.fspace()
|
||||
is_mut := p.tok == .key_mut
|
||||
is_amp := p.tok == .amp
|
||||
if is_mut || is_amp {
|
||||
p.check_space(p.tok)
|
||||
p.check(p.tok)
|
||||
p.fspace()
|
||||
}
|
||||
receiver_typ = p.get_type()
|
||||
t := p.table.find_type(receiver_typ)
|
||||
|
@ -350,7 +352,7 @@ fn (p mut Parser) fn_decl() {
|
|||
// Returns a type?
|
||||
mut typ := 'void'
|
||||
if p.tok in [.name, .mul, .amp, .lsbr, .question, .lpar] {
|
||||
p.fgen(' ')
|
||||
p.fspace()
|
||||
typ = p.get_type()
|
||||
}
|
||||
// V allows empty functions (just definitions)
|
||||
|
@ -1568,9 +1570,9 @@ pub fn (f &Fn) v_fn_name() string {
|
|||
|
||||
pub fn (f &Fn) str_for_error() string {
|
||||
// Build the args for the error
|
||||
mut s := ''
|
||||
for i, a in f.args {
|
||||
if i == 0 {
|
||||
mut s := ''
|
||||
for i, a in f.args {
|
||||
if i == 0 {
|
||||
if f.is_method {
|
||||
s += a.typ + '.' + f.name + '('
|
||||
continue
|
||||
|
@ -1581,7 +1583,7 @@ pub fn (f &Fn) str_for_error() string {
|
|||
if i < f.args.len - 1 {
|
||||
s += ', '
|
||||
}
|
||||
}
|
||||
}
|
||||
return s + ')'
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ module compiler
|
|||
|
||||
fn (p mut Parser) for_st() {
|
||||
p.check(.key_for)
|
||||
p.fgen(' ')
|
||||
p.fspace()
|
||||
p.for_expr_cnt++
|
||||
next_tok := p.peek()
|
||||
//debug := p.scanner.file_path.contains('r_draw')
|
||||
|
@ -32,13 +32,13 @@ fn (p mut Parser) for_st() {
|
|||
}
|
||||
p.check(.semicolon)
|
||||
p.gen(' ; ')
|
||||
p.fgen(' ')
|
||||
p.fspace()
|
||||
if p.tok != .semicolon {
|
||||
p.bool_expression()
|
||||
}
|
||||
p.check(.semicolon)
|
||||
p.gen(' ; ')
|
||||
p.fgen(' ')
|
||||
p.fspace()
|
||||
if p.tok != .lcbr {
|
||||
p.statement(false)
|
||||
}
|
||||
|
@ -61,9 +61,9 @@ fn (p mut Parser) for_st() {
|
|||
if i == '_' && val == '_' {
|
||||
p.error('no new variables on the left side of `in`')
|
||||
}
|
||||
p.fgen(' ')
|
||||
p.fspace()
|
||||
p.check(.key_in)
|
||||
p.fgen(' ')
|
||||
p.fspace()
|
||||
tmp := p.get_tmp()
|
||||
p.cgen.start_tmp()
|
||||
mut typ := p.bool_expression()
|
||||
|
@ -121,7 +121,7 @@ fn (p mut Parser) for_st() {
|
|||
// `for val in vals`
|
||||
else if p.peek() == .key_in {
|
||||
val := p.check_name()
|
||||
p.fgen(' ')
|
||||
p.fspace()
|
||||
p.check(.key_in)
|
||||
p.fspace()
|
||||
tmp := p.get_tmp()
|
||||
|
|
|
@ -117,6 +117,7 @@ pub mut:
|
|||
comptime_define string // -D vfmt for `if $vfmt {`
|
||||
fast bool // use tcc/x64 codegen
|
||||
enable_globals bool // allow __global for low level code
|
||||
is_fmt bool
|
||||
}
|
||||
|
||||
// Should be called by main at the end of the compilation process, to cleanup
|
||||
|
@ -946,6 +947,7 @@ pub fn new_v(args[]string) &V {
|
|||
ccompiler: find_c_compiler()
|
||||
building_v: !is_repl && (rdir_name == 'compiler' || rdir_name == 'v.v' || dir.contains('vlib'))
|
||||
comptime_define: comptime_define
|
||||
is_fmt: comptime_define == 'vfmt'
|
||||
}
|
||||
if pref.is_verbose || pref.is_debug {
|
||||
println('C compiler=$pref.ccompiler')
|
||||
|
|
|
@ -279,6 +279,7 @@ fn (p mut Parser) parse(pass Pass) {
|
|||
p.mod = p.check_name()
|
||||
}
|
||||
//
|
||||
p.fgenln2('\n')
|
||||
|
||||
p.cgen.nogen = false
|
||||
if p.pref.build_mode == .build_module && p.mod != p.v.mod {
|
||||
|
@ -392,6 +393,7 @@ fn (p mut Parser) parse(pass Pass) {
|
|||
//p.error('__global is only allowed in translated code')
|
||||
}
|
||||
p.next()
|
||||
p.fspace()
|
||||
name := p.check_name()
|
||||
typ := p.get_type()
|
||||
p.register_global(name, typ)
|
||||
|
@ -408,6 +410,11 @@ fn (p mut Parser) parse(pass Pass) {
|
|||
if !p.cgen.nogen {
|
||||
p.cgen.consts << g
|
||||
}
|
||||
p.fgenln2('')
|
||||
if p.tok != .key_global {
|
||||
// An extra empty line to separate a block of globals
|
||||
p.fgenln2('')
|
||||
}
|
||||
}
|
||||
.eof {
|
||||
//p.log('end of parse()')
|
||||
|
@ -420,19 +427,7 @@ fn (p mut Parser) parse(pass Pass) {
|
|||
if !p.first_pass() && !p.pref.is_repl {
|
||||
p.check_unused_imports()
|
||||
}
|
||||
if !p.first_pass() && p.fileis('main.v') {
|
||||
s := p.scanner.fmt_out.str().trim_space()
|
||||
if s.len > 0 {
|
||||
println('GENERATING MAIN.V')
|
||||
out := os.create('/var/tmp/fmt.v') or {
|
||||
verror('failed to create fmt.v')
|
||||
return
|
||||
}
|
||||
//println(p.scanner.fmt_out.str())
|
||||
out.writeln(p.scanner.fmt_out.str().trim_space())
|
||||
out.close()
|
||||
}
|
||||
}
|
||||
p.gen_fmt() // not generated unless `-d vfmt` is provided
|
||||
return
|
||||
}
|
||||
else {
|
||||
|
@ -720,8 +715,15 @@ fn (p &Parser) strtok() string {
|
|||
if p.tok == .name {
|
||||
return p.lit
|
||||
}
|
||||
if p.tok == .number {
|
||||
return p.lit
|
||||
}
|
||||
if p.tok == .str {
|
||||
return '"$p.lit"'
|
||||
if p.lit.contains("'") {
|
||||
return '"$p.lit"'
|
||||
} else {
|
||||
return "'$p.lit'"
|
||||
}
|
||||
}
|
||||
res := p.tok.str()
|
||||
if res == '' {
|
||||
|
@ -782,6 +784,8 @@ fn (p mut Parser) get_type() string {
|
|||
mut typ := ''
|
||||
// multiple returns
|
||||
if p.tok == .lpar {
|
||||
//p.warn('`()` are no longer necessary in multiple returns' +
|
||||
//'\nuse `fn foo() int, int {` instead of `fn foo() (int, int) {`')
|
||||
// if p.inside_tuple {p.error('unexpected (')}
|
||||
// p.inside_tuple = true
|
||||
p.check(.lpar)
|
||||
|
@ -1270,9 +1274,8 @@ fn ($v.name mut $v.typ) $p.cur_fn.name (...) {
|
|||
}
|
||||
}
|
||||
p.fspace()
|
||||
p.fgen(tok.str())
|
||||
p.fspace()
|
||||
p.next()
|
||||
p.fspace()
|
||||
pos := p.cgen.cur_line.len
|
||||
expr_type := p.bool_expression()
|
||||
//if p.expected_type.starts_with('array_') {
|
||||
|
@ -1633,7 +1636,6 @@ fn (p mut Parser) var_expr(v Var) string {
|
|||
}
|
||||
}
|
||||
p.gen(p.tok.str())
|
||||
p.fgen(p.tok.str())
|
||||
p.next()// ++/--
|
||||
// allow `a := c++` in translated code TODO remove once c2v handles this
|
||||
if p.pref.translated {
|
||||
|
@ -2541,9 +2543,10 @@ fn (p mut Parser) if_st(is_expr bool, elif_depth int) string {
|
|||
}
|
||||
if_returns := p.returns
|
||||
p.returns = false
|
||||
// println('IF TYp=$typ')
|
||||
if p.tok == .key_else {
|
||||
p.fgenln2('')
|
||||
if !p.inside_if_expr {
|
||||
p.fgenln2('')
|
||||
}
|
||||
p.check(.key_else)
|
||||
p.fspace()
|
||||
if p.tok == .key_if {
|
||||
|
@ -2730,6 +2733,7 @@ fn (p mut Parser) return_st() {
|
|||
p.gen('return')
|
||||
}
|
||||
}
|
||||
p.fgenln('//ret')
|
||||
p.returns = true
|
||||
}
|
||||
|
||||
|
@ -2876,6 +2880,7 @@ fn (p mut Parser) attribute() {
|
|||
p.attr = p.attr + ':' + p.check_name()
|
||||
}
|
||||
p.check(.rsbr)
|
||||
p.fgenln2('')
|
||||
if p.tok == .key_fn || (p.tok == .key_pub && p.peek() == .key_fn) {
|
||||
p.fn_decl()
|
||||
p.attr = ''
|
||||
|
|
|
@ -76,7 +76,7 @@ fn new_scanner_file(file_path string) &Scanner {
|
|||
fn new_scanner(text string) &Scanner {
|
||||
return &Scanner {
|
||||
text: text
|
||||
fmt_out: strings.new_builder(1000)
|
||||
fmt_out: strings.new_builder(10000)
|
||||
should_print_line_on_error: true
|
||||
should_print_errors_in_color: true
|
||||
should_print_relative_paths_on_error: true
|
||||
|
@ -481,7 +481,7 @@ fn (s mut Scanner) scan() ScanRes {
|
|||
if nextc == `!` {
|
||||
// treat shebang line (#!) as a comment
|
||||
s.line_comment = s.text[start + 1..s.pos].trim_space()
|
||||
s.fgenln('// shebang line "$s.line_comment"')
|
||||
//s.fgenln('// shebang line "$s.line_comment"')
|
||||
return s.scan()
|
||||
}
|
||||
hash := s.text[start..s.pos]
|
||||
|
@ -585,7 +585,7 @@ fn (s mut Scanner) scan() ScanRes {
|
|||
s.ignore_line()
|
||||
s.line_comment = s.text[start + 1..s.pos]
|
||||
s.line_comment = s.line_comment.trim_space()
|
||||
s.fgenln('// ${s.prev_tok.str()} "$s.line_comment"')
|
||||
//s.fgenln('// ${s.prev_tok.str()} "$s.line_comment"')
|
||||
// Skip the comment (return the next token)
|
||||
return s.scan()
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ fn (p mut Parser) struct_decl() {
|
|||
is_pub := p.tok == .key_pub
|
||||
if is_pub {
|
||||
p.next()
|
||||
p.fspace()
|
||||
}
|
||||
// V can generate Objective C for integration with Cocoa
|
||||
// `[objc_interface:ParentInterface]`
|
||||
|
@ -220,7 +221,7 @@ fn (p mut Parser) struct_decl() {
|
|||
if p.first_pass() {
|
||||
p.table.add_field(typ.name, field_name, field_type, is_mut, attr, access_mod)
|
||||
}
|
||||
p.fgenln2('')
|
||||
p.fgenln2('') // newline between struct fields
|
||||
}
|
||||
p.check(.rcbr)
|
||||
if !is_c && !did_gen_something && p.first_pass() {
|
||||
|
@ -272,6 +273,7 @@ fn (p mut Parser) struct_init(typ string) string {
|
|||
}
|
||||
p.fspace()
|
||||
did_gen_something = true
|
||||
p.fgenln2('') // newline between struct fields
|
||||
}
|
||||
// If we already set some fields, need to prepend a comma
|
||||
if t.fields.len != inited_fields.len && inited_fields.len > 0 {
|
||||
|
@ -308,6 +310,7 @@ fn (p mut Parser) struct_init(typ string) string {
|
|||
p.gen(',')
|
||||
}
|
||||
did_gen_something = true
|
||||
p.fgenln2('') // newline between struct fields
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -286,6 +286,10 @@ fn (t []TokenKind) contains(val TokenKind) bool {
|
|||
}
|
||||
|
||||
fn (t Token) str() string {
|
||||
if t.tok == .number {
|
||||
return t.lit
|
||||
|
||||
}
|
||||
if t.tok == .str {
|
||||
return "'$t.lit'"
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
module compiler
|
||||
|
||||
import strings
|
||||
import os
|
||||
|
||||
[if vfmt]
|
||||
fn (scanner mut Scanner) fgen(s_ string) {
|
||||
|
@ -93,14 +94,37 @@ fn (p mut Parser) fnext() {
|
|||
if p.tok == .eof {
|
||||
return
|
||||
}
|
||||
if p.tok == .rcbr {
|
||||
if p.tok == .rcbr && !p.inside_if_expr {
|
||||
p.fmt_dec()
|
||||
}
|
||||
p.fgen2(p.strtok())
|
||||
// vfmt: increase indentation on `{` unless it's `{}`
|
||||
if p.tok == .lcbr { //&& p.scanner.pos + 1 < p.scanner.text.len && p.scanner.text[p.scanner.pos + 1] != `}` {
|
||||
if p.tok == .lcbr && !p.inside_if_expr { //&& p.scanner.pos + 1 < p.scanner.text.len && p.scanner.text[p.scanner.pos + 1] != `}` {
|
||||
p.fgenln2('')
|
||||
p.fmt_inc()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[if vfmt]
|
||||
fn (p mut Parser) gen_fmt() {
|
||||
if p.pass != .main {
|
||||
return
|
||||
}
|
||||
if p.file_name == '' {
|
||||
return
|
||||
}
|
||||
s := p.scanner.fmt_out.str().trim_space()
|
||||
if s == '' {
|
||||
return
|
||||
}
|
||||
println('GENERATING ${p.file_name}.V')
|
||||
out := os.create('/var/tmp/fmt/' + p.file_name) or {
|
||||
verror('failed to create fmt.v')
|
||||
return
|
||||
}
|
||||
//println(p.scanner.fmt_out.str())
|
||||
out.writeln(p.scanner.fmt_out.str().trim_space())
|
||||
out.close()
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue