new vfmt using the new parser
parent
a2838ae6f3
commit
59beec8fae
|
@ -16,6 +16,15 @@ CastExpr | EnumVal
|
||||||
pub type Stmt = VarDecl | GlobalDecl | FnDecl | Return | Module | Import | ExprStmt |
|
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 | AssignStmt | EnumDecl | TypeDecl | DeferStmt | GotoLabel | GotoStmt
|
HashStmt | AssignStmt | EnumDecl | TypeDecl | DeferStmt | GotoLabel | GotoStmt
|
||||||
|
|
||||||
|
pub type Type = StructType | ArrayType
|
||||||
|
|
||||||
|
pub struct StructType {
|
||||||
|
fields []Field
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ArrayType {}
|
||||||
|
|
||||||
// | IncDecStmt k
|
// | IncDecStmt k
|
||||||
// Stand-alone expression in a statement list.
|
// Stand-alone expression in a statement list.
|
||||||
pub struct ExprStmt {
|
pub struct ExprStmt {
|
||||||
|
@ -72,6 +81,7 @@ pub:
|
||||||
// type_idx int
|
// type_idx int
|
||||||
mut:
|
mut:
|
||||||
typ table.Type
|
typ table.Type
|
||||||
|
// typ2 Type
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ConstDecl {
|
pub struct ConstDecl {
|
||||||
|
@ -194,11 +204,11 @@ pub:
|
||||||
|
|
||||||
pub struct File {
|
pub struct File {
|
||||||
pub:
|
pub:
|
||||||
path string
|
path string
|
||||||
mod Module
|
mod Module
|
||||||
imports []Import
|
imports []Import
|
||||||
stmts []Stmt
|
stmts []Stmt
|
||||||
scope Scope
|
scope Scope
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct IdentFunc {
|
pub struct IdentFunc {
|
||||||
|
@ -387,15 +397,15 @@ pub:
|
||||||
vals []string
|
vals []string
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TypeDecl{
|
pub struct TypeDecl {
|
||||||
pub:
|
pub:
|
||||||
name string
|
name string
|
||||||
is_pub bool
|
is_pub bool
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DeferStmt{
|
pub struct DeferStmt {
|
||||||
pub:
|
pub:
|
||||||
stmts []Stmt
|
stmts []Stmt
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct AssignExpr {
|
pub struct AssignExpr {
|
||||||
|
@ -406,14 +416,14 @@ pub:
|
||||||
val Expr
|
val Expr
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct GotoLabel{
|
pub struct GotoLabel {
|
||||||
pub:
|
pub:
|
||||||
name string
|
name string
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct GotoStmt {
|
pub struct GotoStmt {
|
||||||
pub:
|
pub:
|
||||||
name string
|
name string
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ArrayInit {
|
pub struct ArrayInit {
|
||||||
|
|
251
vlib/v/fmt/fmt.v
251
vlib/v/fmt/fmt.v
|
@ -3,7 +3,24 @@
|
||||||
// that can be found in the LICENSE file.
|
// that can be found in the LICENSE file.
|
||||||
module fmt
|
module fmt
|
||||||
|
|
||||||
|
import (
|
||||||
|
v.ast
|
||||||
|
v.table
|
||||||
|
strings
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
tabs = ['', '\t', '\t\t', '\t\t\t', '\t\t\t\t']
|
||||||
|
// tabs = ['', ' ', ' ', ' ', ' ']
|
||||||
|
)
|
||||||
|
|
||||||
struct Fmt {
|
struct Fmt {
|
||||||
|
out strings.Builder
|
||||||
|
table &table.Table
|
||||||
|
mut:
|
||||||
|
indent int
|
||||||
|
empty_line bool
|
||||||
|
/*
|
||||||
// vfmt fields TODO move to a separate struct
|
// vfmt fields TODO move to a separate struct
|
||||||
// fmt_out strings.Builder
|
// fmt_out strings.Builder
|
||||||
fmt_lines []string
|
fmt_lines []string
|
||||||
|
@ -11,5 +28,239 @@ struct Fmt {
|
||||||
fmt_indent int
|
fmt_indent int
|
||||||
fmt_line_empty bool
|
fmt_line_empty bool
|
||||||
// fmt_needs_nl bool
|
// fmt_needs_nl bool
|
||||||
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn fmt(file ast.File, table &table.Table) {
|
||||||
|
mut f := Fmt{
|
||||||
|
out: strings.new_builder(1000)
|
||||||
|
table: table
|
||||||
|
indent: -1
|
||||||
|
}
|
||||||
|
f.stmts(file.stmts)
|
||||||
|
println('!!!!!!!!!')
|
||||||
|
println(f.out.str())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (f mut Fmt) write(s string) {
|
||||||
|
if f.indent > 0 && f.empty_line {
|
||||||
|
f.out.write(tabs[f.indent])
|
||||||
|
f.empty_line = false
|
||||||
|
}
|
||||||
|
f.out.write(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (f mut Fmt) writeln(s string) {
|
||||||
|
if f.indent > 0 {
|
||||||
|
println(f.indent.str() + s)
|
||||||
|
f.out.write(tabs[f.indent])
|
||||||
|
}
|
||||||
|
f.out.writeln(s)
|
||||||
|
f.empty_line = true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (f mut Fmt) stmts(stmts []ast.Stmt) {
|
||||||
|
f.indent++
|
||||||
|
for stmt in stmts {
|
||||||
|
f.stmt(stmt)
|
||||||
|
}
|
||||||
|
f.indent--
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (f mut Fmt) stmt(node ast.Stmt) {
|
||||||
|
match node {
|
||||||
|
ast.AssignStmt {
|
||||||
|
for i, left in it.left {
|
||||||
|
f.expr(left)
|
||||||
|
if i < it.left.len - 1 {
|
||||||
|
f.write(', ')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f.write(' = ')
|
||||||
|
for right in it.right {
|
||||||
|
f.expr(right)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ast.ConstDecl {
|
||||||
|
f.writeln('const (')
|
||||||
|
f.indent++
|
||||||
|
for i, field in it.fields {
|
||||||
|
f.write('$field.name = ')
|
||||||
|
f.expr(it.exprs[i])
|
||||||
|
}
|
||||||
|
f.indent--
|
||||||
|
f.writeln('\n)\n')
|
||||||
|
}
|
||||||
|
ast.ExprStmt {
|
||||||
|
f.expr(it.expr)
|
||||||
|
f.writeln('')
|
||||||
|
}
|
||||||
|
ast.FnDecl {
|
||||||
|
f.writeln('fn ${it.name}() {')
|
||||||
|
f.stmts(it.stmts)
|
||||||
|
f.writeln('}\n')
|
||||||
|
}
|
||||||
|
ast.Return {
|
||||||
|
f.write('return')
|
||||||
|
// multiple returns
|
||||||
|
if it.exprs.len > 1 {
|
||||||
|
for i, expr in it.exprs {
|
||||||
|
f.expr(expr)
|
||||||
|
if i < it.exprs.len - 1 {
|
||||||
|
f.write(', ')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// normal return
|
||||||
|
else if it.exprs.len == 1 {
|
||||||
|
f.write(' ')
|
||||||
|
f.expr(it.exprs[0])
|
||||||
|
}
|
||||||
|
f.writeln('')
|
||||||
|
}
|
||||||
|
ast.StructDecl {
|
||||||
|
f.struct_decl(it)
|
||||||
|
}
|
||||||
|
ast.VarDecl {
|
||||||
|
// type_sym := f.table.get_type_symbol(it.typ)
|
||||||
|
if it.is_mut {
|
||||||
|
f.write('mut ')
|
||||||
|
}
|
||||||
|
f.write('$it.name := ')
|
||||||
|
f.expr(it.expr)
|
||||||
|
f.writeln('')
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
println('unknown node')
|
||||||
|
// exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (f mut Fmt) struct_decl(node ast.StructDecl) {
|
||||||
|
f.writeln('struct $node.name {')
|
||||||
|
mut max := 0
|
||||||
|
for field in node.fields {
|
||||||
|
if field.name.len > max {
|
||||||
|
max = field.name.len
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for field in node.fields {
|
||||||
|
field_type_sym := f.table.get_type_symbol(field.typ)
|
||||||
|
f.write('\t$field.name ')
|
||||||
|
f.write(strings.repeat(` `, max - field.name.len))
|
||||||
|
f.writeln('$field_type_sym.name')
|
||||||
|
}
|
||||||
|
f.writeln('}\n')
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (f mut Fmt) expr(node ast.Expr) {
|
||||||
|
match node {
|
||||||
|
ast.ArrayInit {
|
||||||
|
// type_sym := f.table.get_type_symbol(it.typ)
|
||||||
|
f.write('[')
|
||||||
|
for i, expr in it.exprs {
|
||||||
|
f.expr(expr)
|
||||||
|
if i < it.exprs.len - 1 {
|
||||||
|
f.write(', ')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f.write(']')
|
||||||
|
}
|
||||||
|
ast.AssignExpr {
|
||||||
|
f.expr(it.left)
|
||||||
|
f.write(' $it.op.str() ')
|
||||||
|
f.expr(it.val)
|
||||||
|
}
|
||||||
|
ast.BoolLiteral {
|
||||||
|
f.write(it.val.str())
|
||||||
|
}
|
||||||
|
ast.CallExpr {
|
||||||
|
f.write('${it.name}(')
|
||||||
|
for i, expr in it.args {
|
||||||
|
f.expr(expr)
|
||||||
|
if i != it.args.len - 1 {
|
||||||
|
f.write(', ')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f.write(')')
|
||||||
|
}
|
||||||
|
ast.FloatLiteral {
|
||||||
|
f.write(it.val)
|
||||||
|
}
|
||||||
|
ast.IfExpr {
|
||||||
|
f.write('if ')
|
||||||
|
f.expr(it.cond)
|
||||||
|
f.writeln('{')
|
||||||
|
f.stmts(it.stmts)
|
||||||
|
f.writeln('}')
|
||||||
|
if it.else_stmts.len > 0 {
|
||||||
|
f.writeln('else { ')
|
||||||
|
f.stmts(it.else_stmts)
|
||||||
|
f.writeln('}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ast.Ident {
|
||||||
|
f.write('$it.name')
|
||||||
|
}
|
||||||
|
ast.InfixExpr {
|
||||||
|
f.expr(it.left)
|
||||||
|
f.write(' $it.op.str() ')
|
||||||
|
f.expr(it.right)
|
||||||
|
}
|
||||||
|
ast.IndexExpr {
|
||||||
|
f.index_expr(it)
|
||||||
|
}
|
||||||
|
ast.IntegerLiteral {
|
||||||
|
f.write(it.val.str())
|
||||||
|
}
|
||||||
|
ast.PostfixExpr {
|
||||||
|
f.expr(it.expr)
|
||||||
|
f.write(it.op.str())
|
||||||
|
}
|
||||||
|
ast.PrefixExpr {
|
||||||
|
f.write(it.op.str())
|
||||||
|
f.expr(it.right)
|
||||||
|
}
|
||||||
|
ast.SelectorExpr {
|
||||||
|
f.expr(it.expr)
|
||||||
|
f.write('.')
|
||||||
|
f.write(it.field)
|
||||||
|
}
|
||||||
|
ast.StringLiteral {
|
||||||
|
f.write('"$it.val"')
|
||||||
|
}
|
||||||
|
ast.StructInit {
|
||||||
|
type_sym := f.table.get_type_symbol(it.typ)
|
||||||
|
f.writeln('$type_sym.name{')
|
||||||
|
for i, field in it.fields {
|
||||||
|
f.write('\t$field: ')
|
||||||
|
f.expr(it.exprs[i])
|
||||||
|
f.writeln('')
|
||||||
|
}
|
||||||
|
f.write('}')
|
||||||
|
}
|
||||||
|
else {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (f mut Fmt) index_expr(node ast.IndexExpr) {
|
||||||
|
mut is_range := false
|
||||||
|
match node.index {
|
||||||
|
ast.RangeExpr {
|
||||||
|
is_range = true
|
||||||
|
f.expr(node.left)
|
||||||
|
f.write('..')
|
||||||
|
f.expr(it.high)
|
||||||
|
f.write(')')
|
||||||
|
}
|
||||||
|
else {}
|
||||||
|
}
|
||||||
|
if !is_range {
|
||||||
|
f.expr(node.left)
|
||||||
|
f.write('[')
|
||||||
|
f.expr(node.index)
|
||||||
|
f.write(']')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
import (
|
||||||
|
os
|
||||||
|
v.fmt
|
||||||
|
filepath
|
||||||
|
term
|
||||||
|
v.table
|
||||||
|
v.parser
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
nr_tests = 1
|
||||||
|
)
|
||||||
|
|
||||||
|
fn test_fmt() {
|
||||||
|
println('Running vfmt tests')
|
||||||
|
vexe := os.getenv('VEXE')
|
||||||
|
vroot := filepath.dir(vexe)
|
||||||
|
term_ok := term.ok_message('OK')
|
||||||
|
term_fail := term.fail_message('FAIL')
|
||||||
|
for i in 1 .. nr_tests + 1 {
|
||||||
|
path := '$vroot/vlib/v/fmt/tests/${i}.vv'
|
||||||
|
println(path)
|
||||||
|
mut ctext := os.read_file('$vroot/vlib/v/fmt/tests/${i}_out.vv') or {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
ctext = ctext // unused warn
|
||||||
|
table := table.new_table()
|
||||||
|
file := parser.parse_file(path, table)
|
||||||
|
fmt.fmt(file, table)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
fn hello()
|
||||||
|
{
|
||||||
|
mut a:= 3 + 3
|
||||||
|
a = 10
|
||||||
|
a++
|
||||||
|
-23
|
||||||
|
b:= 42
|
||||||
|
println( 'hello' )
|
||||||
|
abc()
|
||||||
|
if true {
|
||||||
|
a = 10
|
||||||
|
a++
|
||||||
|
} else {
|
||||||
|
println('false')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
pi=3.14
|
||||||
|
)
|
||||||
|
|
||||||
|
struct User {
|
||||||
|
name string
|
||||||
|
age int
|
||||||
|
|
||||||
|
very_long_field bool
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn abc() int {
|
||||||
|
mut u := User{name:'Bob'}
|
||||||
|
u.age = 20
|
||||||
|
|
||||||
|
nums := [1,2,3]
|
||||||
|
number := nums[0]
|
||||||
|
return 0
|
||||||
|
}
|
|
@ -24,10 +24,7 @@ pub fn cgen(files []ast.File, table &table.Table) string {
|
||||||
fn_decl: 0
|
fn_decl: 0
|
||||||
}
|
}
|
||||||
for file in files {
|
for file in files {
|
||||||
for stmt in file.stmts {
|
g.stmts(file.stmts)
|
||||||
g.stmt(stmt)
|
|
||||||
g.writeln('')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return g.definitions.str() + g.out.str()
|
return g.definitions.str() + g.out.str()
|
||||||
}
|
}
|
||||||
|
@ -76,7 +73,7 @@ fn (g mut Gen) stmt(node ast.Stmt) {
|
||||||
for i, arg in it.args {
|
for i, arg in it.args {
|
||||||
arg_type_sym := g.table.get_type_symbol(arg.typ)
|
arg_type_sym := g.table.get_type_symbol(arg.typ)
|
||||||
mut arg_type_name := arg_type_sym.name
|
mut arg_type_name := arg_type_sym.name
|
||||||
if i == it.args.len-1 && it.is_variadic {
|
if i == it.args.len - 1 && it.is_variadic {
|
||||||
arg_type_name = 'variadic_$arg_type_sym.name'
|
arg_type_name = 'variadic_$arg_type_sym.name'
|
||||||
}
|
}
|
||||||
g.write(arg_type_name + ' ' + arg.name)
|
g.write(arg_type_name + ' ' + arg.name)
|
||||||
|
@ -194,11 +191,23 @@ fn (g mut Gen) stmt(node ast.Stmt) {
|
||||||
fn (g mut Gen) expr(node ast.Expr) {
|
fn (g mut Gen) expr(node ast.Expr) {
|
||||||
// println('cgen expr()')
|
// println('cgen expr()')
|
||||||
match node {
|
match node {
|
||||||
|
ast.ArrayInit {
|
||||||
|
type_sym := g.table.get_type_symbol(it.typ)
|
||||||
|
g.writeln('new_array_from_c_array($it.exprs.len, $it.exprs.len, sizeof($type_sym.name), {\t')
|
||||||
|
for expr in it.exprs {
|
||||||
|
g.expr(expr)
|
||||||
|
g.write(', ')
|
||||||
|
}
|
||||||
|
g.write('\n})')
|
||||||
|
}
|
||||||
ast.AssignExpr {
|
ast.AssignExpr {
|
||||||
g.expr(it.left)
|
g.expr(it.left)
|
||||||
g.write(' $it.op.str() ')
|
g.write(' $it.op.str() ')
|
||||||
g.expr(it.val)
|
g.expr(it.val)
|
||||||
}
|
}
|
||||||
|
ast.BoolLiteral {
|
||||||
|
g.write(it.val.str())
|
||||||
|
}
|
||||||
ast.IntegerLiteral {
|
ast.IntegerLiteral {
|
||||||
g.write(it.val.str())
|
g.write(it.val.str())
|
||||||
}
|
}
|
||||||
|
@ -263,26 +272,9 @@ fn (g mut Gen) expr(node ast.Expr) {
|
||||||
g.write(')')
|
g.write(')')
|
||||||
}
|
}
|
||||||
ast.MethodCallExpr {}
|
ast.MethodCallExpr {}
|
||||||
ast.ArrayInit {
|
|
||||||
type_sym := g.table.get_type_symbol(it.typ)
|
|
||||||
g.writeln('new_array_from_c_array($it.exprs.len, $it.exprs.len, sizeof($type_sym.name), {\t')
|
|
||||||
for expr in it.exprs {
|
|
||||||
g.expr(expr)
|
|
||||||
g.write(', ')
|
|
||||||
}
|
|
||||||
g.write('\n})')
|
|
||||||
}
|
|
||||||
ast.Ident {
|
ast.Ident {
|
||||||
g.write('$it.name')
|
g.write('$it.name')
|
||||||
}
|
}
|
||||||
ast.BoolLiteral {
|
|
||||||
if it.val == true {
|
|
||||||
g.write('true')
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
g.write('false')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ast.SelectorExpr {
|
ast.SelectorExpr {
|
||||||
g.expr(it.expr)
|
g.expr(it.expr)
|
||||||
g.write('.')
|
g.write('.')
|
||||||
|
|
Loading…
Reference in New Issue