algebraic types are used in many places. due to sathers other features, only minimal syntactic sugar is needed to support them. typesafe union.
the sather compiler uses constructs very similar to algebraic types for its abstract syntax tree.
notice that each 'pass' over the abstract syntax is self contained, using method overloading the code for each pass would have to be spread out among the entire structure of the AST.
algebraic class $TYPE is
case TY_INT;
case TY_STRING;
case TY_BOOL;
case TY_FUNC(from:$TYPE, to:$TYPE);
case TY_TUPLE(fst:$TYPE, snd:$TYPE);
end;
algebraic class $STATEMENT is
case SEQ(seq:LIST{$STATEMENT});
case ASSIGN(var:STR, expr:$EXPR);
case DECLARE(var:STR, type:$TYPE);
case PRINT(expr:$EXPR);
end;
algebraic class $EXPR is
case CONSTANT_INT(val:INT);
case CONSTANT_STR(val:STR);
case TRUE;
case FALSE;
case PLUS(a:$EXPR, b:$EXPR);
end;
class OPTIMIZE is _____ see typecase chaining
optimize_expr(e:$EXPR):$EXPR is \/
typecase e
when PLUS then
typecase e.a when CONSTANT_INT then
typecase e.b when CONSTANT_INT
return #CONSTANT_INT(e.a.val + e.b.val)
else return e end;
else return e end;
else return e end;
end
end;
class PRETTYPRINT is
private attr indent:INT;
lineout:STR is return "\n" + " ".repeat(indent) end;
print_expr(e:$EXPR):STR is
typecase e
when TRUE then return "true"
when FALSE then return "false"
when CONSTANT_INT then return e.val.str
when CONSTANT_STR then return e.val.pretty
when PLUS then return "("print_expr(e.b)") + (" print_expr(e.a) ")"
end;
end;
print_statement(s:$STMT):STR is
typecase s
when SEQ then
res:STR;
loop res := res + (";" + lineout).seperate!(print_statement(s.seq.elt!)) end;
return res
when ASSIGN then s.var + " := " + print_expr(s.expr);
.
.
.
end;
class TYPECHECK is
.
.
.
.
end;
alg_class ::=
"algebraic" "class" "$"UPPERCASE_ID "is" alg_class_decls "end"
alg_case_decls ::= alg_case_decl (";"? | ";" alg_case_decls)
alg_case_decl ::= "case" UPPERCASE_ID ("(" attr_list ")" | "" )
attr_list ::=