mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
cgen: sum types: match
This commit is contained in:
parent
98fc9ab65b
commit
37504c487a
@ -344,12 +344,13 @@ mut:
|
|||||||
|
|
||||||
pub struct MatchExpr {
|
pub struct MatchExpr {
|
||||||
pub:
|
pub:
|
||||||
tok_kind token.Kind
|
tok_kind token.Kind
|
||||||
cond Expr
|
cond Expr
|
||||||
branches []MatchBranch
|
branches []MatchBranch
|
||||||
pos token.Position
|
pos token.Position
|
||||||
mut:
|
mut:
|
||||||
expr_type table.Type // type of `x` in `match x {`
|
expr_type table.Type // type of `x` in `match x {`
|
||||||
|
is_sum_type bool
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MatchBranch {
|
pub struct MatchBranch {
|
||||||
|
@ -315,7 +315,7 @@ fn (g mut Gen) stmt(node ast.Stmt) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast.TypeDecl {
|
ast.TypeDecl {
|
||||||
g.writeln('// type')
|
g.writeln('// TypeDecl')
|
||||||
}
|
}
|
||||||
ast.UnsafeStmt {
|
ast.UnsafeStmt {
|
||||||
g.stmts(it.stmts)
|
g.stmts(it.stmts)
|
||||||
@ -728,7 +728,10 @@ fn (g mut Gen) expr(node ast.Expr) {
|
|||||||
}
|
}
|
||||||
g.write('if (')
|
g.write('if (')
|
||||||
for i, expr in branch.exprs {
|
for i, expr in branch.exprs {
|
||||||
if type_sym.kind == .string {
|
if it.is_sum_type {
|
||||||
|
g.write('${tmp}.typ == ')
|
||||||
|
}
|
||||||
|
else if type_sym.kind == .string {
|
||||||
g.write('string_eq($tmp, ')
|
g.write('string_eq($tmp, ')
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -909,7 +912,10 @@ fn (g mut Gen) expr(node ast.Expr) {
|
|||||||
g.write(it.field)
|
g.write(it.field)
|
||||||
}
|
}
|
||||||
ast.Type {
|
ast.Type {
|
||||||
g.write('/* Type */')
|
// match sum Type
|
||||||
|
// g.write('/* Type */')
|
||||||
|
g.write('_type_idx_')
|
||||||
|
g.write(g.typ(it.typ))
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// #printf("node=%d\n", node.typ);
|
// #printf("node=%d\n", node.typ);
|
||||||
@ -1270,7 +1276,7 @@ fn (g mut Gen) write_sorted_types() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn (g mut Gen) write_types(types []table.TypeSymbol) {
|
fn (g mut Gen) write_types(types []table.TypeSymbol) {
|
||||||
for typ in types {
|
for i, typ in types {
|
||||||
if typ.name.starts_with('C.') {
|
if typ.name.starts_with('C.') {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -1288,11 +1294,12 @@ fn (g mut Gen) write_types(types []table.TypeSymbol) {
|
|||||||
// g.definitions.writeln('} $name;\n')
|
// g.definitions.writeln('} $name;\n')
|
||||||
//
|
//
|
||||||
g.definitions.writeln('};\n')
|
g.definitions.writeln('};\n')
|
||||||
|
g.typedefs.writeln('#define _type_idx_$name $i')
|
||||||
}
|
}
|
||||||
table.Enum {
|
table.Enum {
|
||||||
g.definitions.writeln('typedef enum {')
|
g.definitions.writeln('typedef enum {')
|
||||||
for i, val in it.vals {
|
for j, val in it.vals {
|
||||||
g.definitions.writeln('\t${name}_$val, // $i')
|
g.definitions.writeln('\t${name}_$val, // $j')
|
||||||
}
|
}
|
||||||
g.definitions.writeln('} $name;\n')
|
g.definitions.writeln('} $name;\n')
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,15 @@
|
|||||||
|
struct IfExpr {
|
||||||
|
};
|
||||||
|
|
||||||
|
struct IntegerLiteral {
|
||||||
|
};
|
||||||
|
|
||||||
|
// Sum type
|
||||||
|
typedef struct {
|
||||||
|
void* obj;
|
||||||
|
int typ;
|
||||||
|
} Expr;
|
||||||
|
|
||||||
struct User {
|
struct User {
|
||||||
int age;
|
int age;
|
||||||
string name;
|
string name;
|
||||||
@ -8,6 +20,9 @@ struct User {
|
|||||||
typedef Option Option_int;
|
typedef Option Option_int;
|
||||||
Option_int get_opt();
|
Option_int get_opt();
|
||||||
void User_foo(User* u);
|
void User_foo(User* u);
|
||||||
|
void println(string s);
|
||||||
|
void handle_expr(Expr e);
|
||||||
|
// TypeDecl
|
||||||
|
|
||||||
Option_int get_opt() {
|
Option_int get_opt() {
|
||||||
return opt_ok(& (int []) { 0 }, sizeof(int));
|
return opt_ok(& (int []) { 0 }, sizeof(int));
|
||||||
@ -20,6 +35,26 @@ tos3(""),
|
|||||||
}), u->age);
|
}), u->age);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void println(string s) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_expr(Expr e) {
|
||||||
|
Expr tmp1 = e;
|
||||||
|
if (tmp1.typ == _type_idx_IfExpr) {
|
||||||
|
println(tos3("if"));
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (tmp1.typ == _type_idx_IntegerLiteral) {
|
||||||
|
println(tos3("integer"));
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
println(tos3("else"));
|
||||||
|
|
||||||
|
}
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
User user = (User){
|
User user = (User){
|
||||||
0};
|
0};
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
type Expr = IfExpr | IntegerLiteral
|
||||||
|
|
||||||
|
struct IfExpr{}
|
||||||
|
struct IntegerLiteral{}
|
||||||
|
|
||||||
struct User {
|
struct User {
|
||||||
age int
|
age int
|
||||||
name string
|
name string
|
||||||
@ -12,6 +17,26 @@ fn (u &User) foo() {
|
|||||||
zzz := [''].repeat(u.age)
|
zzz := [''].repeat(u.age)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn println(s string) {}
|
||||||
|
|
||||||
|
fn handle_expr(e Expr) {
|
||||||
|
match e {
|
||||||
|
IfExpr {
|
||||||
|
println('if')
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
IntegerLiteral {
|
||||||
|
println('integer')
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
println('else')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
user := User{}
|
user := User{}
|
||||||
user.age = 10
|
user.age = 10
|
||||||
|
@ -48,7 +48,7 @@ pub fn parse_stmt(text string, table &table.Table, scope &ast.Scope) ast.Stmt {
|
|||||||
pref: &pref.Preferences{}
|
pref: &pref.Preferences{}
|
||||||
scope: scope
|
scope: scope
|
||||||
// scope: &ast.Scope{start_pos: 0, parent: 0}
|
// scope: &ast.Scope{start_pos: 0, parent: 0}
|
||||||
|
|
||||||
}
|
}
|
||||||
p.init_parse_fns()
|
p.init_parse_fns()
|
||||||
p.read_first_token()
|
p.read_first_token()
|
||||||
@ -72,7 +72,7 @@ pub fn parse_file(path string, table &table.Table, comments_mode scanner.Comment
|
|||||||
parent: 0
|
parent: 0
|
||||||
}
|
}
|
||||||
// comments_mode: comments_mode
|
// comments_mode: comments_mode
|
||||||
|
|
||||||
}
|
}
|
||||||
p.read_first_token()
|
p.read_first_token()
|
||||||
// p.scope = &ast.Scope{start_pos: p.tok.position(), parent: 0}
|
// p.scope = &ast.Scope{start_pos: p.tok.position(), parent: 0}
|
||||||
@ -610,7 +610,7 @@ pub fn (p mut Parser) name_expr() ast.Expr {
|
|||||||
p.expr_mod = ''
|
p.expr_mod = ''
|
||||||
return ast.EnumVal{
|
return ast.EnumVal{
|
||||||
enum_name: enum_name // lp.prepend_mod(enum_name)
|
enum_name: enum_name // lp.prepend_mod(enum_name)
|
||||||
|
|
||||||
val: val
|
val: val
|
||||||
pos: p.tok.position()
|
pos: p.tok.position()
|
||||||
mod: mod
|
mod: mod
|
||||||
@ -703,7 +703,7 @@ pub fn (p mut Parser) expr(precedence int) ast.Expr {
|
|||||||
// Map `{"age": 20}` or `{ x | foo:bar, a:10 }`
|
// Map `{"age": 20}` or `{ x | foo:bar, a:10 }`
|
||||||
.lcbr {
|
.lcbr {
|
||||||
p.next()
|
p.next()
|
||||||
if p.tok.kind == .string{
|
if p.tok.kind == .string {
|
||||||
mut keys := []ast.Expr
|
mut keys := []ast.Expr
|
||||||
mut vals := []ast.Expr
|
mut vals := []ast.Expr
|
||||||
for p.tok.kind != .rcbr && p.tok.kind != .eof {
|
for p.tok.kind != .rcbr && p.tok.kind != .eof {
|
||||||
@ -941,7 +941,7 @@ fn (p mut Parser) infix_expr(left ast.Expr) ast.Expr {
|
|||||||
left: left
|
left: left
|
||||||
right: right
|
right: right
|
||||||
// right_type: typ
|
// right_type: typ
|
||||||
|
|
||||||
op: op
|
op: op
|
||||||
pos: pos
|
pos: pos
|
||||||
}
|
}
|
||||||
@ -1055,7 +1055,7 @@ fn (p mut Parser) for_statement() ast.Stmt {
|
|||||||
p.scope.register_var(ast.Var{
|
p.scope.register_var(ast.Var{
|
||||||
name: var_name
|
name: var_name
|
||||||
// expr: cond
|
// expr: cond
|
||||||
|
|
||||||
})
|
})
|
||||||
stmts := p.parse_block()
|
stmts := p.parse_block()
|
||||||
// println('nr stmts=$stmts.len')
|
// println('nr stmts=$stmts.len')
|
||||||
@ -1150,11 +1150,11 @@ fn (p mut Parser) if_expr() ast.Expr {
|
|||||||
stmts: stmts
|
stmts: stmts
|
||||||
else_stmts: else_stmts
|
else_stmts: else_stmts
|
||||||
// typ: typ
|
// typ: typ
|
||||||
|
|
||||||
pos: pos
|
pos: pos
|
||||||
has_else: has_else
|
has_else: has_else
|
||||||
// left: left
|
// left: left
|
||||||
|
|
||||||
}
|
}
|
||||||
return node
|
return node
|
||||||
}
|
}
|
||||||
@ -1169,7 +1169,7 @@ fn (p mut Parser) string_expr() ast.Expr {
|
|||||||
return node
|
return node
|
||||||
}
|
}
|
||||||
// Handle $ interpolation
|
// Handle $ interpolation
|
||||||
for p.tok.kind == .string{
|
for p.tok.kind == .string {
|
||||||
p.next()
|
p.next()
|
||||||
if p.tok.kind != .str_dollar {
|
if p.tok.kind != .str_dollar {
|
||||||
continue
|
continue
|
||||||
@ -1329,7 +1329,7 @@ fn (p mut Parser) const_decl() ast.ConstDecl {
|
|||||||
fields << ast.Field{
|
fields << ast.Field{
|
||||||
name: name
|
name: name
|
||||||
// typ: typ
|
// typ: typ
|
||||||
|
|
||||||
}
|
}
|
||||||
exprs << expr
|
exprs << expr
|
||||||
// TODO: once consts are fixed reg here & update in checker
|
// TODO: once consts are fixed reg here & update in checker
|
||||||
@ -1596,6 +1596,7 @@ fn (p mut Parser) global_decl() ast.GlobalDecl {
|
|||||||
fn (p mut Parser) match_expr() ast.MatchExpr {
|
fn (p mut Parser) match_expr() ast.MatchExpr {
|
||||||
p.check(.key_match)
|
p.check(.key_match)
|
||||||
is_mut := p.tok.kind == .key_mut
|
is_mut := p.tok.kind == .key_mut
|
||||||
|
mut is_sum_type := false
|
||||||
if is_mut {
|
if is_mut {
|
||||||
p.next()
|
p.next()
|
||||||
}
|
}
|
||||||
@ -1626,6 +1627,7 @@ fn (p mut Parser) match_expr() ast.MatchExpr {
|
|||||||
p.next()
|
p.next()
|
||||||
p.parse_type()
|
p.parse_type()
|
||||||
}
|
}
|
||||||
|
is_sum_type = true
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Expression match
|
// Expression match
|
||||||
@ -1653,6 +1655,7 @@ fn (p mut Parser) match_expr() ast.MatchExpr {
|
|||||||
return ast.MatchExpr{
|
return ast.MatchExpr{
|
||||||
branches: branches
|
branches: branches
|
||||||
cond: cond
|
cond: cond
|
||||||
|
is_sum_type: is_sum_type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user