parse_files(); ast.File

pull/3280/head
Alexander Medvednikov 2019-12-30 12:10:46 +01:00
parent d2f2ac523f
commit 093a025ebf
8 changed files with 93 additions and 20 deletions

1
v.v
View File

@ -8,6 +8,7 @@ import (
benchmark benchmark
os os
filepath filepath
//v.types
// time // time
) )

View File

@ -9,6 +9,10 @@ import (
strings strings
filepath filepath
compiler.x64 compiler.x64
//v.table
//v.parser
//v.gen
//v.types
) )
pub const ( pub const (
@ -25,7 +29,8 @@ enum BuildMode {
} }
const ( const (
supported_platforms = ['windows', 'mac', 'macos', 'linux', 'freebsd', 'openbsd', 'netbsd', 'dragonfly', 'android', 'js', 'solaris', 'haiku'] supported_platforms = ['windows', 'mac', 'macos', 'linux', 'freebsd', 'openbsd', 'netbsd',
'dragonfly', 'android', 'js', 'solaris', 'haiku']
) )
enum OS { enum OS {
@ -373,6 +378,43 @@ pub fn (v mut V) compile() {
v.cc() v.cc()
} }
/*
pub fn (v mut V) compile2() {
if os.user_os() != 'windows' && v.pref.ccompiler == 'msvc' {
verror('Cannot build with msvc on ${os.user_os()}')
}
//cgen.genln('// Generated by V')
println('compile2()')
if v.pref.is_verbose {
println('all .v files before:')
println(v.files)
}
v.add_v_files_to_compile()
if v.pref.is_verbose {
println('all .v files:')
println(v.files)
}
table := &table.Table{}
files := parser.parse_files(v.files, table)
c := gen.cgen(files)
println('out: $v.out_name_c')
os.write_file(v.out_name_c, c)
/*
cgen.genln(c_builtin_types)
if !v.pref.is_bare {
cgen.genln(c_headers)
}
else {
cgen.genln(bare_c_headers)
}
}
*/
v.cc()
}
*/
pub fn (v mut V) compile_x64() { pub fn (v mut V) compile_x64() {
$if !linux { $if !linux {
println('v -x64 can only generate Linux binaries for now') println('v -x64 can only generate Linux binaries for now')
@ -513,7 +555,7 @@ pub fn (v mut V) generate_main() {
else if v.v_fmt_file=='' && !v.pref.is_repl { else if v.v_fmt_file=='' && !v.pref.is_repl {
verror('function `main` is not declared in the main module') verror('function `main` is not declared in the main module')
} }
} }
else if v.pref.is_test { else if v.pref.is_test {
if v.table.main_exists() { if v.table.main_exists() {
verror('test files cannot have function `main`') verror('test files cannot have function `main`')

View File

@ -8,10 +8,10 @@ import (
v.types v.types
) )
pub type Expr = BinaryExpr | UnaryExpr | IfExpr | StringLiteral | IntegerLiteral | pub type Expr = BinaryExpr | UnaryExpr | IfExpr | StringLiteral | IntegerLiteral |
FloatLiteral | Ident | CallExpr | BoolLiteral | StructInit | ArrayInit FloatLiteral | Ident | CallExpr | BoolLiteral | StructInit | ArrayInit
pub type Stmt = VarDecl | FnDecl | Return | Module | Import | ExprStmt | AssignStmt | pub type Stmt = VarDecl | FnDecl | Return | Module | Import | ExprStmt | AssignStmt |
ForStmt | StructDecl ForStmt | StructDecl
// Stand-alone expression in a statement list. // Stand-alone expression in a statement list.
pub struct ExprStmt { pub struct ExprStmt {
@ -123,7 +123,7 @@ pub:
typ types.Type typ types.Type
} }
pub struct Program { pub struct File {
pub: pub:
stmts []Stmt stmts []Stmt
} }

View File

@ -10,15 +10,17 @@ struct Gen {
out strings.Builder out strings.Builder
} }
pub fn cgen(program ast.Program) string { pub fn cgen(files []ast.File) string {
mut g := Gen{ mut g := Gen{
out: strings.new_builder(100) out: strings.new_builder(100)
} }
for stmt in program.stmts { for file in files {
g.stmt(stmt) for stmt in file.stmts {
g.writeln('') g.stmt(stmt)
g.writeln('')
}
} }
return (g.out.str()) return g.out.str()
} }
pub fn (g &Gen) save() {} pub fn (g &Gen) save() {}

View File

@ -25,7 +25,7 @@ fn test_c_files() {
} }
table := &table.Table{} table := &table.Table{}
program := parser.parse_file(text, table) program := parser.parse_file(text, table)
res := gen.cgen(program) res := gen.cgen([program])
if compare_texts(res, ctext) { if compare_texts(res, ctext) {
eprintln('${i}... ' + term.green('OK')) eprintln('${i}... ' + term.green('OK'))
} }

View File

@ -10,7 +10,7 @@ struct JsGen {
out strings.Builder out strings.Builder
} }
pub fn jsgen(program ast.Program) string { pub fn jsgen(program ast.File) string {
mut g := JsGen{ mut g := JsGen{
out: strings.new_builder(100) out: strings.new_builder(100)
} }

View File

@ -10,6 +10,7 @@ import (
v.table v.table
v.types v.types
term term
os
) )
struct Parser { struct Parser {
@ -57,7 +58,7 @@ pub fn (p mut Parser) get_type() types.Type {
} }
} }
pub fn parse_file(text string, table &table.Table) ast.Program { pub fn parse_file(text string, table &table.Table) ast.File {
mut stmts := []ast.Stmt mut stmts := []ast.Stmt
mut p := Parser{ mut p := Parser{
scanner: scanner.new_scanner(text) scanner: scanner.new_scanner(text)
@ -76,11 +77,40 @@ pub fn parse_file(text string, table &table.Table) ast.Program {
} }
// println('nr stmts = $stmts.len') // println('nr stmts = $stmts.len')
// println(stmts[0]) // println(stmts[0])
return ast.Program{ return ast.File{
stmts: stmts stmts: stmts
} }
} }
pub fn parse_files(paths []string, table &table.Table) []ast.File {
mut files := []ast.File
for path in paths {
mut stmts := []ast.Stmt
text := os.read_file(path) or { panic(err) }
mut p := Parser{
scanner: scanner.new_scanner(text)
table: table
}
p.read_first_token()
for {
// res := s.scan()
if p.tok.kind == .eof {
break
}
// println('expr at ' + p.tok.str())
s := p.stmt()
// println(s)
stmts << s // p.stmt()
}
// println('nr stmts = $stmts.len')
// println(stmts[0])
files << ast.File{
stmts: stmts
}
}
return files
}
pub fn (p mut Parser) read_first_token() { pub fn (p mut Parser) read_first_token() {
// need to call next() twice to get peek token and current token // need to call next() twice to get peek token and current token
p.next() p.next()
@ -452,8 +482,8 @@ fn (p mut Parser) parse_number_literal() (ast.Expr,types.Type) {
return node,typ return node,typ
} }
fn (p mut Parser) module_decl() ast.Stmt { fn (p mut Parser) module_decl() ast.Module {
// p.check(.key_module) p.check(.key_module)
p.next() p.next()
return ast.Module{} return ast.Module{}
} }
@ -520,7 +550,6 @@ fn (p mut Parser) fn_decl() ast.FnDecl {
name: name name: name
args: args args: args
}) })
// p.check(.rcbr)
stmts := p.parse_block() stmts := p.parse_block()
return ast.FnDecl{ return ast.FnDecl{
name: name name: name
@ -531,7 +560,6 @@ fn (p mut Parser) fn_decl() ast.FnDecl {
} }
fn (p mut Parser) return_stmt() ast.Return { fn (p mut Parser) return_stmt() ast.Return {
// println('return st')
p.next() p.next()
expr,t := p.expr(0) expr,t := p.expr(0)
if !types.check(p.return_type, t) { if !types.check(p.return_type, t) {
@ -568,7 +596,7 @@ fn (p mut Parser) var_decl() ast.VarDecl {
return ast.VarDecl{ return ast.VarDecl{
name: name name: name
expr: expr // p.expr(token.lowest_prec) expr: expr // p.expr(token.lowest_prec)
typ: t typ: t
} }
} }

View File

@ -76,7 +76,7 @@ fn test_parse_expr() {
for s in input { for s in input {
e << parse_stmt(s, table) e << parse_stmt(s, table)
} }
program := ast.Program{ program := ast.File{
stmts: e stmts: e
} }
res := gen.cgen(program) res := gen.cgen(program)