v2: scopes, or, in, hex
parent
9b60a50d07
commit
80daaff874
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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'
|
||||||
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue