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
run: ./v -freestanding -o bare vlib/os/bare/bare_example_linux.v
- 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:

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')
mut t := p.find_type(child_type_name)
if t.name == '' {
p.error('qunknown type `$child_type_name`')
p.error('unknown type `$child_type_name`')
}
t.parent = name
p.table.rewrite_type(t)
@ -3107,13 +3107,13 @@ fn (p mut Parser) check_unused_imports() {
if output == '' {
return
}
// the imports are usually at the start of the file
//p.production_error_with_token_index('the following imports were never used: $output', 0)
if p.pref.is_verbose {
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) {

View File

@ -11,7 +11,7 @@ import (
pub type Expr = BinaryExpr | UnaryExpr | IfExpr | StringLiteral | IntegerLiteral |
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
// | IncDecStmt k
// Stand-alone expression in a statement list.
@ -72,7 +72,7 @@ pub:
pub struct StructInit {
pub:
// typ types.TypeIdent
// typ types.TypeIdent
ti types.TypeIdent
fields []string
exprs []Expr
@ -203,12 +203,15 @@ pub struct ReturnStmt {
results []Expr
}
/*
pub struct AssignStmt {
pub:
left Expr
right Expr
op token.Kind
}
*/
pub struct AssignExpr {
pub:

View File

@ -43,17 +43,7 @@ fn (g mut Gen) stmt(node ast.Stmt) {
// println('cgen.stmt()')
// g.writeln('//// stmt start')
match node {
ast.Import {
}
/*
ast.AssignStmt {
g.expr(it.left)
g.write(' $it.op.str() ')
g.expr(it.right)
g.writeln(';')
}
*/
ast.Import {}
ast.FnDecl {
is_main := it.name == '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) {
match node {
ast.AssignStmt {
g.expr(it.left)
g.write(' $it.op.str() ')
g.expr(it.right)
g.writeln(';')
}
ast.FnDecl {
g.write('/** @return { $it.ti.name } **/\nfunction ${it.name}(')
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) {
match node {
ast.AssignStmt {
g.expr(it.left)
g.write(' $it.op.str() ')
g.expr(it.right)
g.writeln(';')
}
ast.FnDecl {
is_main := it.name == 'main'
if is_main {
@ -332,44 +326,19 @@ fn (g mut Gen) stmt(node ast.Stmt) {
g.ret()
}
ast.Return {
g.write('return ')
g.expr(it.expr)
g.writeln(';')
}
ast.VarDecl {
g.write('$it.ti.name $it.name = ')
g.expr(it.expr)
g.writeln(';')
}
ast.ForStmt {
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 {
g.writeln('typedef struct {')
for field in it.fields {
g.writeln('\t$field.ti.name $field.name;')
}
g.writeln('} $it.name;')
}
ast.ExprStmt {
g.expr(it.expr)
match it.expr {
// no ; after an if expression
ast.IfExpr {}
else {
g.writeln(';')
}
}
}
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) {
// println('cgen expr()')
match node {
ast.IntegerLiteral {
g.write(it.val.str())
}
ast.FloatLiteral {
g.write(it.val)
}
ast.AssignExpr {}
ast.IntegerLiteral {}
ast.FloatLiteral {}
ast.UnaryExpr {
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'}`
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.StructInit {}
ast.CallExpr {
if it.name == 'println' || it.name == 'print' {
expr := it.args[0]
@ -425,43 +373,12 @@ fn (g mut Gen) expr(node ast.Expr) {
*/
}
ast.ArrayInit {
g.writeln('new_array_from_c_array($it.exprs.len, $it.exprs.len, sizeof($it.ti.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.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('}')
}
}
ast.ArrayInit {}
ast.Ident {}
ast.BoolLiteral {}
ast.IfExpr {}
else {
println(term.red('cgen.expr(): bad node'))
//println(term.red('x64.expr(): bad node'))
}
}
}

View File

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