clean up the parser a bit; run vfmt; add x64 to ci
parent
b815878d60
commit
1e28c1d4fd
|
@ -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:
|
||||
|
|
|
@ -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()} ')
|
||||
|
||||
}
|
|
@ -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") } ')
|
||||
|
||||
}
|
|
@ -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) {
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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'))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue