v2: scopes, or, in, hex

pull/3652/head
Alexander Medvednikov 2020-02-04 17:44:39 +01:00
parent 9b60a50d07
commit 80daaff874
8 changed files with 153 additions and 66 deletions

View File

@ -157,7 +157,7 @@ pub fn (n i64) hex() string {
hex := malloc(len) hex := malloc(len)
// QTODO // QTODO
//count := C.sprintf(charptr(hex), '0x%'C.PRIx64, n) //count := C.sprintf(charptr(hex), '0x%'C.PRIx64, n)
count := C.sprintf('%x', n) count := C.sprintf(charptr(hex), '0x%x', n)
return tos(hex, count) return tos(hex, count)
} }
@ -165,7 +165,7 @@ pub fn (n u64) hex() string {
len := if n >= u64(0) { n.str().len + 3 } else { 19 } len := if n >= u64(0) { n.str().len + 3 } else { 19 }
hex := malloc(len) hex := malloc(len)
//count := C.sprintf(charptr(hex), '0x%'C.PRIx64, n) //count := C.sprintf(charptr(hex), '0x%'C.PRIx64, n)
count := C.sprintf('%x', n) count := C.sprintf(charptr(hex), '0x%lx', n)
return tos(hex, count) return tos(hex, count)
} }

View File

@ -108,3 +108,8 @@ fn test_int_alias() {
assert i + 10 == 12 assert i + 10 == 12
*/ */
} }
fn test_hex() {
x := u64(10)
assert x.hex() == '0xa'
}

View File

@ -123,8 +123,8 @@ fn (n mut mapnode) split_child(child_index int, y mut mapnode) {
} }
if !isnil(y.children) { if !isnil(y.children) {
z.children = &voidptr(malloc(children_bytes)) z.children = &voidptr(malloc(children_bytes))
for j := degree - 1; j >= 0; j-- { for jj := degree - 1; jj >= 0; jj-- {
z.children[j] = y.children[j + degree] z.children[jj] = y.children[jj + degree]
} }
} }
if isnil(n.children) { if isnil(n.children) {

View File

@ -195,6 +195,17 @@ struct RepIndex {
val_idx int val_idx int
} }
fn compare_rep_index(a, b &RepIndex) int {
if a.idx < b.idx {
return -1
}
if a.idx > b.idx {
return 1
}
return 0
}
fn (a mut []RepIndex) sort() { fn (a mut []RepIndex) sort() {
a.sort_with_compare(compare_rep_index) a.sort_with_compare(compare_rep_index)
} }
@ -207,16 +218,6 @@ fn (a RepIndex) < (b RepIndex) bool {
*/ */
fn compare_rep_index(a, b &RepIndex) int {
if a.idx < b.idx {
return -1
}
if a.idx > b.idx {
return 1
}
return 0
}
pub fn (s string) replace_each(vals []string) string { pub fn (s string) replace_each(vals []string) string {
if s.len == 0 || vals.len == 0 { if s.len == 0 || vals.len == 0 {
return s return s
@ -244,7 +245,8 @@ pub fn (s string) replace_each(vals []string) string {
// We need to remember both the position in the string, // We need to remember both the position in the string,
// and which rep/with pair it refers to. // and which rep/with pair it refers to.
idxs << RepIndex{ idxs << RepIndex{
idx,rep_i} idx:idx
val_idx:rep_i}
idx++ idx++
new_len += with.len - rep.len new_len += with.len - rep.len
} }
@ -403,8 +405,8 @@ pub fn (s string) split(delim string) []string {
} }
/* /*
split_nth - splits the string based on the passed `delim` substring. split_nth - splits the string based on the passed `delim` substring.
It returns the first Nth parts. When N=0, return all the splits. It returns the first Nth parts. When N=0, return all the splits.
The last returned element has the remainder of the string, even if The last returned element has the remainder of the string, even if
the remainder contains more `delim` substrings. the remainder contains more `delim` substrings.
*/ */
@ -447,7 +449,7 @@ pub fn (s string) split_nth(delim string, nth int) []string {
res << s.right(start) res << s.right(start)
break break
} }
res << val res << val
start = i + delim.len start = i + delim.len
} }

View File

@ -216,7 +216,8 @@ pub fn parse_iso(s string) Time {
} }
mm := pos / 3 + 1 mm := pos / 3 + 1
tmstr := malloc(s.len * 2) tmstr := malloc(s.len * 2)
count := int(C.sprintf(charptr(tmstr), '%s-%02d-%s %s'.str, fields[3].str, mm, fields[1].str, fields[4].str)) count := C.sprintf(charptr(tmstr), '%s-%02d-%s %s'.str, fields[3].str, mm,
fields[1].str, fields[4].str)
return parse(tos(tmstr, count)) return parse(tos(tmstr, count))
} }

View File

@ -21,6 +21,10 @@ pub fn (p mut Parser) call_expr() (ast.CallExpr,table.Type) {
pos: tok.position() pos: tok.position()
} }
if p.tok.kind == .key_orelse {
p.next()
p.parse_block()
}
if f := p.table.find_fn(fn_name) { if f := p.table.find_fn(fn_name) {
return node,f.return_type return node,f.return_type
} }
@ -45,6 +49,7 @@ pub fn (p mut Parser) call_args() []ast.Expr {
} }
fn (p mut Parser) fn_decl() ast.FnDecl { fn (p mut Parser) fn_decl() ast.FnDecl {
p.table.clear_vars()
is_pub := p.tok.kind == .key_pub is_pub := p.tok.kind == .key_pub
if is_pub { if is_pub {
p.next() p.next()

View File

@ -32,6 +32,8 @@ mut:
// vars []string // vars []string
table &table.Table table &table.Table
return_type table.Type // current function's return type return_type table.Type // current function's return type
// scope_level int
// var_idx int
is_c bool is_c bool
// //
// prefix_parse_fns []PrefixParseFn // prefix_parse_fns []PrefixParseFn
@ -118,6 +120,7 @@ pub fn (p mut Parser) read_first_token() {
} }
pub fn (p mut Parser) parse_block() []ast.Stmt { pub fn (p mut Parser) parse_block() []ast.Stmt {
p.table.open_scope()
p.check(.lcbr) p.check(.lcbr)
mut stmts := []ast.Stmt mut stmts := []ast.Stmt
if p.tok.kind != .rcbr { if p.tok.kind != .rcbr {
@ -130,6 +133,7 @@ pub fn (p mut Parser) parse_block() []ast.Stmt {
} }
} }
p.check(.rcbr) p.check(.rcbr)
p.table.close_scope()
// println('nr exprs in block = $exprs.len') // println('nr exprs in block = $exprs.len')
return stmts return stmts
} }
@ -405,7 +409,7 @@ pub fn (p mut Parser) name_expr() (ast.Expr,table.Type) {
} }
// variable // variable
if var := p.table.find_var(p.tok.lit) { if var := p.table.find_var(p.tok.lit) {
println('#### IDENT: $var.name: $var.typ.name - $var.typ.idx') // println('#### IDENT: $var.name: $var.typ.name - $var.typ.idx')
typ = var.typ typ = var.typ
ident.kind = .variable ident.kind = .variable
ident.info = ast.IdentVar{ ident.info = ast.IdentVar{
@ -592,6 +596,10 @@ fn (p mut Parser) dot_expr(left ast.Expr, left_ti &table.Type) (ast.Expr,table.T
if p.tok.kind == .lpar { if p.tok.kind == .lpar {
p.next() p.next()
args := p.call_args() args := p.call_args()
if p.tok.kind == .key_orelse {
p.next()
p.parse_block()
}
mcall_expr := ast.MethodCallExpr{ mcall_expr := ast.MethodCallExpr{
expr: left expr: left
name: field_name name: field_name
@ -645,9 +653,12 @@ fn (p &Parser) is_addative() bool {
fn (p mut Parser) for_statement() ast.Stmt { fn (p mut Parser) for_statement() ast.Stmt {
p.check(.key_for) p.check(.key_for)
p.table.open_scope()
// defer { p.table.close_scope() }
// Infinite loop // Infinite loop
if p.tok.kind == .lcbr { if p.tok.kind == .lcbr {
stmts := p.parse_block() stmts := p.parse_block()
p.table.close_scope()
return ast.ForStmt{ return ast.ForStmt{
stmts: stmts stmts: stmts
pos: p.tok.position() pos: p.tok.position()
@ -685,6 +696,7 @@ fn (p mut Parser) for_statement() ast.Stmt {
inc = p.stmt() inc = p.stmt()
} }
stmts := p.parse_block() stmts := p.parse_block()
p.table.close_scope()
return ast.ForCStmt{ return ast.ForCStmt{
stmts: stmts stmts: stmts
init: init init: init
@ -693,8 +705,16 @@ fn (p mut Parser) for_statement() ast.Stmt {
} }
} }
// `for i in vals`, `for i in start .. end` // `for i in vals`, `for i in start .. end`
else if p.peek_tok.kind == .key_in { else if p.peek_tok.kind == .key_in || p.peek_tok.kind == .comma {
var_name := p.check_name() var_name := p.check_name()
if p.tok.kind == .comma {
p.check(.comma)
val_name := p.check_name()
p.table.register_var(table.Var{
name: val_name
typ: table.int_type
})
}
p.check(.key_in) p.check(.key_in)
start := p.tok.lit.int() start := p.tok.lit.int()
p.expr(0) p.expr(0)
@ -708,6 +728,7 @@ fn (p mut Parser) for_statement() ast.Stmt {
}) })
stmts := p.parse_block() stmts := p.parse_block()
// println('nr stmts=$stmts.len') // println('nr stmts=$stmts.len')
p.table.close_scope()
return ast.ForStmt{ return ast.ForStmt{
stmts: stmts stmts: stmts
pos: p.tok.position() pos: p.tok.position()
@ -716,6 +737,7 @@ fn (p mut Parser) for_statement() ast.Stmt {
// `for cond {` // `for cond {`
cond,_ := p.expr(0) cond,_ := p.expr(0)
stmts := p.parse_block() stmts := p.parse_block()
p.table.close_scope()
return ast.ForStmt{ return ast.ForStmt{
cond: cond cond: cond
stmts: stmts stmts: stmts
@ -735,7 +757,12 @@ fn (p mut Parser) if_expr() (ast.Expr,table.Type) {
mut else_stmts := []ast.Stmt mut else_stmts := []ast.Stmt
if p.tok.kind == .key_else { if p.tok.kind == .key_else {
p.check(.key_else) p.check(.key_else)
else_stmts = p.parse_block() if p.tok.kind == .key_if {
p.if_expr()
}
else {
else_stmts = p.parse_block()
}
} }
mut ti := table.void_type mut ti := table.void_type
// mut left := ast.Expr{} // mut left := ast.Expr{}
@ -944,13 +971,18 @@ fn (p mut Parser) struct_decl() ast.StructDecl {
// println('struct field $ti.name $field_name') // println('struct field $ti.name $field_name')
} }
p.check(.rcbr) p.check(.rcbr)
p.table.register_type(table.Type{ if name != 'string' {
kind: .struct_ ret := p.table.register_type(table.Type{
name: name kind: .struct_
info: table.Struct{ name: name
fields: fields info: table.Struct{
fields: fields
}
})
if ret == -1 {
p.error('cannot register type `$name`, another type with this name exists')
} }
}) }
return ast.StructDecl{ return ast.StructDecl{
name: name name: name
is_pub: is_pub is_pub: is_pub

View File

@ -8,15 +8,17 @@ module table
pub struct Table { pub struct Table {
// struct_fields map[string][]string // struct_fields map[string][]string
pub mut: pub mut:
types []Type types []Type
// type_idxs Hashmap // type_idxs Hashmap
type_idxs map[string]int type_idxs map[string]int
local_vars []Var local_vars []Var
scope_level int
var_idx int
// fns Hashmap // fns Hashmap
fns map[string]Fn fns map[string]Fn
consts map[string]Var consts map[string]Var
tmp_cnt int tmp_cnt int
imports []string imports []string
} }
pub struct Fn { pub struct Fn {
@ -28,12 +30,14 @@ pub:
pub struct Var { pub struct Var {
pub: pub:
name string name string
is_mut bool idx int
is_const bool is_mut bool
is_global bool is_const bool
is_global bool
scope_level int
mut: mut:
typ Type typ Type
} }
pub fn new_table() &Table { pub fn new_table() &Table {
@ -52,32 +56,21 @@ pub fn (t &Table) find_var_idx(name string) int {
} }
pub fn (t &Table) find_var(name string) ?Var { pub fn (t &Table) find_var(name string) ?Var {
/* for i in 0 .. t.var_idx {
for i in 0 .. p.var_idx { if t.local_vars[i].name == name {
if p.local_vars[i].name == name { return t.local_vars[i]
return p.local_vars[i]
} }
} }
*/ /*
// println(t.names) // println(t.names)
for var in t.local_vars { for var in t.local_vars {
if var.name == name { if var.name == name {
return var return var
} }
} }
return none */
}
pub fn (t mut Table) clear_vars() { return none
// shared a := [1, 2, 3]
// p.var_idx = 0
if t.local_vars.len > 0 {
// if p.pref.autofree {
// p.local_vars.free()
// }
t.local_vars = []
}
} }
pub fn (t mut Table) register_const(v Var) { pub fn (t mut Table) register_const(v Var) {
@ -99,27 +92,76 @@ pub fn (t mut Table) register_global(name string, typ Type) {
pub fn (t mut Table) register_var(v Var) { pub fn (t mut Table) register_var(v Var) {
println('register_var: $v.name - $v.typ.name') println('register_var: $v.name - $v.typ.name')
t.local_vars << v
/*
mut new_var := { mut new_var := {
v | v |
idx:p.var_idx, idx:t.var_idx,
scope_level:p.cur_fn.scope_level scope_level:t.scope_level
} }
// t.local_vars << v
/*
if v.line_nr == 0 { if v.line_nr == 0 {
new_var.token_idx = p.cur_tok_index() new_var.token_idx = p.cur_tok_index()
new_var.line_nr = p.cur_tok().line_nr new_var.line_nr = p.cur_tok().line_nr
} }
*/
// Expand the array // Expand the array
if p.var_idx >= p.local_vars.len { if t.var_idx >= t.local_vars.len {
p.local_vars << new_var t.local_vars << new_var
} }
else { else {
p.local_vars[p.var_idx] = new_var t.local_vars[t.var_idx] = new_var
}
t.var_idx++
}
pub fn (t mut Table) open_scope() {
t.scope_level++
}
pub fn (t mut Table) close_scope() {
// println('close_scope level=$f.scope_level var_idx=$f.var_idx')
// Move back `var_idx` (pointer to the end of the array) till we reach
// the previous scope level. This effectivly deletes (closes) current
// scope.
mut i := t.var_idx - 1
for ; i >= 0; i-- {
var := t.local_vars[i]
/*
if p.pref.autofree && (v.is_alloc || (v.is_arg && v.typ == 'string')) {
// && !p.pref.is_test {
p.free_var(v)
}
*/
// if p.fileis('mem.v') {
// println(v.name + ' $v.is_arg scope=$v.scope_level cur=$p.cur_fn.scope_level')}
if var.scope_level != t.scope_level {
// && !v.is_arg {
break
}
}
/*
if p.cur_fn.defer_text.last() != '' {
p.genln(p.cur_fn.defer_text.last())
// p.cur_fn.defer_text[f] = ''
} }
p.var_idx++
*/ */
t.scope_level--
// p.cur_fn.defer_text = p.cur_fn.defer_text[..p.cur_fn.scope_level + 1]
t.var_idx = i + 1
// println('close_scope new var_idx=$f.var_idx\n')
}
pub fn (p mut Table) clear_vars() {
// shared a := [1, 2, 3]
p.var_idx = 0
if p.local_vars.len > 0 {
// ///if p.pref.autofree {
// p.local_vars.free()
// ///}
p.local_vars = []
}
} }
pub fn (t &Table) find_fn(name string) ?Fn { pub fn (t &Table) find_fn(name string) ?Fn {
@ -240,7 +282,7 @@ pub fn (t mut Table) register_type(typ Type) int {
if ex_type.kind == typ.kind { if ex_type.kind == typ.kind {
return existing_idx return existing_idx
} }
panic('cannot register type `$typ.name`, another type with this name exists') return -1
} }
} }
} }