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