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