for ;; syntax
parent
1e28c1d4fd
commit
48ea1153a5
|
@ -126,8 +126,9 @@ jobs:
|
||||||
echo "Generating a 1m line V file..."
|
echo "Generating a 1m line V file..."
|
||||||
../vprod run gen1m.v > 1m.v
|
../vprod run gen1m.v > 1m.v
|
||||||
echo "Building it..."
|
echo "Building it..."
|
||||||
../vprod -x64 1m.v
|
../vprod -x64 -o 1m 1m.v
|
||||||
echo "Running it..."
|
echo "Running it..."
|
||||||
|
ls
|
||||||
./1m
|
./1m
|
||||||
#run: echo "TODO" #cd examples/x64 && ../../v -x64 hello_world.v && ./hello_world
|
#run: echo "TODO" #cd examples/x64 && ../../v -x64 hello_world.v && ./hello_world
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,7 @@ fn (a mut array) ensure_cap(required int) {
|
||||||
// repeated `nr_repeat` times
|
// repeated `nr_repeat` times
|
||||||
pub fn (a array) repeat(nr_repeats int) array {
|
pub fn (a array) repeat(nr_repeats int) array {
|
||||||
if nr_repeats < 0 {
|
if nr_repeats < 0 {
|
||||||
panic('array.repeat: count is negative (count == $nr_repeats)')
|
panic('array.repeat: count is negative (count == nr_repeats)')
|
||||||
}
|
}
|
||||||
mut size := nr_repeats * a.len * a.element_size
|
mut size := nr_repeats * a.len * a.element_size
|
||||||
if size == 0 {
|
if size == 0 {
|
||||||
|
|
|
@ -12,7 +12,7 @@ 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 |
|
pub type Stmt = VarDecl | FnDecl | Return | Module | Import | ExprStmt |
|
||||||
ForStmt | StructDecl
|
ForStmt | StructDecl | ForCStmt | ForInStmt
|
||||||
// | IncDecStmt k
|
// | IncDecStmt k
|
||||||
// Stand-alone expression in a statement list.
|
// Stand-alone expression in a statement list.
|
||||||
pub struct ExprStmt {
|
pub struct ExprStmt {
|
||||||
|
@ -195,7 +195,21 @@ pub struct ForStmt {
|
||||||
pub:
|
pub:
|
||||||
cond Expr
|
cond Expr
|
||||||
stmts []Stmt
|
stmts []Stmt
|
||||||
is_in bool
|
}
|
||||||
|
|
||||||
|
pub struct ForInStmt {
|
||||||
|
pub:
|
||||||
|
var string
|
||||||
|
cond Expr
|
||||||
|
stmts []Stmt
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ForCStmt {
|
||||||
|
pub:
|
||||||
|
init Stmt // i := 0;
|
||||||
|
cond Expr // i < 10;
|
||||||
|
inc Stmt // i++;
|
||||||
|
stmts []Stmt
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ReturnStmt {
|
pub struct ReturnStmt {
|
||||||
|
|
|
@ -81,11 +81,20 @@ fn (g mut Gen) stmt(node ast.Stmt) {
|
||||||
}
|
}
|
||||||
ast.ForStmt {
|
ast.ForStmt {
|
||||||
g.write('while (')
|
g.write('while (')
|
||||||
if !it.is_in {
|
g.expr(it.cond)
|
||||||
// `for in` loops don't have a condition
|
g.writeln(') {')
|
||||||
println('it cond')
|
for stmt in it.stmts {
|
||||||
g.expr(it.cond)
|
g.stmt(stmt)
|
||||||
}
|
}
|
||||||
|
g.writeln('}')
|
||||||
|
}
|
||||||
|
ast.ForCStmt {
|
||||||
|
g.write('for (')
|
||||||
|
g.stmt(it.init)
|
||||||
|
// g.write('; ')
|
||||||
|
g.expr(it.cond)
|
||||||
|
g.write('; ')
|
||||||
|
g.stmt(it.inc)
|
||||||
g.writeln(') {')
|
g.writeln(') {')
|
||||||
for stmt in it.stmts {
|
for stmt in it.stmts {
|
||||||
g.stmt(stmt)
|
g.stmt(stmt)
|
||||||
|
|
|
@ -31,6 +31,7 @@ fn test_c_files() {
|
||||||
eprintln('${i}... ' + term.red('FAIL'))
|
eprintln('${i}... ' + term.red('FAIL'))
|
||||||
eprintln(path)
|
eprintln(path)
|
||||||
eprintln('got:\n$res')
|
eprintln('got:\n$res')
|
||||||
|
assert false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ void foo(int a);
|
||||||
int get_int(string a);
|
int get_int(string a);
|
||||||
int get_int2();
|
int get_int2();
|
||||||
void myuser();
|
void myuser();
|
||||||
|
void variadic(variadic_int a);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int age;
|
int age;
|
||||||
|
@ -18,6 +19,13 @@ return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void foo(int a) {
|
void foo(int a) {
|
||||||
|
while (true) {
|
||||||
|
|
||||||
|
}
|
||||||
|
for (int i = 0;
|
||||||
|
i < 10; i++;
|
||||||
|
) {
|
||||||
|
}
|
||||||
void n = get_int2();
|
void n = get_int2();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,12 @@ fn main() {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
fn foo(a int) {
|
fn foo(a int) {
|
||||||
|
for true {
|
||||||
|
|
||||||
|
}
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
|
||||||
|
}
|
||||||
n := get_int2()
|
n := get_int2()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ module x64
|
||||||
|
|
||||||
import (
|
import (
|
||||||
v.ast
|
v.ast
|
||||||
term
|
// term
|
||||||
)
|
)
|
||||||
|
|
||||||
pub struct Gen {
|
pub struct Gen {
|
||||||
|
@ -325,15 +325,10 @@ fn (g mut Gen) stmt(node ast.Stmt) {
|
||||||
}
|
}
|
||||||
g.ret()
|
g.ret()
|
||||||
}
|
}
|
||||||
ast.Return {
|
ast.Return {}
|
||||||
}
|
ast.VarDecl {}
|
||||||
ast.VarDecl {
|
ast.ForStmt {}
|
||||||
}
|
ast.StructDecl {}
|
||||||
ast.ForStmt {
|
|
||||||
if it.is_in {}
|
|
||||||
}
|
|
||||||
ast.StructDecl {
|
|
||||||
}
|
|
||||||
ast.ExprStmt {
|
ast.ExprStmt {
|
||||||
g.expr(it.expr)
|
g.expr(it.expr)
|
||||||
}
|
}
|
||||||
|
@ -378,12 +373,12 @@ fn (g mut Gen) expr(node ast.Expr) {
|
||||||
ast.BoolLiteral {}
|
ast.BoolLiteral {}
|
||||||
ast.IfExpr {}
|
ast.IfExpr {}
|
||||||
else {
|
else {
|
||||||
//println(term.red('x64.expr(): bad node'))
|
// println(term.red('x64.expr(): bad node'))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn verror(s string) {
|
fn verror(s string) {
|
||||||
println(s)
|
println(s)
|
||||||
exit(1)
|
exit(1)
|
||||||
}
|
}
|
||||||
|
|
|
@ -149,7 +149,7 @@ pub fn (p mut Parser) top_stmt() ast.Stmt {
|
||||||
p.error('wrong pub keyword usage')
|
p.error('wrong pub keyword usage')
|
||||||
return ast.Stmt{}
|
return ast.Stmt{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// .key_const {
|
// .key_const {
|
||||||
// return p.const_decl()
|
// return p.const_decl()
|
||||||
// }
|
// }
|
||||||
|
@ -256,6 +256,10 @@ pub fn (p &Parser) warn(s string) {
|
||||||
pub fn (p mut Parser) name_expr() (ast.Expr,types.TypeIdent) {
|
pub fn (p mut Parser) name_expr() (ast.Expr,types.TypeIdent) {
|
||||||
mut node := ast.Expr{}
|
mut node := ast.Expr{}
|
||||||
mut ti := types.void_ti
|
mut ti := types.void_ti
|
||||||
|
if p.tok.lit == 'C' {
|
||||||
|
p.next()
|
||||||
|
p.check(.dot)
|
||||||
|
}
|
||||||
// fn call
|
// fn call
|
||||||
if p.peek_tok.kind == .lpar {
|
if p.peek_tok.kind == .lpar {
|
||||||
x,ti2 := p.call_expr() // TODO `node,typ :=` should work
|
x,ti2 := p.call_expr() // TODO `node,typ :=` should work
|
||||||
|
@ -435,10 +439,59 @@ fn (p &Parser) is_addative() bool {
|
||||||
return p.tok.kind in [.plus, .minus] && p.peek_tok.kind in [.number, .name]
|
return p.tok.kind in [.plus, .minus] && p.peek_tok.kind in [.number, .name]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (p mut Parser) for_statement() ast.ForStmt {
|
fn (p mut Parser) for_statement() ast.Stmt {
|
||||||
p.check(.key_for)
|
p.check(.key_for)
|
||||||
|
// Infinite loop
|
||||||
|
if p.tok.kind == .lcbr {
|
||||||
|
stmts := p.parse_block()
|
||||||
|
return ast.ForStmt{
|
||||||
|
stmts: stmts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if p.tok.kind == .key_mut {
|
||||||
|
p.error('`mut` is not required in for loops')
|
||||||
|
}
|
||||||
|
// for i := 0; i < 10; i++ {
|
||||||
|
else if p.peek_tok.kind in [.decl_assign, .assign, .semicolon] {
|
||||||
|
mut init := ast.Stmt{}
|
||||||
|
mut cond := ast.Expr{}
|
||||||
|
mut inc := ast.Stmt{}
|
||||||
|
if p.peek_tok.kind == .decl_assign {
|
||||||
|
init = p.var_decl()
|
||||||
|
}
|
||||||
|
else if p.tok.kind != .semicolon {
|
||||||
|
// allow `for ;; i++ {`
|
||||||
|
// Allow `for i = 0; i < ...`
|
||||||
|
/*
|
||||||
|
cond, typ = p.expr(0)
|
||||||
|
if typ.kind != _bool {
|
||||||
|
p.error('non-bool used as for condition')
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
println(1)
|
||||||
|
}
|
||||||
|
p.check(.semicolon)
|
||||||
|
if p.tok.kind != .semicolon {
|
||||||
|
mut typ := types.TypeIdent{}
|
||||||
|
cond,typ = p.expr(0)
|
||||||
|
if typ.kind != ._bool {
|
||||||
|
p.error('non-bool used as for condition')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p.check(.semicolon)
|
||||||
|
if p.tok.kind != .lcbr {
|
||||||
|
inc = p.stmt()
|
||||||
|
}
|
||||||
|
stmts := p.parse_block()
|
||||||
|
return ast.ForCStmt{
|
||||||
|
stmts: stmts
|
||||||
|
init: init
|
||||||
|
cond: cond
|
||||||
|
inc: inc
|
||||||
|
}
|
||||||
|
}
|
||||||
// `for i in start .. end`
|
// `for i in start .. end`
|
||||||
if p.peek_tok.kind == .key_in {
|
else if p.peek_tok.kind == .key_in {
|
||||||
var := p.check_name()
|
var := p.check_name()
|
||||||
p.check(.key_in)
|
p.check(.key_in)
|
||||||
start := p.tok.lit.int()
|
start := p.tok.lit.int()
|
||||||
|
@ -451,7 +504,6 @@ fn (p mut Parser) for_statement() ast.ForStmt {
|
||||||
// println('nr stmts=$stmts.len')
|
// println('nr stmts=$stmts.len')
|
||||||
return ast.ForStmt{
|
return ast.ForStmt{
|
||||||
stmts: stmts
|
stmts: stmts
|
||||||
is_in: true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// `for cond {`
|
// `for cond {`
|
||||||
|
|
Loading…
Reference in New Issue