v2: match expr; enum val; string formatting
parent
d51c159160
commit
26cfaa150e
|
@ -10,7 +10,8 @@ import (
|
|||
|
||||
pub type Expr = InfixExpr | IfExpr | StringLiteral | IntegerLiteral | CharLiteral |
|
||||
FloatLiteral | Ident | CallExpr | BoolLiteral | StructInit | ArrayInit | SelectorExpr | PostfixExpr |
|
||||
AssignExpr | PrefixExpr | MethodCallExpr | IndexExpr | RangeExpr | MatchExpr | CastExpr
|
||||
AssignExpr | PrefixExpr | MethodCallExpr | IndexExpr | RangeExpr | MatchExpr |
|
||||
CastExpr | EnumVal
|
||||
|
||||
pub type Stmt = VarDecl | GlobalDecl | FnDecl | Return | Module | Import | ExprStmt |
|
||||
ForStmt | StructDecl | ForCStmt | ForInStmt | CompIf | ConstDecl | Attr | BranchStmt |
|
||||
|
@ -366,6 +367,12 @@ pub:
|
|||
name string
|
||||
}
|
||||
|
||||
pub struct EnumVal{
|
||||
pub:
|
||||
name string
|
||||
|
||||
}
|
||||
|
||||
pub struct AssignExpr {
|
||||
pub:
|
||||
op token.Kind
|
||||
|
|
|
@ -92,6 +92,13 @@ multi_return_int_string multi_return() {
|
|||
|
||||
void variadic(variadic_int a) {
|
||||
int x = path_sep;
|
||||
int y = if (true) {
|
||||
1;
|
||||
}
|
||||
else {
|
||||
0;
|
||||
}
|
||||
;
|
||||
}
|
||||
|
||||
void ensure_cap(int required, int cap) {
|
||||
|
@ -105,12 +112,12 @@ void println(string s) {
|
|||
|
||||
void matches() {
|
||||
int a = 100;
|
||||
int tmp1 = a;
|
||||
if tmp1 == 10{
|
||||
int tmp2 = a;
|
||||
if tmp2 == 10{
|
||||
println(tos3("10"));
|
||||
|
||||
}
|
||||
if tmp1 == 20{
|
||||
if tmp2 == 20{
|
||||
int k = a + 1;
|
||||
|
||||
}
|
||||
|
|
|
@ -98,6 +98,7 @@ fn multi_return() (int,string) {
|
|||
|
||||
fn variadic(a ...int) {
|
||||
x := path_sep
|
||||
y := if true { 1 } else { 0 } // TODO cgen
|
||||
}
|
||||
|
||||
fn ensure_cap(required int, cap int) {
|
||||
|
@ -118,6 +119,13 @@ fn matches() {
|
|||
k := a + 1
|
||||
}
|
||||
}
|
||||
/*
|
||||
n := match a {
|
||||
1 { 10 }
|
||||
2 { 20 }
|
||||
else { 30 }
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
const (
|
||||
|
|
|
@ -18,6 +18,7 @@ pub fn (p mut Parser) call_expr() (ast.CallExpr,table.Type) {
|
|||
name: fn_name
|
||||
args: args
|
||||
// tok: tok
|
||||
|
||||
pos: tok.position()
|
||||
}
|
||||
if p.tok.kind == .key_orelse {
|
||||
|
@ -121,7 +122,7 @@ fn (p mut Parser) fn_decl() ast.FnDecl {
|
|||
typ: arg_type
|
||||
}
|
||||
args << arg
|
||||
//p.table.register_var(arg)
|
||||
// p.table.register_var(arg)
|
||||
ast_args << ast.Arg{
|
||||
name: arg_name
|
||||
typ: arg_type
|
||||
|
@ -156,7 +157,7 @@ fn (p mut Parser) fn_decl() ast.FnDecl {
|
|||
name: arg_name
|
||||
typ: typ
|
||||
}
|
||||
//if typ.typ.kind == .variadic && p.tok.kind == .comma {
|
||||
// if typ.typ.kind == .variadic && p.tok.kind == .comma {
|
||||
if is_variadic && p.tok.kind == .comma {
|
||||
p.error('cannot use ...(variadic) with non-final parameter $arg_name')
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@ mut:
|
|||
mod string
|
||||
unresolved []ast.Expr
|
||||
unresolved_offset int
|
||||
expected_type table.Type
|
||||
}
|
||||
|
||||
// for tests
|
||||
|
@ -471,7 +472,7 @@ pub fn (p mut Parser) name_expr() (ast.Expr,table.Type) {
|
|||
if p.peek_tok.kind == .lpar {
|
||||
name := p.tok.lit
|
||||
// type cast. TODO: finish
|
||||
//if name in table.builtin_type_names {
|
||||
// if name in table.builtin_type_names {
|
||||
if name in p.table.type_idxs {
|
||||
to_typ := p.parse_type()
|
||||
p.check(.lpar)
|
||||
|
@ -487,7 +488,7 @@ pub fn (p mut Parser) name_expr() (ast.Expr,table.Type) {
|
|||
typ: to_typ
|
||||
expr: expr
|
||||
}
|
||||
return node, to_typ
|
||||
return node,to_typ
|
||||
}
|
||||
// fn call
|
||||
else {
|
||||
|
@ -540,6 +541,10 @@ pub fn (p mut Parser) expr(precedence int) (ast.Expr,table.Type) {
|
|||
.str {
|
||||
node,typ = p.string_expr()
|
||||
}
|
||||
.dot {
|
||||
// .enum_val
|
||||
node,typ = p.enum_val()
|
||||
}
|
||||
.chartoken {
|
||||
typ = table.byte_type
|
||||
node = ast.CharLiteral{
|
||||
|
@ -562,7 +567,7 @@ pub fn (p mut Parser) expr(precedence int) (ast.Expr,table.Type) {
|
|||
p.next()
|
||||
}
|
||||
.key_match {
|
||||
return p.match_expr()
|
||||
node,typ = p.match_expr()
|
||||
}
|
||||
.number {
|
||||
node,typ = p.parse_number_literal()
|
||||
|
@ -747,7 +752,16 @@ fn (p &Parser) is_addative() bool {
|
|||
return p.tok.kind in [.plus, .minus] && p.peek_tok.kind in [.number, .name]
|
||||
}
|
||||
*/
|
||||
|
||||
// `.green`
|
||||
fn (p mut Parser) enum_val() (ast.Expr,table.Type) {
|
||||
p.check(.dot)
|
||||
name := p.check_name()
|
||||
mut node := ast.Expr{}
|
||||
node = ast.EnumVal{
|
||||
name: name
|
||||
}
|
||||
return node,table.bool_type
|
||||
}
|
||||
|
||||
fn (p mut Parser) for_statement() ast.Stmt {
|
||||
p.check(.key_for)
|
||||
|
@ -815,7 +829,8 @@ fn (p mut Parser) for_statement() ast.Stmt {
|
|||
}
|
||||
p.check(.key_in)
|
||||
mut elem_type := table.void_type
|
||||
/*arr_expr*/_,arr_typ := p.expr(0)
|
||||
// arr_expr
|
||||
_,arr_typ := p.expr(0)
|
||||
// array / map
|
||||
arr_typ_sym := p.table.get_type_symbol(arr_typ)
|
||||
match arr_typ_sym.info {
|
||||
|
@ -826,8 +841,9 @@ fn (p mut Parser) for_statement() ast.Stmt {
|
|||
elem_type = it.value_type
|
||||
}
|
||||
else {
|
||||
//elem_type_sym := p.table.get_type_symbol(elem_type)
|
||||
//p.error('cannot loop over type: $elem_type_sym.name')
|
||||
println(1)
|
||||
// elem_type_sym := p.table.get_type_symbol(elem_type)
|
||||
// p.error('cannot loop over type: $elem_type_sym.name')
|
||||
}
|
||||
}
|
||||
// 0 .. 10
|
||||
|
@ -922,7 +938,7 @@ fn (p mut Parser) string_expr() (ast.Expr,table.Type) {
|
|||
}
|
||||
p.check(.str_dollar)
|
||||
p.expr(0)
|
||||
if p.tok.kind == .semicolon {
|
||||
if p.tok.kind == .colon {
|
||||
p.next()
|
||||
}
|
||||
}
|
||||
|
@ -945,6 +961,7 @@ fn (p mut Parser) array_init() (ast.Expr,table.Type) {
|
|||
// []
|
||||
else {
|
||||
// TODO ?
|
||||
println(0)
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -966,18 +983,15 @@ fn (p mut Parser) array_init() (ast.Expr,table.Type) {
|
|||
is_fixed = true
|
||||
val_type = p.parse_type()
|
||||
match exprs[0] {
|
||||
ast.IntegerLiteral { fixed_size = it.val }
|
||||
ast.IntegerLiteral {
|
||||
fixed_size = it.val
|
||||
}
|
||||
else {}
|
||||
}
|
||||
p.warn('fixed size array')
|
||||
}
|
||||
}
|
||||
idx := if is_fixed {
|
||||
p.table.find_or_register_array_fixed(val_type, fixed_size, 1)
|
||||
}
|
||||
else {
|
||||
p.table.find_or_register_array(val_type, 1)
|
||||
}
|
||||
idx := if is_fixed { p.table.find_or_register_array_fixed(val_type, fixed_size, 1) } else { p.table.find_or_register_array(val_type, 1) }
|
||||
array_type := table.new_type(idx)
|
||||
node = ast.ArrayInit{
|
||||
typ: array_type
|
||||
|
@ -1277,13 +1291,15 @@ fn (p mut Parser) match_expr() (ast.Expr,table.Type) {
|
|||
p.check(.lcbr)
|
||||
mut blocks := []ast.StmtBlock
|
||||
mut match_exprs := []ast.Expr
|
||||
mut return_type := table.void_type
|
||||
for {
|
||||
// p.tok.kind != .rcbr {
|
||||
match_expr,_ := p.expr(0)
|
||||
match_exprs << match_expr
|
||||
p.warn('match block')
|
||||
stmts := p.parse_block()
|
||||
blocks << ast.StmtBlock{
|
||||
stmts: p.parse_block()
|
||||
stmts: stmts
|
||||
}
|
||||
if p.tok.kind == .key_else {
|
||||
p.next()
|
||||
|
@ -1291,6 +1307,17 @@ fn (p mut Parser) match_expr() (ast.Expr,table.Type) {
|
|||
stmts: p.parse_block()
|
||||
}
|
||||
}
|
||||
// If the last statement is an expression, return its type
|
||||
if stmts.len > 0 {
|
||||
match stmts[stmts.len - 1] {
|
||||
ast.ExprStmt {
|
||||
type_sym := p.table.get_type_symbol(it.typ)
|
||||
p.warn('match expr ret $type_sym.name')
|
||||
return_type = it.typ
|
||||
}
|
||||
else {}
|
||||
}
|
||||
}
|
||||
if p.tok.kind == .rcbr {
|
||||
break
|
||||
}
|
||||
|
@ -1303,7 +1330,7 @@ fn (p mut Parser) match_expr() (ast.Expr,table.Type) {
|
|||
typ: typ
|
||||
cond: cond
|
||||
}
|
||||
return node,table.void_type
|
||||
return node,return_type
|
||||
}
|
||||
|
||||
fn (p mut Parser) add_unresolved(key string, expr ast.Expr) table.Type {
|
||||
|
|
|
@ -168,6 +168,7 @@ pub fn (p mut Table) clear_vars() {
|
|||
// ///}
|
||||
p.local_vars = []
|
||||
}
|
||||
p.tmp_cnt = 0
|
||||
}
|
||||
|
||||
pub fn (t &Table) find_fn(name string) ?Fn {
|
||||
|
@ -224,7 +225,6 @@ pub fn (t &TypeSymbol) find_method(name string) ?Fn {
|
|||
return none
|
||||
}
|
||||
|
||||
|
||||
pub fn (s &TypeSymbol) has_field(name string) bool {
|
||||
s.find_field(name) or {
|
||||
return false
|
||||
|
@ -302,7 +302,8 @@ pub fn (t &Table) get_type_symbol(typ Type) &TypeSymbol {
|
|||
kind: .unresolved
|
||||
name: 'unresolved-$unresolved_idx'
|
||||
}
|
||||
} else if idx > 0 {
|
||||
}
|
||||
else if idx > 0 {
|
||||
return &t.types[idx]
|
||||
}
|
||||
// this should never happen
|
||||
|
@ -319,8 +320,12 @@ pub fn (t mut Table) register_builtin_type_symbol(typ TypeSymbol) int {
|
|||
if existing_idx >= string_type_idx {
|
||||
if existing_idx == string_type_idx {
|
||||
existing_type := &t.types[existing_idx]
|
||||
t.types[existing_idx] = { typ | kind: existing_type.kind }
|
||||
} else {
|
||||
t.types[existing_idx] = {
|
||||
typ |
|
||||
kind:existing_type.kind
|
||||
}
|
||||
}
|
||||
else {
|
||||
t.types[existing_idx] = typ
|
||||
}
|
||||
}
|
||||
|
@ -473,8 +478,7 @@ pub fn (t &Table) check(got, expected Type) bool {
|
|||
if exp_type_sym.kind == .voidptr {
|
||||
return true
|
||||
}
|
||||
if got_type_sym.kind in [.voidptr, .byteptr, .charptr, .int] &&
|
||||
exp_type_sym.kind in [.voidptr, .byteptr, .charptr] {
|
||||
if got_type_sym.kind in [.voidptr, .byteptr, .charptr, .int] && exp_type_sym.kind in [.voidptr, .byteptr, .charptr] {
|
||||
return true
|
||||
}
|
||||
if got_type_sym.is_int() && exp_type_sym.is_int() {
|
||||
|
@ -489,7 +493,7 @@ pub fn (t &Table) check(got, expected Type) bool {
|
|||
// if expected.name == 'array' {
|
||||
// return true
|
||||
// }
|
||||
if got_idx != exp_idx /*&& got.typ.name != expected.typ.name*/ {
|
||||
if got_idx != exp_idx/*&& got.typ.name != expected.typ.name*/ {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
|
|
Loading…
Reference in New Issue