2019-07-29 18:21:36 +02:00
|
|
|
// Copyright (c) 2019 Alexander Medvednikov. All rights reserved.
|
|
|
|
// Use of this source code is governed by an MIT license
|
|
|
|
// that can be found in the LICENSE file.
|
|
|
|
|
2019-10-13 15:37:43 +02:00
|
|
|
module compiler
|
2019-07-29 18:21:36 +02:00
|
|
|
|
2019-08-17 21:19:37 +02:00
|
|
|
import strings
|
2019-11-09 20:05:44 +01:00
|
|
|
import os
|
2019-07-29 18:21:36 +02:00
|
|
|
|
2019-10-27 10:16:33 +01:00
|
|
|
[if vfmt]
|
2019-08-07 08:19:27 +02:00
|
|
|
fn (scanner mut Scanner) fgen(s_ string) {
|
2019-08-17 21:19:37 +02:00
|
|
|
mut s := s_
|
2019-07-29 18:21:36 +02:00
|
|
|
if scanner.fmt_line_empty {
|
|
|
|
s = strings.repeat(`\t`, scanner.fmt_indent) + s
|
|
|
|
}
|
2019-12-06 13:24:53 +01:00
|
|
|
|
2019-11-11 06:04:37 +01:00
|
|
|
//scanner.fmt_out << s
|
2019-07-29 18:21:36 +02:00
|
|
|
scanner.fmt_out.write(s)
|
|
|
|
scanner.fmt_line_empty = false
|
|
|
|
}
|
|
|
|
|
2019-10-27 10:16:33 +01:00
|
|
|
[if vfmt]
|
2019-08-07 08:19:27 +02:00
|
|
|
fn (scanner mut Scanner) fgenln(s_ string) {
|
2019-08-17 21:19:37 +02:00
|
|
|
mut s := s_
|
2019-11-11 15:18:32 +01:00
|
|
|
if scanner.fmt_line_empty && scanner.fmt_indent > 0 {
|
2019-07-29 18:21:36 +02:00
|
|
|
s = strings.repeat(`\t`, scanner.fmt_indent) + s
|
|
|
|
}
|
2019-11-11 06:04:37 +01:00
|
|
|
//scanner.fmt_out << s
|
|
|
|
//scanner.fmt_out << '\n'
|
2019-07-29 18:21:36 +02:00
|
|
|
scanner.fmt_out.writeln(s)
|
|
|
|
scanner.fmt_line_empty = true
|
|
|
|
}
|
|
|
|
|
2019-11-18 11:10:31 +01:00
|
|
|
[if vfmt]
|
|
|
|
fn (scanner mut Scanner) fgen_nl() {
|
|
|
|
scanner.fmt_out.writeln('')
|
|
|
|
scanner.fmt_line_empty = true
|
|
|
|
}
|
|
|
|
|
2019-11-09 17:13:26 +01:00
|
|
|
|
2019-10-27 10:16:33 +01:00
|
|
|
[if vfmt]
|
2019-07-29 18:21:36 +02:00
|
|
|
fn (p mut Parser) fgen(s string) {
|
2019-11-09 17:13:26 +01:00
|
|
|
if p.pass != .main {
|
|
|
|
return
|
2019-12-06 13:24:53 +01:00
|
|
|
}
|
2019-07-29 18:21:36 +02:00
|
|
|
p.scanner.fgen(s)
|
|
|
|
}
|
|
|
|
|
2019-10-27 10:16:33 +01:00
|
|
|
[if vfmt]
|
2019-07-29 18:21:36 +02:00
|
|
|
fn (p mut Parser) fspace() {
|
2019-11-09 17:13:26 +01:00
|
|
|
if p.first_pass() {
|
|
|
|
return
|
2019-12-06 13:24:53 +01:00
|
|
|
}
|
2019-11-10 01:08:53 +01:00
|
|
|
p.fgen(' ')
|
2019-07-29 18:21:36 +02:00
|
|
|
}
|
|
|
|
|
2019-11-09 17:13:26 +01:00
|
|
|
|
2019-10-27 10:16:33 +01:00
|
|
|
[if vfmt]
|
2019-07-29 18:21:36 +02:00
|
|
|
fn (p mut Parser) fgenln(s string) {
|
2019-11-09 17:13:26 +01:00
|
|
|
if p.pass != .main {
|
|
|
|
return
|
2019-12-06 13:24:53 +01:00
|
|
|
}
|
2019-07-29 18:21:36 +02:00
|
|
|
p.scanner.fgenln(s)
|
|
|
|
}
|
|
|
|
|
2019-11-18 11:10:31 +01:00
|
|
|
[if vfmt]
|
|
|
|
fn (p mut Parser) fgen_nl() {
|
|
|
|
if p.pass != .main {
|
|
|
|
return
|
2019-12-06 13:24:53 +01:00
|
|
|
}
|
2019-11-18 11:10:31 +01:00
|
|
|
println(p.tok)
|
|
|
|
if p.prev_tok == .line_comment {
|
|
|
|
return
|
2019-12-06 13:24:53 +01:00
|
|
|
}
|
2019-11-18 11:10:31 +01:00
|
|
|
p.scanner.fgen_nl()
|
|
|
|
}
|
|
|
|
|
2019-09-27 03:00:48 +02:00
|
|
|
/*
|
2019-10-09 00:05:34 +02:00
|
|
|
fn (p mut Parser) peek() TokenKind {
|
2019-07-29 18:21:36 +02:00
|
|
|
for {
|
2019-08-04 11:00:56 +02:00
|
|
|
p.cgen.line = p.scanner.line_nr + 1
|
2019-07-29 18:21:36 +02:00
|
|
|
tok := p.scanner.peek()
|
|
|
|
if tok != .nl {
|
|
|
|
return tok
|
|
|
|
}
|
|
|
|
}
|
2019-08-08 09:49:56 +02:00
|
|
|
return .eof // TODO can never get here - v doesn't know that
|
2019-07-29 18:21:36 +02:00
|
|
|
}
|
2019-09-27 03:00:48 +02:00
|
|
|
*/
|
2019-07-29 18:21:36 +02:00
|
|
|
|
2019-10-27 10:16:33 +01:00
|
|
|
[if vfmt]
|
2019-07-29 18:21:36 +02:00
|
|
|
fn (p mut Parser) fmt_inc() {
|
2019-11-09 17:13:26 +01:00
|
|
|
if p.pass != .main {
|
|
|
|
return
|
2019-12-06 13:24:53 +01:00
|
|
|
}
|
2019-07-29 18:21:36 +02:00
|
|
|
p.scanner.fmt_indent++
|
|
|
|
}
|
|
|
|
|
2019-10-27 10:16:33 +01:00
|
|
|
[if vfmt]
|
2019-07-29 18:21:36 +02:00
|
|
|
fn (p mut Parser) fmt_dec() {
|
2019-11-09 17:13:26 +01:00
|
|
|
if p.pass != .main {
|
|
|
|
return
|
2019-12-06 13:24:53 +01:00
|
|
|
}
|
2019-07-29 18:21:36 +02:00
|
|
|
p.scanner.fmt_indent--
|
|
|
|
}
|
|
|
|
|
2019-11-11 06:58:50 +01:00
|
|
|
[if vfmt]
|
|
|
|
fn (p mut Scanner) init_fmt() {
|
2019-11-11 15:18:32 +01:00
|
|
|
// Right now we can't do `$if vfmt {`, so I'm using
|
|
|
|
// a conditional function init_fmt to set this flag.
|
|
|
|
// This function will only be called if `-d vfmt` is passed.
|
2019-11-11 06:58:50 +01:00
|
|
|
p.is_fmt = true
|
|
|
|
}
|
|
|
|
|
2019-11-09 17:13:26 +01:00
|
|
|
[if vfmt]
|
|
|
|
fn (p mut Parser) fnext() {
|
2019-11-11 15:18:32 +01:00
|
|
|
//if p.tok == .eof {
|
|
|
|
//println('eof ret')
|
|
|
|
//return
|
|
|
|
//}
|
2019-11-10 01:08:53 +01:00
|
|
|
if p.tok == .rcbr && !p.inside_if_expr && p.prev_tok != .lcbr {
|
2019-11-09 17:13:26 +01:00
|
|
|
p.fmt_dec()
|
|
|
|
}
|
2019-12-06 13:24:53 +01:00
|
|
|
s := p.strtok()
|
2019-11-11 15:18:32 +01:00
|
|
|
if p.tok != .eof {
|
2019-11-10 01:08:53 +01:00
|
|
|
p.fgen(s)
|
2019-11-11 15:18:32 +01:00
|
|
|
}
|
2019-11-09 17:13:26 +01:00
|
|
|
// vfmt: increase indentation on `{` unless it's `{}`
|
2019-12-06 13:24:53 +01:00
|
|
|
inc_indent := false
|
2019-11-10 01:08:53 +01:00
|
|
|
if p.tok == .lcbr && !p.inside_if_expr && p.peek() != .rcbr {
|
2019-11-18 11:10:31 +01:00
|
|
|
p.fgen_nl()
|
2019-11-09 17:13:26 +01:00
|
|
|
p.fmt_inc()
|
|
|
|
}
|
2019-12-06 13:24:53 +01:00
|
|
|
|
2019-11-11 15:18:32 +01:00
|
|
|
// Skip comments and add them to vfmt output
|
|
|
|
if p.tokens[p.token_idx].tok in [.line_comment, .mline_comment] {
|
|
|
|
// Newline before the comment and after consts and closing }
|
|
|
|
if p.inside_const {
|
2019-11-18 11:10:31 +01:00
|
|
|
p.fgen_nl()
|
|
|
|
p.fgen_nl()
|
2019-12-06 13:24:53 +01:00
|
|
|
}
|
|
|
|
//is_rcbr := p.tok == .rcbr
|
2019-11-11 15:18:32 +01:00
|
|
|
for p.token_idx < p.tokens.len - 1 {
|
2019-11-18 11:10:31 +01:00
|
|
|
i := p.token_idx
|
2019-11-11 15:18:32 +01:00
|
|
|
tok := p.tokens[p.token_idx].tok
|
|
|
|
if tok != .line_comment && tok != .mline_comment {
|
|
|
|
break
|
2019-12-06 13:24:53 +01:00
|
|
|
}
|
2019-11-11 15:18:32 +01:00
|
|
|
comment_token := p.tokens[p.token_idx]
|
2019-11-18 11:10:31 +01:00
|
|
|
next := p.tokens[p.token_idx+1]
|
|
|
|
comment_on_new_line := p.token_idx == 0 ||
|
|
|
|
comment_token.line_nr > p.tokens[p.token_idx - 1].line_nr
|
|
|
|
//prev_token := p.tokens[p.token_idx - 1]
|
2019-11-11 15:18:32 +01:00
|
|
|
comment := comment_token.lit
|
2019-11-18 11:10:31 +01:00
|
|
|
if i > 0 && p.tokens[i-1].tok != .line_comment &&
|
|
|
|
comment_token.line_nr > p.tokens[i-1].line_nr {
|
|
|
|
p.fgen_nl()
|
2019-12-06 13:24:53 +01:00
|
|
|
}
|
2019-11-11 15:18:32 +01:00
|
|
|
if tok == .line_comment {
|
2019-11-18 11:10:31 +01:00
|
|
|
if !comment_on_new_line { //prev_token.line_nr < comment_token.line_nr {
|
|
|
|
p.fgen(' ')
|
2019-12-06 13:24:53 +01:00
|
|
|
}
|
2019-11-11 15:18:32 +01:00
|
|
|
p.fgen('// ' + comment)
|
2019-11-18 11:10:31 +01:00
|
|
|
/*
|
|
|
|
if false && i > 0 {
|
|
|
|
p.fgen(
|
|
|
|
'pln=${p.tokens[i-1].line_nr} ${comment_token.str()} ' +
|
|
|
|
'line_nr=$comment_token.line_nr next=${next.str()} next_line_nr=$next.line_nr')
|
|
|
|
}
|
|
|
|
*/
|
2019-12-06 13:24:53 +01:00
|
|
|
|
2019-11-11 15:18:32 +01:00
|
|
|
} else {
|
|
|
|
p.fgen(comment)
|
2019-12-06 13:24:53 +01:00
|
|
|
}
|
2019-11-18 11:10:31 +01:00
|
|
|
if next.tok == .line_comment && comment_token.line_nr < next.line_nr {
|
|
|
|
p.fgen_nl()
|
2019-11-11 15:18:32 +01:00
|
|
|
}
|
|
|
|
p.token_idx++
|
2019-12-06 13:24:53 +01:00
|
|
|
}
|
|
|
|
|
2019-11-18 11:10:31 +01:00
|
|
|
if inc_indent {
|
|
|
|
p.fgen_nl()
|
2019-12-06 13:24:53 +01:00
|
|
|
}
|
2019-11-11 15:18:32 +01:00
|
|
|
}
|
2019-11-09 17:13:26 +01:00
|
|
|
}
|
|
|
|
|
2019-11-11 06:04:37 +01:00
|
|
|
|
2019-11-09 20:05:44 +01:00
|
|
|
[if vfmt]
|
|
|
|
fn (p mut Parser) gen_fmt() {
|
|
|
|
if p.pass != .main {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if p.file_name == '' {
|
|
|
|
return
|
2019-12-06 13:24:53 +01:00
|
|
|
}
|
2019-11-11 15:18:32 +01:00
|
|
|
//s := p.scanner.fmt_out.str().replace('\n\n\n', '\n').trim_space()
|
2019-11-09 20:05:44 +01:00
|
|
|
s := p.scanner.fmt_out.str().trim_space()
|
2019-11-11 06:04:37 +01:00
|
|
|
//s := p.scanner.fmt_out.join('').trim_space()
|
2019-11-09 20:05:44 +01:00
|
|
|
if s == '' {
|
|
|
|
return
|
2019-12-06 13:24:53 +01:00
|
|
|
}
|
2019-11-18 11:10:31 +01:00
|
|
|
println('generating ${p.file_name}.v')
|
2019-12-01 10:50:13 +01:00
|
|
|
mut out := os.create('/var/tmp/fmt/' + p.file_name) or {
|
2019-11-09 20:05:44 +01:00
|
|
|
verror('failed to create fmt.v')
|
|
|
|
return
|
|
|
|
}
|
2019-11-11 06:04:37 +01:00
|
|
|
out.writeln(s)//p.scanner.fmt_out.str().trim_space())
|
2019-11-09 20:05:44 +01:00
|
|
|
out.close()
|
|
|
|
}
|
|
|
|
|