| 1 | module Mal |
| 2 | class Symbol |
| 3 | property :str |
| 4 | def initialize(@str) |
| 5 | end |
| 6 | end |
| 7 | |
| 8 | class List < Array(Type) |
| 9 | end |
| 10 | |
| 11 | class Vector < Array(Type) |
| 12 | end |
| 13 | |
| 14 | class HashMap < Hash(String, Type) |
| 15 | end |
| 16 | |
| 17 | class Type |
| 18 | alias Func = (Array(Type) -> Type) |
| 19 | alias ValueType = Nil | Bool | Int32 | String | Symbol | List | Vector | HashMap | Func |
| 20 | |
| 21 | def initialize(@val : ValueType) |
| 22 | end |
| 23 | |
| 24 | def initialize(other : Type) |
| 25 | @val = other.unwrap |
| 26 | end |
| 27 | |
| 28 | def unwrap |
| 29 | @val |
| 30 | end |
| 31 | |
| 32 | def ==(other : Mal::Type) |
| 33 | @val == other.unwrap |
| 34 | end |
| 35 | |
| 36 | macro rel_op(*ops) |
| 37 | {% for op in ops %} |
| 38 | def {{op.id}}(other : Mal::Type) |
| 39 | l, r = @val, other.unwrap |
| 40 | {% for t in [Int32, String] %} |
| 41 | if l.is_a?({{t}}) && r.is_a?({{t}}) |
| 42 | return (l) {{op.id}} (r) |
| 43 | end |
| 44 | {% end %} |
| 45 | if l.is_a?(Symbol) && r.is_a?(Symbol) |
| 46 | return l.str {{op.id}} r.str |
| 47 | end |
| 48 | false |
| 49 | end |
| 50 | {% end %} |
| 51 | end |
| 52 | |
| 53 | rel_op :<, :>, :<=, :>= |
| 54 | end |
| 55 | |
| 56 | alias Func = Type::Func |
| 57 | end |
| 58 | |
| 59 | macro gen_type(t) |
| 60 | Mal::Type.new {{t.id}}.new |
| 61 | end |