mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
new vfmt using the new parser
This commit is contained in:
parent
a2838ae6f3
commit
59beec8fae
@ -16,6 +16,15 @@ CastExpr | EnumVal
|
||||
pub type Stmt = VarDecl | GlobalDecl | FnDecl | Return | Module | Import | ExprStmt |
|
||||
ForStmt | StructDecl | ForCStmt | ForInStmt | CompIf | ConstDecl | Attr | BranchStmt |
|
||||
HashStmt | AssignStmt | EnumDecl | TypeDecl | DeferStmt | GotoLabel | GotoStmt
|
||||
|
||||
pub type Type = StructType | ArrayType
|
||||
|
||||
pub struct StructType {
|
||||
fields []Field
|
||||
}
|
||||
|
||||
pub struct ArrayType {}
|
||||
|
||||
// | IncDecStmt k
|
||||
// Stand-alone expression in a statement list.
|
||||
pub struct ExprStmt {
|
||||
@ -72,6 +81,7 @@ pub:
|
||||
// type_idx int
|
||||
mut:
|
||||
typ table.Type
|
||||
// typ2 Type
|
||||
}
|
||||
|
||||
pub struct ConstDecl {
|
||||
@ -387,15 +397,15 @@ pub:
|
||||
vals []string
|
||||
}
|
||||
|
||||
pub struct TypeDecl{
|
||||
pub struct TypeDecl {
|
||||
pub:
|
||||
name string
|
||||
is_pub bool
|
||||
}
|
||||
|
||||
pub struct DeferStmt{
|
||||
pub struct DeferStmt {
|
||||
pub:
|
||||
stmts []Stmt
|
||||
stmts []Stmt
|
||||
}
|
||||
|
||||
pub struct AssignExpr {
|
||||
@ -406,14 +416,14 @@ pub:
|
||||
val Expr
|
||||
}
|
||||
|
||||
pub struct GotoLabel{
|
||||
pub struct GotoLabel {
|
||||
pub:
|
||||
name string
|
||||
name string
|
||||
}
|
||||
|
||||
pub struct GotoStmt {
|
||||
pub:
|
||||
name string
|
||||
name string
|
||||
}
|
||||
|
||||
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.
|
||||
module fmt
|
||||
|
||||
import (
|
||||
v.ast
|
||||
v.table
|
||||
strings
|
||||
)
|
||||
|
||||
const (
|
||||
tabs = ['', '\t', '\t\t', '\t\t\t', '\t\t\t\t']
|
||||
// tabs = ['', ' ', ' ', ' ', ' ']
|
||||
)
|
||||
|
||||
struct Fmt {
|
||||
out strings.Builder
|
||||
table &table.Table
|
||||
mut:
|
||||
indent int
|
||||
empty_line bool
|
||||
/*
|
||||
// vfmt fields TODO move to a separate struct
|
||||
// fmt_out strings.Builder
|
||||
fmt_lines []string
|
||||
@ -11,5 +28,239 @@ struct Fmt {
|
||||
fmt_indent int
|
||||
fmt_line_empty 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(']')
|
||||
}
|
||||
}
|
||||
|
31
vlib/v/fmt/fmt_test.v
Normal file
31
vlib/v/fmt/fmt_test.v
Normal file
@ -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)
|
||||
}
|
||||
}
|
37
vlib/v/fmt/tests/1.vv
Normal file
37
vlib/v/fmt/tests/1.vv
Normal file
@ -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
|
||||
}
|
0
vlib/v/fmt/tests/1_out.vv
Normal file
0
vlib/v/fmt/tests/1_out.vv
Normal file
@ -24,10 +24,7 @@ pub fn cgen(files []ast.File, table &table.Table) string {
|
||||
fn_decl: 0
|
||||
}
|
||||
for file in files {
|
||||
for stmt in file.stmts {
|
||||
g.stmt(stmt)
|
||||
g.writeln('')
|
||||
}
|
||||
g.stmts(file.stmts)
|
||||
}
|
||||
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 {
|
||||
arg_type_sym := g.table.get_type_symbol(arg.typ)
|
||||
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'
|
||||
}
|
||||
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) {
|
||||
// println('cgen expr()')
|
||||
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 {
|
||||
g.expr(it.left)
|
||||
g.write(' $it.op.str() ')
|
||||
g.expr(it.val)
|
||||
}
|
||||
ast.BoolLiteral {
|
||||
g.write(it.val.str())
|
||||
}
|
||||
ast.IntegerLiteral {
|
||||
g.write(it.val.str())
|
||||
}
|
||||
@ -263,26 +272,9 @@ fn (g mut Gen) expr(node ast.Expr) {
|
||||
g.write(')')
|
||||
}
|
||||
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 {
|
||||
g.write('$it.name')
|
||||
}
|
||||
ast.BoolLiteral {
|
||||
if it.val == true {
|
||||
g.write('true')
|
||||
}
|
||||
else {
|
||||
g.write('false')
|
||||
}
|
||||
}
|
||||
ast.SelectorExpr {
|
||||
g.expr(it.expr)
|
||||
g.write('.')
|
||||
|
Loading…
Reference in New Issue
Block a user