module ast; import std.stdio; import std.string; import std.regexp; import lqtypes; class ASTElement { // makeshift string representation used for testing abstract string toString() { return ""; } LqType convert() { throw new Exception("abstract method"); } } class ASTAtom : ASTElement { string data; this(string s) { this.data = s; } string toString() { return data; } LqType convert() { /* I suppose we can precompile the regexen later... */ if (auto m = std.regexp.search(this.data, r"^-?\d+$")) { return LqInteger.from_token(this.data); } if (auto m = std.regexp.search(this.data, "^\".*\"$")) { return LqString.from_token(this.data); } if (auto m = std.regexp.search(this.data, r"^:\S+$")) { return LqKeyword.from_token(this.data); } /* anything else is a symbol */ return LqSymbol.from_token(this.data); } } class ASTList : ASTElement { ASTElement[] data; this(ASTElement[] tokens) { this.data = tokens; } string toString() { string[] parts = []; foreach (ASTElement e; this.data) { parts ~= e.toString(); } return "(" ~ join(parts, " ") ~ ")"; } LqType convert() { if (this.data.length == 0) return LQ_EMPTY_LIST(); /* otherwise, convert this to an LqPair, converting sub-elements as we go */ LqType[] converted = []; foreach (ASTElement e; this.data) { LqType q = e.convert(); converted ~= q; } return LqList.from_list(converted); } } unittest { void test_atom_convert() { ASTAtom a1 = new ASTAtom("34"); auto q1 = a1.convert(); assert(q1.type_indicator() == "integer", q1.type_indicator()); ASTAtom a2 = new ASTAtom("set!"); auto q2 = a2.convert(); assert(q2.type_indicator() == "symbol", q2.type_indicator()); ASTAtom a3 = new ASTAtom("\"ha people\""); auto q3 = a3.convert(); assert(q3.type_indicator() == "string", q3.type_indicator()); } void test_list_convert() { ASTList a1 = new ASTList([]); auto q1 = a1.convert(); assert(q1.type_indicator() == "empty-list", q1.type_indicator()); assert(q1.lq_repr() == "()"); ASTElement[] tokens2 = [a1]; tokens2 ~= new ASTAtom("34"); /* cannot be added in the same literal */ ASTList a2 = new ASTList(tokens2); auto q2 = a2.convert(); assert(q2.type_indicator() == "pair", q1.type_indicator()); assert(q2.lq_repr() == "(() 34)", q2.lq_repr()); } writefln("unittest: ast"); test_atom_convert(); test_list_convert(); }