for ;; syntax

pull/3354/head
Alexander Medvednikov 2020-01-07 00:14:19 +01:00
parent 1e28c1d4fd
commit 48ea1153a5
9 changed files with 116 additions and 30 deletions

View File

@ -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

View File

@ -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 {

View File

@ -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 {

View File

@ -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.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)

View File

@ -31,6 +31,7 @@ fn test_c_files() {
eprintln('${i}... ' + term.red('FAIL'))
eprintln(path)
eprintln('got:\n$res')
assert false
}
}
}

View File

@ -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();
}

View File

@ -24,6 +24,12 @@ fn main() {
*/
fn foo(a int) {
for true {
}
for i := 0; i < 10; i++ {
}
n := get_int2()
}
@ -45,5 +51,5 @@ fn myuser() {
b2 := user.age > 0
}
fn variadic(a ...int) {
fn variadic(a ...int) {
}

View File

@ -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)
}
@ -378,12 +373,12 @@ fn (g mut Gen) expr(node ast.Expr) {
ast.BoolLiteral {}
ast.IfExpr {}
else {
//println(term.red('x64.expr(): bad node'))
}
// println(term.red('x64.expr(): bad node'))
}
}
}
}
fn verror(s string) {
println(s)
exit(1)
}
fn verror(s string) {
println(s)
exit(1)
}

View File

@ -149,7 +149,7 @@ pub fn (p mut Parser) top_stmt() ast.Stmt {
p.error('wrong pub keyword usage')
return ast.Stmt{}
}
}
}
// .key_const {
// 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) {
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 {`