ometa Parser { ws = ' ', nl = "\n", digit = '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9', lowercase = "a"|"b"|"c"|"d"|"e"|"f"|"g"|"h"|"i"|"j"|"k"|"l"|"m"|"n"|"o"|"p"|"q"|"r"|"s"|"t"|"u"|"v"|"w"|"x"|"y"|"z", uppercase = "A"|"B"|"C"|"D"|"E"|"F"|"G"|"H"|"I"|"J"|"K"|"L"|"M"|"N"|"O"|"P"|"Q"|"R"|"S"|"T"|"U"|"V"|"W"|"X"|"Y"|"Z", letter = (lowercase|uppercase):x -> x, var = uppercase:x letter*:y -> ["var", x + y.join("")], pair = literal:x ":" literal:y -> ["pair", x, y], integer = digit+:x -> ["integer", x.join("")], float = digit+:x '.' digit+:y -> ["float", x.join("") + "." + y.join("")], atom = lowercase:x letter*:y -> ["atom", x + y.join("")], string = '"' letter*:x '"' -> ["string", x.join("")], list = "[" literal+:x "]" -> ["list", x], set = "(" literal+:x ")" -> ["set", x], map = "{" pair+:x "}" -> ["map", x], bool = ("true"|"false"):x -> ["bool", x], nil = "nil":x -> ["nil", x], header = "(" uppercase*:x ")" -> x, body = (assign|literal):x -> x, method = "method" header:x body:y "end" -> ["method", x, y], literal = ws* (method|float|integer|bool|nil|atom|string|list|set|map):x ws* -> x, expression = literal, property = (uppercase:x letter*:y) "." (uppercase:v letter*:w) -> ["property", x + y.join(""), v + w.join("")], assign = (property|var):x ws* ":" ws* (property|var|literal):y -> ["assign", x, y], statement = ws* assign:x ws* -> x } string = "X: 3" tree = Parser.matchAll(string, "assign") pool = { reg: 0, next: function () { last = this.reg; reg++; return " " + last.toString(); }, mapping: {}, setVar: function(key) { this.mapping[key] = this.next(); return ""; } } ometa Assembler { literal = ['integer' anything:x] -> ("INTEGER_CREATE " + x.toString()) | ['float' anything:x] -> ("FLOAT_CREATE " + x.toString()) | ['atom' anything:x] -> ("ATOM_CREATE " + x) | ['string' anything:x] -> ("STRING_CREATE " + x) | ['bool' anything:x] -> ("BOOL_CREATE " + x) | ['nil' anything:x] -> "NIL_CREATE", assign = ['assign' ['var' anything:x] literal:y] -> (y + pool.next()) } Assembler.match(tree, "assign")