for ;; syntax
parent
1e28c1d4fd
commit
48ea1153a5
|
@ -126,8 +126,9 @@ jobs:
|
|||
echo "Generating a 1m line V file..."
|
||||
../vprod run gen1m.v > 1m.v
|
||||
echo "Building it..."
|
||||
../vprod -x64 1m.v
|
||||
../vprod -x64 -o 1m 1m.v
|
||||
echo "Running it..."
|
||||
ls
|
||||
./1m
|
||||
#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
|
||||
pub fn (a array) repeat(nr_repeats int) array {
|
||||
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
|
||||
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
|
||||
|
||||
pub type Stmt = VarDecl | FnDecl | Return | Module | Import | ExprStmt |
|
||||
ForStmt | StructDecl
|
||||
ForStmt | StructDecl | ForCStmt | ForInStmt
|
||||
// | IncDecStmt k
|
||||
// Stand-alone expression in a statement list.
|
||||
pub struct ExprStmt {
|
||||
|
@ -195,7 +195,21 @@ pub struct ForStmt {
|
|||
pub:
|
||||
cond Expr
|
||||
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 {
|
||||
|
|
|
@ -81,11 +81,20 @@ fn (g mut Gen) stmt(node ast.Stmt) {
|
|||
}
|
||||
ast.ForStmt {
|
||||
g.write('while (')
|
||||
if !it.is_in {
|
||||
// `for in` loops don't have a condition
|
||||
println('it cond')
|
||||
g.expr(it.cond)
|
||||
g.writeln(') {')
|
||||
for stmt in it.stmts {
|
||||
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(') {')
|
||||
for stmt in it.stmts {
|
||||
g.stmt(stmt)
|
||||
|
|
|
@ -31,6 +31,7 @@ fn test_c_files() {
|
|||
eprintln('${i}... ' + term.red('FAIL'))
|
||||
eprintln(path)
|
||||
eprintln('got:\n$res')
|
||||
assert false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ void foo(int a);
|
|||
int get_int(string a);
|
||||
int get_int2();
|
||||
void myuser();
|
||||
void variadic(variadic_int a);
|
||||
|
||||
typedef struct {
|
||||
int age;
|
||||
|
@ -18,6 +19,13 @@ return 0;
|
|||
}
|
||||
|
||||
void foo(int a) {
|
||||
while (true) {
|
||||
|
||||
}
|
||||
for (int i = 0;
|
||||
i < 10; i++;
|
||||
) {
|
||||
}
|
||||
void n = get_int2();
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,12 @@ fn main() {
|
|||
*/
|
||||
|
||||
fn foo(a int) {
|
||||
for true {
|
||||
|
||||
}
|
||||
for i := 0; i < 10; i++ {
|
||||
|
||||
}
|
||||
n := get_int2()
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ module x64
|
|||
|
||||
import (
|
||||
v.ast
|
||||
term
|
||||
// term
|
||||
)
|
||||
|
||||
pub struct Gen {
|
||||
|
@ -325,15 +325,10 @@ fn (g mut Gen) stmt(node ast.Stmt) {
|
|||
}
|
||||
g.ret()
|
||||
}
|
||||
ast.Return {
|
||||
}
|
||||
ast.VarDecl {
|
||||
}
|
||||
ast.ForStmt {
|
||||
if it.is_in {}
|
||||
}
|
||||
ast.StructDecl {
|
||||
}
|
||||
ast.Return {}
|
||||
ast.VarDecl {}
|
||||
ast.ForStmt {}
|
||||
ast.StructDecl {}
|
||||
ast.ExprStmt {
|
||||
g.expr(it.expr)
|
||||
}
|
||||
|
|
|
@ -256,6 +256,10 @@ pub fn (p &Parser) warn(s string) {
|
|||
pub fn (p mut Parser) name_expr() (ast.Expr,types.TypeIdent) {
|
||||
mut node := ast.Expr{}
|
||||
mut ti := types.void_ti
|
||||
if p.tok.lit == 'C' {
|
||||
p.next()
|
||||
p.check(.dot)
|
||||
}
|
||||
// fn call
|
||||
if p.peek_tok.kind == .lpar {
|
||||
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]
|
||||
}
|
||||
|
||||
fn (p mut Parser) for_statement() ast.ForStmt {
|
||||
fn (p mut Parser) for_statement() ast.Stmt {
|
||||
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`
|
||||
if p.peek_tok.kind == .key_in {
|
||||
else if p.peek_tok.kind == .key_in {
|
||||
var := p.check_name()
|
||||
p.check(.key_in)
|
||||
start := p.tok.lit.int()
|
||||
|
@ -451,7 +504,6 @@ fn (p mut Parser) for_statement() ast.ForStmt {
|
|||
// println('nr stmts=$stmts.len')
|
||||
return ast.ForStmt{
|
||||
stmts: stmts
|
||||
is_in: true
|
||||
}
|
||||
}
|
||||
// `for cond {`
|
||||
|
|
Loading…
Reference in New Issue