v2: update MatchExpr
							parent
							
								
									ed763df42e
								
							
						
					
					
						commit
						e71948461e
					
				| 
						 | 
				
			
			@ -217,11 +217,6 @@ mut:
 | 
			
		|||
	typ  table.Type
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub struct StmtBlock {
 | 
			
		||||
pub:
 | 
			
		||||
	stmts []Stmt
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub struct File {
 | 
			
		||||
pub:
 | 
			
		||||
	path    string
 | 
			
		||||
| 
						 | 
				
			
			@ -340,13 +335,20 @@ pub struct MatchExpr {
 | 
			
		|||
pub:
 | 
			
		||||
	tok_kind    token.Kind
 | 
			
		||||
	cond        Expr
 | 
			
		||||
	blocks      []StmtBlock
 | 
			
		||||
	match_exprs []Expr
 | 
			
		||||
	branches    []MatchBranch
 | 
			
		||||
	pos         token.Position
 | 
			
		||||
mut:
 | 
			
		||||
	typ         table.Type
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub struct MatchBranch {
 | 
			
		||||
pub:
 | 
			
		||||
	exprs []Expr
 | 
			
		||||
	stmts []Stmt
 | 
			
		||||
	pos   token.Position
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
pub struct CompIf {
 | 
			
		||||
pub:
 | 
			
		||||
	cond       Expr
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -666,20 +666,20 @@ pub fn (c mut Checker) ident(ident mut ast.Ident) table.Type {
 | 
			
		|||
 | 
			
		||||
pub fn (c mut Checker) match_expr(node mut ast.MatchExpr) table.Type {
 | 
			
		||||
	t := c.expr(node.cond)
 | 
			
		||||
	c.expected_type = t
 | 
			
		||||
	mut ret_type := table.void_type
 | 
			
		||||
	for i, block in node.blocks {
 | 
			
		||||
		if i < node.match_exprs.len {
 | 
			
		||||
			match_expr := node.match_exprs[i]
 | 
			
		||||
	for branch in node.branches {
 | 
			
		||||
		for expr in branch.exprs {
 | 
			
		||||
			c.expected_type = t
 | 
			
		||||
			typ := c.expr(match_expr)
 | 
			
		||||
			typ := c.expr(expr)
 | 
			
		||||
			typ_sym := c.table.get_type_symbol(typ)
 | 
			
		||||
			// TODO:
 | 
			
		||||
			if typ_sym.kind == .sum_type {}
 | 
			
		||||
		}
 | 
			
		||||
		c.stmts(block.stmts)
 | 
			
		||||
		c.stmts(branch.stmts)
 | 
			
		||||
		// If the last statement is an expression, return its type
 | 
			
		||||
		if block.stmts.len > 0 {
 | 
			
		||||
			match block.stmts[block.stmts.len - 1] {
 | 
			
		||||
		if branch.stmts.len > 0 {
 | 
			
		||||
			match branch.stmts[branch.stmts.len - 1] {
 | 
			
		||||
				ast.ExprStmt {
 | 
			
		||||
					ret_type = c.expr(it.expr)
 | 
			
		||||
				}
 | 
			
		||||
| 
						 | 
				
			
			@ -690,7 +690,7 @@ pub fn (c mut Checker) match_expr(node mut ast.MatchExpr) table.Type {
 | 
			
		|||
				// node.typ = typ
 | 
			
		||||
				// return typ
 | 
			
		||||
				else {}
 | 
			
		||||
	}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	node.typ = t
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -351,12 +351,17 @@ fn (g mut Gen) expr(node ast.Expr) {
 | 
			
		|||
			g.write('$type_sym.name $tmp = ')
 | 
			
		||||
			g.expr(it.cond)
 | 
			
		||||
			g.writeln(';') // $it.blocks.len')
 | 
			
		||||
			for i, block in it.blocks {
 | 
			
		||||
				match_expr := it.match_exprs[i]
 | 
			
		||||
				g.write('if $tmp == ')
 | 
			
		||||
				g.expr(match_expr)
 | 
			
		||||
			for branch in it.branches {
 | 
			
		||||
				g.write('if ')
 | 
			
		||||
				for i, expr in branch.exprs {
 | 
			
		||||
					g.write('$tmp == ')
 | 
			
		||||
					g.expr(expr)
 | 
			
		||||
					if i < branch.exprs.len-1 {
 | 
			
		||||
						g.write(' || ')
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				g.writeln('{')
 | 
			
		||||
				g.stmts(block.stmts)
 | 
			
		||||
				g.stmts(branch.stmts)
 | 
			
		||||
				g.writeln('}')
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1702,27 +1702,28 @@ fn (p mut Parser) global_decl() ast.GlobalDecl {
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn (p mut Parser) match_expr() ast.Expr {
 | 
			
		||||
fn (p mut Parser) match_expr() ast.MatchExpr {
 | 
			
		||||
	p.check(.key_match)
 | 
			
		||||
	is_mut := p.tok.kind == .key_mut
 | 
			
		||||
	if is_mut {
 | 
			
		||||
		p.next()
 | 
			
		||||
	}
 | 
			
		||||
	cond,_ := p.expr(0)
 | 
			
		||||
	// sym := p.table.get_type_symbol(typ)
 | 
			
		||||
	// p.warn('match typ $sym.name')
 | 
			
		||||
	p.check(.lcbr)
 | 
			
		||||
	mut blocks := []ast.StmtBlock
 | 
			
		||||
	mut match_exprs := []ast.Expr
 | 
			
		||||
	// mut return_type := table.void_type
 | 
			
		||||
	mut branches := []ast.MatchBranch
 | 
			
		||||
	for {
 | 
			
		||||
		mut exprs := []ast.Expr
 | 
			
		||||
		p.open_scope()
 | 
			
		||||
		// final else
 | 
			
		||||
		if p.tok.kind == .key_else {
 | 
			
		||||
			p.next()
 | 
			
		||||
		}
 | 
			
		||||
		// Sum type match
 | 
			
		||||
		if p.tok.kind == .name && (p.tok.lit[0].is_capital() || p.peek_tok.kind == .dot) {
 | 
			
		||||
		else if p.tok.kind == .name && (p.tok.lit[0].is_capital() || p.peek_tok.kind == .dot) {
 | 
			
		||||
			// if sym.kind == .sum_type {
 | 
			
		||||
			// p.warn('is sum')
 | 
			
		||||
			typ := p.parse_type()
 | 
			
		||||
			match_exprs << ast.Type{
 | 
			
		||||
			exprs << ast.Type{
 | 
			
		||||
				typ: typ
 | 
			
		||||
			}
 | 
			
		||||
			p.scope.register_var(ast.VarDecl{
 | 
			
		||||
| 
						 | 
				
			
			@ -1733,8 +1734,8 @@ fn (p mut Parser) match_expr() ast.Expr {
 | 
			
		|||
		else {
 | 
			
		||||
			// Expression match
 | 
			
		||||
			for {
 | 
			
		||||
				match_expr,_ := p.expr(0)
 | 
			
		||||
				match_exprs << match_expr
 | 
			
		||||
				expr,_ := p.expr(0)
 | 
			
		||||
				exprs << expr
 | 
			
		||||
				if p.tok.kind != .comma {
 | 
			
		||||
					break
 | 
			
		||||
				}
 | 
			
		||||
| 
						 | 
				
			
			@ -1743,45 +1744,21 @@ fn (p mut Parser) match_expr() ast.Expr {
 | 
			
		|||
		}
 | 
			
		||||
		// p.warn('match block')
 | 
			
		||||
		stmts := p.parse_block()
 | 
			
		||||
		blocks << ast.StmtBlock{
 | 
			
		||||
		branches << ast.MatchBranch{
 | 
			
		||||
			exprs: exprs
 | 
			
		||||
			stmts: stmts
 | 
			
		||||
			
 | 
			
		||||
		}
 | 
			
		||||
		if p.tok.kind == .key_else {
 | 
			
		||||
			p.next()
 | 
			
		||||
			blocks << ast.StmtBlock{
 | 
			
		||||
				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 {}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		*/
 | 
			
		||||
 | 
			
		||||
		p.close_scope()
 | 
			
		||||
		if p.tok.kind == .rcbr {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	p.check(.rcbr)
 | 
			
		||||
	mut node := ast.Expr{}
 | 
			
		||||
	node = ast.MatchExpr{
 | 
			
		||||
		blocks: blocks
 | 
			
		||||
		match_exprs: match_exprs
 | 
			
		||||
		// typ: typ
 | 
			
		||||
		
 | 
			
		||||
	return ast.MatchExpr{
 | 
			
		||||
		branches: branches
 | 
			
		||||
		cond: cond
 | 
			
		||||
	}
 | 
			
		||||
	return node
 | 
			
		||||
	// return node,return_type
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn (p mut Parser) enum_decl() ast.EnumDecl {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue