v2: range, *, function object
parent
4fc52948b3
commit
71653273f6
|
@ -378,7 +378,8 @@ pub fn (b []byte) hex() string {
|
||||||
// TODO: implement for all types
|
// TODO: implement for all types
|
||||||
pub fn copy(dst, src []byte) int {
|
pub fn copy(dst, src []byte) int {
|
||||||
if dst.len > 0 && src.len > 0 {
|
if dst.len > 0 && src.len > 0 {
|
||||||
min := if dst.len < src.len { dst.len } else { src.len }
|
mut min := 0
|
||||||
|
min = if dst.len < src.len { dst.len } else { src.len }
|
||||||
C.memcpy(dst.data, src[..min].data, dst.element_size * min)
|
C.memcpy(dst.data, src[..min].data, dst.element_size * min)
|
||||||
return min
|
return min
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
|
|
||||||
pub type Expr = InfixExpr | IfExpr | StringLiteral | IntegerLiteral |
|
pub type Expr = InfixExpr | IfExpr | StringLiteral | IntegerLiteral |
|
||||||
FloatLiteral | Ident | CallExpr | BoolLiteral | StructInit | ArrayInit | SelectorExpr | PostfixExpr |
|
FloatLiteral | Ident | CallExpr | BoolLiteral | StructInit | ArrayInit | SelectorExpr | PostfixExpr |
|
||||||
AssignExpr | PrefixExpr | MethodCallExpr | IndexExpr
|
AssignExpr | PrefixExpr | MethodCallExpr | IndexExpr | RangeExpr
|
||||||
|
|
||||||
pub type Stmt = VarDecl | FnDecl | Return | Module | Import | ExprStmt |
|
pub type Stmt = VarDecl | FnDecl | Return | Module | Import | ExprStmt |
|
||||||
ForStmt | StructDecl | ForCStmt | ForInStmt
|
ForStmt | StructDecl | ForCStmt | ForInStmt
|
||||||
|
@ -296,6 +296,13 @@ pub:
|
||||||
ti table.Type
|
ti table.Type
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// s[10..20]
|
||||||
|
pub struct RangeExpr {
|
||||||
|
pub:
|
||||||
|
low Expr
|
||||||
|
high Expr
|
||||||
|
}
|
||||||
|
|
||||||
// string representaiton of expr
|
// string representaiton of expr
|
||||||
pub fn (x Expr) str() string {
|
pub fn (x Expr) str() string {
|
||||||
match x {
|
match x {
|
||||||
|
|
|
@ -194,112 +194,112 @@ fn (c &Checker) stmt(node ast.Stmt) {
|
||||||
}
|
}
|
||||||
ast.VarDecl {
|
ast.VarDecl {
|
||||||
typ := c.expr(it.expr)
|
typ := c.expr(it.expr)
|
||||||
println('1111var decl $typ.name it.typ=$it.typ.name $it.pos.line_nr')
|
// println('var decl $typ.name it.typ=$it.typ.name $it.pos.line_nr')
|
||||||
if it.typ.kind == .unresolved {
|
if it.typ.kind == .unresolved {
|
||||||
// it.ti = typ
|
// it.ti = typ
|
||||||
println('VAR DECL UN!!!')
|
// println('unresolved var')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
ast.ForStmt {
|
||||||
ast.ForStmt {
|
c.expr(it.cond)
|
||||||
c.expr(it.cond)
|
for stmt in it.stmts {
|
||||||
for stmt in it.stmts {
|
c.stmt(stmt)
|
||||||
c.stmt(stmt)
|
}
|
||||||
}
|
}
|
||||||
}
|
ast.ForCStmt {
|
||||||
ast.ForCStmt {
|
c.stmt(it.init)
|
||||||
c.stmt(it.init)
|
c.expr(it.cond)
|
||||||
c.expr(it.cond)
|
c.stmt(it.inc)
|
||||||
c.stmt(it.inc)
|
for stmt in it.stmts {
|
||||||
for stmt in it.stmts {
|
c.stmt(stmt)
|
||||||
c.stmt(stmt)
|
}
|
||||||
}
|
}
|
||||||
}
|
// ast.StructDecl {}
|
||||||
// ast.StructDecl {}
|
ast.ExprStmt {
|
||||||
ast.ExprStmt {
|
c.expr(it.expr)
|
||||||
c.expr(it.expr)
|
}
|
||||||
}
|
else {}
|
||||||
else {}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pub fn (c &Checker) expr(node ast.Expr) table.Type {
|
pub fn (c &Checker) expr(node ast.Expr) table.Type {
|
||||||
match node {
|
match node {
|
||||||
ast.AssignExpr {
|
ast.AssignExpr {
|
||||||
c.check_assign_expr(it)
|
c.check_assign_expr(it)
|
||||||
}
|
}
|
||||||
ast.IntegerLiteral {
|
ast.IntegerLiteral {
|
||||||
return table.int_type
|
return table.int_type
|
||||||
}
|
}
|
||||||
// ast.FloatLiteral {}
|
// ast.FloatLiteral {}
|
||||||
ast.PostfixExpr {
|
ast.PostfixExpr {
|
||||||
return c.expr(it.expr)
|
return c.expr(it.expr)
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
ast.UnaryExpr {
|
ast.UnaryExpr {
|
||||||
c.expr(it.left)
|
c.expr(it.left)
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ast.StringLiteral {
|
ast.StringLiteral {
|
||||||
return table.string_type
|
return table.string_type
|
||||||
}
|
}
|
||||||
ast.PrefixExpr {
|
ast.PrefixExpr {
|
||||||
return c.expr(it.right)
|
return c.expr(it.right)
|
||||||
}
|
}
|
||||||
ast.InfixExpr {
|
ast.InfixExpr {
|
||||||
return c.infix_expr(it)
|
return c.infix_expr(it)
|
||||||
}
|
}
|
||||||
ast.StructInit {
|
ast.StructInit {
|
||||||
return c.check_struct_init(it)
|
return c.check_struct_init(it)
|
||||||
}
|
}
|
||||||
ast.CallExpr {
|
ast.CallExpr {
|
||||||
return c.call_expr(it)
|
return c.call_expr(it)
|
||||||
}
|
}
|
||||||
ast.MethodCallExpr {
|
ast.MethodCallExpr {
|
||||||
return c.check_method_call_expr(it)
|
return c.check_method_call_expr(it)
|
||||||
}
|
}
|
||||||
ast.ArrayInit {
|
ast.ArrayInit {
|
||||||
return c.array_init(it)
|
return c.array_init(it)
|
||||||
}
|
}
|
||||||
ast.Ident {
|
ast.Ident {
|
||||||
if it.kind == .variable {
|
if it.kind == .variable {
|
||||||
info := it.info as ast.IdentVar
|
info := it.info as ast.IdentVar
|
||||||
if info.typ.kind != .unresolved {
|
if info.typ.kind != .unresolved {
|
||||||
return info.typ
|
return info.typ
|
||||||
|
}
|
||||||
|
return c.expr(info.expr)
|
||||||
}
|
}
|
||||||
return c.expr(info.expr)
|
return table.void_type
|
||||||
}
|
}
|
||||||
return table.void_type
|
// ast.BoolLiteral {}
|
||||||
}
|
ast.SelectorExpr {
|
||||||
// ast.BoolLiteral {}
|
return c.selector_expr(it)
|
||||||
ast.SelectorExpr {
|
|
||||||
return c.selector_expr(it)
|
|
||||||
}
|
|
||||||
ast.IndexExpr {
|
|
||||||
c.expr(it.left)
|
|
||||||
c.expr(it.index)
|
|
||||||
}
|
|
||||||
ast.IfExpr {
|
|
||||||
c.expr(it.cond)
|
|
||||||
for i, stmt in it.stmts {
|
|
||||||
c.stmt(stmt)
|
|
||||||
}
|
}
|
||||||
if it.else_stmts.len > 0 {
|
ast.IndexExpr {
|
||||||
for stmt in it.else_stmts {
|
c.expr(it.left)
|
||||||
|
c.expr(it.index)
|
||||||
|
}
|
||||||
|
ast.IfExpr {
|
||||||
|
c.expr(it.cond)
|
||||||
|
for i, stmt in it.stmts {
|
||||||
c.stmt(stmt)
|
c.stmt(stmt)
|
||||||
}
|
}
|
||||||
|
if it.else_stmts.len > 0 {
|
||||||
|
for stmt in it.else_stmts {
|
||||||
|
c.stmt(stmt)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
else {}
|
||||||
else {}
|
}
|
||||||
|
return table.void_type
|
||||||
}
|
}
|
||||||
return table.void_type
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn (c &Checker) error(s string, pos token.Position) {
|
pub fn (c &Checker) error(s string, pos token.Position) {
|
||||||
print_backtrace()
|
print_backtrace()
|
||||||
final_msg_line := '$c.file_name:$pos.line_nr: error: $s'
|
final_msg_line := '$c.file_name:$pos.line_nr: error: $s'
|
||||||
eprintln(final_msg_line)
|
eprintln(final_msg_line)
|
||||||
/*
|
/*
|
||||||
if colored_output {
|
if colored_output {
|
||||||
eprintln(term.bold(term.red(final_msg_line)))
|
eprintln(term.bold(term.red(final_msg_line)))
|
||||||
}else{
|
}else{
|
||||||
|
@ -307,5 +307,5 @@ pub fn (c &Checker) error(s string, pos token.Position) {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
exit(1)
|
exit(1)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
v.ast
|
v.ast
|
||||||
v.table
|
v.table
|
||||||
v.checker
|
v.checker
|
||||||
// v.types
|
|
||||||
term
|
term
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -267,10 +266,7 @@ fn (g mut Gen) expr(node ast.Expr) {
|
||||||
g.write(it.field)
|
g.write(it.field)
|
||||||
}
|
}
|
||||||
ast.IndexExpr {
|
ast.IndexExpr {
|
||||||
g.expr(it.left)
|
g.index_expr(it)
|
||||||
g.write('[')
|
|
||||||
g.expr(it.index)
|
|
||||||
g.write(']')
|
|
||||||
}
|
}
|
||||||
ast.IfExpr {
|
ast.IfExpr {
|
||||||
// If expression? Assign the value to a temp var.
|
// If expression? Assign the value to a temp var.
|
||||||
|
@ -307,6 +303,31 @@ fn (g mut Gen) expr(node ast.Expr) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (g mut Gen) index_expr(node ast.IndexExpr) {
|
||||||
|
// TODO else doesn't work with sum types
|
||||||
|
mut is_range := false
|
||||||
|
match node.index {
|
||||||
|
ast.RangeExpr {
|
||||||
|
is_range = true
|
||||||
|
g.write('array_slice(')
|
||||||
|
g.expr(node.left)
|
||||||
|
g.write(', ')
|
||||||
|
// g.expr(it.low)
|
||||||
|
g.write('0')
|
||||||
|
g.write(', ')
|
||||||
|
g.expr(it.high)
|
||||||
|
g.write(')')
|
||||||
|
}
|
||||||
|
else {}
|
||||||
|
}
|
||||||
|
if !is_range {
|
||||||
|
g.expr(node.left)
|
||||||
|
g.write('[')
|
||||||
|
g.expr(node.index)
|
||||||
|
g.write(']')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn verror(s string) {
|
fn verror(s string) {
|
||||||
println(s)
|
println(s)
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
|
@ -33,6 +33,7 @@ i < 10; i++;
|
||||||
array_int nums = new_array_from_c_array(3, 3, sizeof(array_int), {
|
array_int nums = new_array_from_c_array(3, 3, sizeof(array_int), {
|
||||||
1, 2, 3,
|
1, 2, 3,
|
||||||
});
|
});
|
||||||
|
array_int nums2 = array_slice(nums, 0, 2);
|
||||||
int number = nums[0];
|
int number = nums[0];
|
||||||
array_bool bools = new_array_from_c_array(2, 2, sizeof(array_bool), {
|
array_bool bools = new_array_from_c_array(2, 2, sizeof(array_bool), {
|
||||||
true, false,
|
true, false,
|
||||||
|
|
|
@ -33,6 +33,7 @@ fn foo(a int) {
|
||||||
|
|
||||||
}
|
}
|
||||||
nums := [1,2,3]
|
nums := [1,2,3]
|
||||||
|
nums2 := nums[..2]
|
||||||
number := nums[0]
|
number := nums[0]
|
||||||
bools := [true, false]
|
bools := [true, false]
|
||||||
b := bools[0]
|
b := bools[0]
|
||||||
|
|
|
@ -231,6 +231,20 @@ pub fn (p mut Parser) assign_expr(left ast.Expr) ast.AssignExpr {
|
||||||
return node
|
return node
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (p mut Parser) range_expr(low ast.Expr) ast.Expr {
|
||||||
|
// ,table.Type) {
|
||||||
|
p.next()
|
||||||
|
high,typ := p.expr(0)
|
||||||
|
if typ.kind != .int {
|
||||||
|
p.error('non-integer index `$typ.name`')
|
||||||
|
}
|
||||||
|
node := ast.RangeExpr{
|
||||||
|
low: low
|
||||||
|
high: high
|
||||||
|
}
|
||||||
|
return node
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
pub fn (p mut Parser) assign_stmt() ast.AssignStmt {
|
pub fn (p mut Parser) assign_stmt() ast.AssignStmt {
|
||||||
name := p.tok.lit
|
name := p.tok.lit
|
||||||
|
@ -340,21 +354,26 @@ pub fn (p mut Parser) name_expr() (ast.Expr,table.Type) {
|
||||||
mut ident := ast.Ident{
|
mut ident := ast.Ident{
|
||||||
name: p.tok.lit
|
name: p.tok.lit
|
||||||
}
|
}
|
||||||
var := p.table.find_var(p.tok.lit) or {
|
if var := p.table.find_var(p.tok.lit) {
|
||||||
p.error('name expr unknown variable `$p.tok.lit`')
|
typ = var.typ
|
||||||
exit(0)
|
ident.kind = .variable
|
||||||
}
|
ident.info = ast.IdentVar{
|
||||||
typ = var.typ
|
typ: typ
|
||||||
ident.kind = .variable
|
name: ident.name
|
||||||
ident.info = ast.IdentVar{
|
// expr: p.expr(0)// var.expr
|
||||||
typ: typ
|
|
||||||
name: ident.name
|
|
||||||
// expr: p.expr(0)// var.expr
|
|
||||||
|
|
||||||
|
}
|
||||||
|
// ident.ti = ti
|
||||||
|
node = ident
|
||||||
|
p.next()
|
||||||
|
}else{
|
||||||
|
// Function object (not a call), e.g. `onclick(my_click)`
|
||||||
|
p.table.find_fn(p.tok.lit) or {
|
||||||
|
p.error('name expr unknown variable `$p.tok.lit`')
|
||||||
|
exit(0)
|
||||||
|
}
|
||||||
|
p.next()
|
||||||
}
|
}
|
||||||
// ident.ti = ti
|
|
||||||
node = ident
|
|
||||||
p.next()
|
|
||||||
}
|
}
|
||||||
return node,typ
|
return node,typ
|
||||||
}
|
}
|
||||||
|
@ -372,7 +391,7 @@ pub fn (p mut Parser) expr(precedence int) (ast.Expr,table.Type) {
|
||||||
node,typ = p.string_expr()
|
node,typ = p.string_expr()
|
||||||
}
|
}
|
||||||
// -1, -a etc
|
// -1, -a etc
|
||||||
.minus, .amp {
|
.minus, .amp, .mul {
|
||||||
node,typ = p.prefix_expr()
|
node,typ = p.prefix_expr()
|
||||||
}
|
}
|
||||||
// .amp {
|
// .amp {
|
||||||
|
@ -412,21 +431,7 @@ pub fn (p mut Parser) expr(precedence int) (ast.Expr,table.Type) {
|
||||||
node,typ = p.dot_expr(node, typ)
|
node,typ = p.dot_expr(node, typ)
|
||||||
}
|
}
|
||||||
else if p.tok.kind == .lsbr {
|
else if p.tok.kind == .lsbr {
|
||||||
// TODO
|
node,typ = p.index_expr(node, typ)
|
||||||
// info := ti.info as table.Array
|
|
||||||
// ti = p.table.types[info.elem_type_idx]
|
|
||||||
if typ.name.starts_with('array_') {
|
|
||||||
elm_typ := typ.name[6..]
|
|
||||||
x := p.table.find_type(elm_typ) or {
|
|
||||||
p.error(elm_typ)
|
|
||||||
exit(0)
|
|
||||||
}
|
|
||||||
typ = x
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
typ = table.int_type
|
|
||||||
}
|
|
||||||
node = p.index_expr(node)
|
|
||||||
}
|
}
|
||||||
else if p.tok.kind.is_infix() {
|
else if p.tok.kind.is_infix() {
|
||||||
node,typ = p.infix_expr(node)
|
node,typ = p.infix_expr(node)
|
||||||
|
@ -459,23 +464,50 @@ fn (p mut Parser) prefix_expr() (ast.Expr,table.Type) {
|
||||||
return expr,ti
|
return expr,ti
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (p mut Parser) index_expr(left ast.Expr) ast.Expr {
|
fn (p mut Parser) index_expr(left ast.Expr, typ_ table.Type) (ast.Expr,table.Type) {
|
||||||
// ,table.Type) {
|
mut typ := typ_
|
||||||
|
// TODO
|
||||||
|
// info := ti.info as table.Array
|
||||||
|
// ti = p.table.types[info.elem_type_idx]
|
||||||
|
if typ.name.starts_with('array_') {
|
||||||
|
elm_typ := typ.name[6..]
|
||||||
|
// TODO `typ = ... or ...`
|
||||||
|
x := p.table.find_type(elm_typ) or {
|
||||||
|
p.error(elm_typ)
|
||||||
|
exit(0)
|
||||||
|
}
|
||||||
|
typ = x
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
typ = table.int_type
|
||||||
|
}
|
||||||
// println('index expr$p.tok.str() line=$p.tok.line_nr')
|
// println('index expr$p.tok.str() line=$p.tok.line_nr')
|
||||||
p.next()
|
p.next() // [
|
||||||
println('start index expr')
|
// `numbers[..end]`
|
||||||
index,typ := p.expr(0)
|
mut index_expr := ast.Expr{}
|
||||||
println('end expr typ=$typ.name')
|
if p.tok.kind == .dotdot {
|
||||||
|
index_expr = p.range_expr(left)
|
||||||
|
typ = typ_ // set the type back to array
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// println('start index expr')
|
||||||
|
mut index_type := table.Type{}
|
||||||
|
index_expr,index_type = p.expr(0)
|
||||||
|
if index_type.kind != .int {
|
||||||
|
p.error('non-integer index (type `$typ.name`)')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// println('end expr typ=$typ.name')
|
||||||
p.check(.rsbr)
|
p.check(.rsbr)
|
||||||
println('got ]')
|
// println('got ]')
|
||||||
// /ti := table.int_type
|
// /ti := table.int_type
|
||||||
mut node := ast.Expr{}
|
mut node := ast.Expr{}
|
||||||
node = ast.IndexExpr{
|
node = ast.IndexExpr{
|
||||||
left: left
|
left: left
|
||||||
index: index
|
index: index_expr
|
||||||
}
|
}
|
||||||
return node
|
// return node
|
||||||
// /return node,ti
|
return node,typ
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (p mut Parser) dot_expr(left ast.Expr, left_ti &table.Type) (ast.Expr,table.Type) {
|
fn (p mut Parser) dot_expr(left ast.Expr, left_ti &table.Type) (ast.Expr,table.Type) {
|
||||||
|
|
|
@ -357,6 +357,8 @@ const (
|
||||||
)
|
)
|
||||||
// precedence returns a tokens precedence if defined, otherwise lowest_prec
|
// precedence returns a tokens precedence if defined, otherwise lowest_prec
|
||||||
pub fn (tok Token) precedence() int {
|
pub fn (tok Token) precedence() int {
|
||||||
|
// TODO
|
||||||
|
// return int(precedences[int(tok)])
|
||||||
match tok.kind {
|
match tok.kind {
|
||||||
.lsbr {
|
.lsbr {
|
||||||
return 9
|
return 9
|
||||||
|
|
Loading…
Reference in New Issue