clean up the parser a bit; run vfmt; add x64 to ci

pull/3354/head
Alexander Medvednikov 2020-01-06 23:15:37 +01:00
parent b815878d60
commit 1e28c1d4fd
9 changed files with 186 additions and 212 deletions

View File

@ -120,7 +120,16 @@ jobs:
- name: Freestanding - name: Freestanding
run: ./v -freestanding -o bare vlib/os/bare/bare_example_linux.v run: ./v -freestanding -o bare vlib/os/bare/bare_example_linux.v
- name: x64 machine code generation - name: x64 machine code generation
run: echo "TODO" #cd examples/x64 && ../../v -x64 hello_world.v && ./hello_world run: |
./v -o vprod -prod v.v
cd tools
echo "Generating a 1m line V file..."
../vprod run gen1m.v > 1m.v
echo "Building it..."
../vprod -x64 1m.v
echo "Running it..."
./1m
#run: echo "TODO" #cd examples/x64 && ../../v -x64 hello_world.v && ./hello_world
ubuntu-prebuilt: ubuntu-prebuilt:

View File

@ -1,16 +0,0 @@
fn main() {
for i in 0..10000 {
println('
fn foo${i}() {
x := $i
mut a := x
a += 2
println(a)
a = 0
a = 1
}
')
}
println('fn main() {foo1()} ')
}

19
tools/gen1m.v 100644
View File

@ -0,0 +1,19 @@
fn main() {
println('fn println(a int) {}')
println('fn print(a string) {}')
for i in 0..100000 {
println('
fn foo${i}() {
x := $i
mut a := x
a += 2
println(a)
a = 0
a = 1
}
')
}
//println('fn main() {foo1()} ')
println('fn main() { print("1m DONE") } ')
}

View File

@ -840,7 +840,7 @@ fn (p mut Parser) type_decl() {
//println('child=$child_type_name parent=$name') //println('child=$child_type_name parent=$name')
mut t := p.find_type(child_type_name) mut t := p.find_type(child_type_name)
if t.name == '' { if t.name == '' {
p.error('qunknown type `$child_type_name`') p.error('unknown type `$child_type_name`')
} }
t.parent = name t.parent = name
p.table.rewrite_type(t) p.table.rewrite_type(t)
@ -3107,13 +3107,13 @@ fn (p mut Parser) check_unused_imports() {
if output == '' { if output == '' {
return return
} }
// the imports are usually at the start of the file // the imports are usually at the start of the file
//p.production_error_with_token_index('the following imports were never used: $output', 0) //p.production_error_with_token_index('the following imports were never used: $output', 0)
if p.pref.is_verbose { if p.pref.is_verbose {
eprintln('Used imports table: ${p.import_table.used_imports.str()}') eprintln('Used imports table: ${p.import_table.used_imports.str()}')
} }
p.warn('the following imports were never used: $output') p.warn('the following imports were never used: $output')
} }
fn (p &Parser) is_expr_fn_call(start_tok_idx int) (bool,string) { fn (p &Parser) is_expr_fn_call(start_tok_idx int) (bool,string) {

View File

@ -11,7 +11,7 @@ import (
pub type Expr = BinaryExpr | UnaryExpr | IfExpr | StringLiteral | IntegerLiteral | pub type Expr = BinaryExpr | UnaryExpr | IfExpr | StringLiteral | IntegerLiteral |
FloatLiteral | Ident | CallExpr | BoolLiteral | StructInit | ArrayInit | SelectorExpr | PostfixExpr | AssignExpr | PrefixExpr FloatLiteral | Ident | CallExpr | BoolLiteral | StructInit | ArrayInit | SelectorExpr | PostfixExpr | AssignExpr | PrefixExpr
pub type Stmt = VarDecl | FnDecl | Return | Module | Import | ExprStmt | AssignStmt | pub type Stmt = VarDecl | FnDecl | Return | Module | Import | ExprStmt |
ForStmt | StructDecl ForStmt | StructDecl
// | IncDecStmt k // | IncDecStmt k
// Stand-alone expression in a statement list. // Stand-alone expression in a statement list.
@ -72,7 +72,7 @@ pub:
pub struct StructInit { pub struct StructInit {
pub: pub:
// typ types.TypeIdent // typ types.TypeIdent
ti types.TypeIdent ti types.TypeIdent
fields []string fields []string
exprs []Expr exprs []Expr
@ -203,12 +203,15 @@ pub struct ReturnStmt {
results []Expr results []Expr
} }
/*
pub struct AssignStmt { pub struct AssignStmt {
pub: pub:
left Expr left Expr
right Expr right Expr
op token.Kind op token.Kind
} }
*/
pub struct AssignExpr { pub struct AssignExpr {
pub: pub:

View File

@ -43,17 +43,7 @@ fn (g mut Gen) stmt(node ast.Stmt) {
// println('cgen.stmt()') // println('cgen.stmt()')
// g.writeln('//// stmt start') // g.writeln('//// stmt start')
match node { match node {
ast.Import { ast.Import {}
}
/*
ast.AssignStmt {
g.expr(it.left)
g.write(' $it.op.str() ')
g.expr(it.right)
g.writeln(';')
}
*/
ast.FnDecl { ast.FnDecl {
is_main := it.name == 'main' is_main := it.name == 'main'
if is_main { if is_main {

View File

@ -33,12 +33,6 @@ pub fn (g mut JsGen) writeln(s string) {
fn (g mut JsGen) stmt(node ast.Stmt) { fn (g mut JsGen) stmt(node ast.Stmt) {
match node { match node {
ast.AssignStmt {
g.expr(it.left)
g.write(' $it.op.str() ')
g.expr(it.right)
g.writeln(';')
}
ast.FnDecl { ast.FnDecl {
g.write('/** @return { $it.ti.name } **/\nfunction ${it.name}(') g.write('/** @return { $it.ti.name } **/\nfunction ${it.name}(')
for arg in it.args { for arg in it.args {

View File

@ -310,12 +310,6 @@ pub fn (g mut Gen) call_fn(name string) {
fn (g mut Gen) stmt(node ast.Stmt) { fn (g mut Gen) stmt(node ast.Stmt) {
match node { match node {
ast.AssignStmt {
g.expr(it.left)
g.write(' $it.op.str() ')
g.expr(it.right)
g.writeln(';')
}
ast.FnDecl { ast.FnDecl {
is_main := it.name == 'main' is_main := it.name == 'main'
if is_main { if is_main {
@ -332,44 +326,19 @@ fn (g mut Gen) stmt(node ast.Stmt) {
g.ret() g.ret()
} }
ast.Return { ast.Return {
g.write('return ')
g.expr(it.expr)
g.writeln(';')
} }
ast.VarDecl { ast.VarDecl {
g.write('$it.ti.name $it.name = ')
g.expr(it.expr)
g.writeln(';')
} }
ast.ForStmt { ast.ForStmt {
if it.is_in {} if it.is_in {}
g.write('while (')
g.expr(it.cond)
g.writeln(') {')
for stmt in it.stmts {
g.stmt(stmt)
}
g.writeln('}')
} }
ast.StructDecl { ast.StructDecl {
g.writeln('typedef struct {')
for field in it.fields {
g.writeln('\t$field.ti.name $field.name;')
}
g.writeln('} $it.name;')
} }
ast.ExprStmt { ast.ExprStmt {
g.expr(it.expr) g.expr(it.expr)
match it.expr {
// no ; after an if expression
ast.IfExpr {}
else {
g.writeln(';')
}
}
} }
else { else {
verror('cgen.stmt(): bad node') verror('x64.stmt(): bad node')
} }
} }
} }
@ -377,37 +346,16 @@ 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.IntegerLiteral { ast.AssignExpr {}
g.write(it.val.str()) ast.IntegerLiteral {}
} ast.FloatLiteral {}
ast.FloatLiteral {
g.write(it.val)
}
ast.UnaryExpr { ast.UnaryExpr {
g.expr(it.left) g.expr(it.left)
g.write(it.op.str())
}
ast.StringLiteral {
g.write('tos3("$it.val")')
}
ast.BinaryExpr {
g.expr(it.left)
g.write(' $it.op.str() ')
g.expr(it.right)
// if ti.type_name != typ2.name {
// verror('bad types $ti.type_name $typ2.name')
// }
} }
ast.StringLiteral {}
ast.BinaryExpr {}
// `user := User{name: 'Bob'}` // `user := User{name: 'Bob'}`
ast.StructInit { ast.StructInit {}
g.writeln('($it.ti.name){')
for i, field in it.fields {
g.write('\t.$field = ')
g.expr(it.exprs[i])
g.writeln(', ')
}
g.write('}')
}
ast.CallExpr { ast.CallExpr {
if it.name == 'println' || it.name == 'print' { if it.name == 'println' || it.name == 'print' {
expr := it.args[0] expr := it.args[0]
@ -425,43 +373,12 @@ fn (g mut Gen) expr(node ast.Expr) {
*/ */
} }
ast.ArrayInit { ast.ArrayInit {}
g.writeln('new_array_from_c_array($it.exprs.len, $it.exprs.len, sizeof($it.ti.name), {\t') ast.Ident {}
for expr in it.exprs { ast.BoolLiteral {}
g.expr(expr) ast.IfExpr {}
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.IfExpr {
g.write('if (')
g.expr(it.cond)
g.writeln(') {')
for stmt in it.stmts {
g.stmt(stmt)
}
g.writeln('}')
if it.else_stmts.len > 0 {
g.writeln('else { ')
for stmt in it.else_stmts {
g.stmt(stmt)
}
g.writeln('}')
}
}
else { else {
println(term.red('cgen.expr(): bad node')) //println(term.red('x64.expr(): bad node'))
} }
} }
} }

View File

@ -4,7 +4,7 @@
module types module types
pub enum Kind { pub enum Kind {
_placeholder, _placeholder
_void, _void,
_voidptr, _voidptr,
_charptr, _charptr,
@ -32,17 +32,20 @@ pub enum Kind {
_variadic _variadic
} }
pub type Type = Placeholder | Void | Voidptr | Charptr | Byteptr | Const | Enum | Struct |
Int | Float | String | Char | Byte | Bool | Array | ArrayFixed | Map | MultiReturn | Variadic
pub struct TypeIdent { pub struct TypeIdent {
pub: pub:
idx int idx int
kind Kind kind Kind
name string name string
nr_muls int nr_muls int
} }
[inline] [inline]
pub fn new_ti(kind Kind, name string, idx int, nr_muls int) TypeIdent { pub fn new_ti(kind Kind, name string, idx int, nr_muls int) TypeIdent {
return TypeIdent{ return TypeIdent{
idx: idx idx: idx
kind: kind kind: kind
name: name name: name
@ -52,7 +55,7 @@ pub fn new_ti(kind Kind, name string, idx int, nr_muls int) TypeIdent {
[inline] [inline]
pub fn new_base_ti(kind Kind, nr_muls int) TypeIdent { pub fn new_base_ti(kind Kind, nr_muls int) TypeIdent {
return TypeIdent{ return TypeIdent{
kind: kind kind: kind
name: kind.str() name: kind.str()
nr_muls: nr_muls nr_muls: nr_muls
@ -61,22 +64,22 @@ pub fn new_base_ti(kind Kind, nr_muls int) TypeIdent {
[inline] [inline]
pub fn (ti &TypeIdent) is_ptr() bool { pub fn (ti &TypeIdent) is_ptr() bool {
return ti.nr_muls > 0 return ti.nr_muls > 0
} }
[inline] [inline]
pub fn (ti &TypeIdent) is_int() bool { pub fn (ti &TypeIdent) is_int() bool {
return ti.kind in [._i8, ._i16, ._int, ._i64, ._byte, ._u16, ._u32, ._u64] return ti.kind in [._i8, ._i16, ._int, ._i64, ._byte, ._u16, ._u32, ._u64]
} }
[inline] [inline]
pub fn (ti &TypeIdent) is_float() bool { pub fn (ti &TypeIdent) is_float() bool {
return ti.kind in [._f32, ._f64] return ti.kind in [._f32, ._f64]
} }
[inline] [inline]
pub fn (ti &TypeIdent) is_number() bool { pub fn (ti &TypeIdent) is_number() bool {
return ti.is_int() || ti.is_float() return ti.is_int() || ti.is_float()
} }
pub fn (ti &TypeIdent) str() string { pub fn (ti &TypeIdent) str() string {
@ -92,81 +95,80 @@ pub fn check(got, expected &TypeIdent) bool {
pub fn (k Kind) str() string { pub fn (k Kind) str() string {
k_str := match k { k_str := match k {
._placeholder { ._placeholder{
'placeholder' 'placeholder'
} }
._void { ._void{
'void' 'void'
} }
._voidptr { ._voidptr{
'voidptr' 'voidptr'
} }
._charptr { ._charptr{
'charptr' 'charptr'
} }
._byteptr { ._byteptr{
'byteptr' 'byteptr'
} }
._const { ._const{
'const' 'const'
} }
._enum { ._enum{
'enum' 'enum'
} }
._struct { ._struct{
'struct' 'struct'
} }
._int { ._int{
'int' 'int'
} }
._i8 { ._i8{
'i8' 'i8'
} }
._i16 { ._i16{
'i16' 'i16'
} }
._i64 { ._i64{
'i64' 'i64'
} }
._byte { ._byte{
'byte' 'byte'
} }
._u16 { ._u16{
'u18' 'u18'
} }
._f32 { ._f32{
'f32' 'f32'
} }
._f64 { ._f64{
'f64' 'f64'
} }
._string { ._string{
'string' 'string'
} }
._char { ._char{
'char' 'char'
} }
._bool { ._bool{
'bool' 'bool'
} }
._array { ._array{
'array' 'array'
} }
._array_fixed { ._array_fixed{
'array_fixed' 'array_fixed'
} }
._map { ._map{
'map' 'map'
} }
._multi_return { ._multi_return{
'multi_return' 'multi_return'
} }
._variadic { ._variadic{
'variadic' 'variadic'
} }
else { else {
'unknown' 'unknown'}
}
} }
return k_str return k_str
} }
@ -175,17 +177,13 @@ pub fn (kinds []Kind) str() string {
mut kinds_str := '' mut kinds_str := ''
for i, k in kinds { for i, k in kinds {
kinds_str += k.str() kinds_str += k.str()
if i < kinds.len-1 { if i < kinds.len - 1 {
kinds_str += '_' kinds_str += '_'
} }
} }
return kinds_str return kinds_str
} }
pub type Type = Placeholder | Void | Voidptr | Charptr | Byteptr | Const | Enum | Struct |
Int | Float | String | Char | Byte | Bool | Array | ArrayFixed | Map | MultiReturn | Variadic
pub struct Placeholder { pub struct Placeholder {
pub: pub:
idx int idx int
@ -270,7 +268,7 @@ pub:
idx int idx int
name string name string
key_type_kind Kind key_type_kind Kind
key_type_idx int key_type_idx int
value_type_kind Kind value_type_kind Kind
value_type_idx int value_type_idx int
} }
@ -290,47 +288,107 @@ pub:
type_idx int type_idx int
} }
pub fn (t Void) str() string { return 'void' } pub fn (t Void) str() string {
pub fn (t Voidptr) str() string { return 'voidptr' } return 'void'
pub fn (t Charptr) str() string { return 'charptr' } }
pub fn (t Byteptr) str() string { return 'byteptr' }
pub fn (t Const) str() string { return t.name } pub fn (t Voidptr) str() string {
pub fn (t Enum) str() string { return t.name } return 'voidptr'
pub fn (t Struct) str() string { return t.name } }
pub fn (t Int) str() string { return if t.is_unsigned {'u$t.bit_size' } else { 'i$t.bit_size' } }
pub fn (t Float) str() string { return 'f$t.bit_size' } pub fn (t Charptr) str() string {
pub fn (t String) str() string { return 'string' } return 'charptr'
pub fn (t Char) str() string { return 'char' } }
pub fn (t Byte) str() string { return 'byte' }
pub fn (t Array) str() string { return t.name } pub fn (t Byteptr) str() string {
pub fn (t ArrayFixed) str() string { return t.name } return 'byteptr'
pub fn (t Map) str() string { return t.name } }
pub fn (t MultiReturn) str() string { return t.name }
pub fn (t Variadic) str() string { return 'variadic_$t.type_kind.str()' } pub fn (t Const) str() string {
return t.name
}
pub fn (t Enum) str() string {
return t.name
}
pub fn (t Struct) str() string {
return t.name
}
pub fn (t Int) str() string {
return if t.is_unsigned { 'u$t.bit_size' } else { 'i$t.bit_size' }
}
pub fn (t Float) str() string {
return 'f$t.bit_size'
}
pub fn (t String) str() string {
return 'string'
}
pub fn (t Char) str() string {
return 'char'
}
pub fn (t Byte) str() string {
return 'byte'
}
pub fn (t Array) str() string {
return t.name
}
pub fn (t ArrayFixed) str() string {
return t.name
}
pub fn (t Map) str() string {
return t.name
}
pub fn (t MultiReturn) str() string {
return t.name
}
pub fn (t Variadic) str() string {
return 'variadic_$t.type_kind.str()'
}
pub const ( pub const (
void_type = Void{} void_type = Void{}
voidptr_type = Voidptr{} voidptr_type = Voidptr{}
charptr_type = Charptr{} charptr_type = Charptr{}
byteptr_type = Byteptr{} byteptr_type = Byteptr{}
i8_type = Int{8, false} i8_type = Int{
i16_type = Int{16, false} 8,false}
int_type = Int{32, false} i16_type = Int{
i64_type = Int{64, false} 16,false}
byte_type = Int{8, true} int_type = Int{
u16_type = Int{16, true} 32,false}
u32_type = Int{32, true} i64_type = Int{
u64_type = Int{64, true} 64,false}
f32_type = Float{32} byte_type = Int{
f64_type = Float{64} 8,true}
string_type = String{} u16_type = Int{
char_type = Char{} 16,true}
bool_type = Bool{} u32_type = Int{
32,true}
u64_type = Int{
64,true}
f32_type = Float{
32}
f64_type = Float{
64}
string_type = String{}
char_type = Char{}
bool_type = Bool{}
) )
pub const ( pub const (
void_ti = new_base_ti(._void, 0) void_ti = new_base_ti(._void, 0)
int_ti = new_base_ti(._int, 0) int_ti = new_base_ti(._int, 0)
string_ti = new_base_ti(._string, 0) string_ti = new_base_ti(._string, 0)
bool_ti = new_base_ti(._bool, 0) bool_ti = new_base_ti(._bool, 0)
) )