// This is Jarkko Kniivilä trying to grok OMeta and make a Limbo language recognizer ometa LimboParser <: Parser { escapeChar = '\\' char:c -> unescape('\\' + c), plainStringConstant = '"' (escapeChar | ~'"' char)*:cs '"' -> [`stringCon, cs.join('')], stringConstant = spaces plainStringConstant, identifierFirst = '_' | letter, identifierRest = identifierFirst | digit, plainIdentifier = firstAndRest(`identifierFirst, `identifierRest):xs -> xs.join(''), identifier = spaces plainIdentifier:t -> [`name, t], identifier_opt = identifier | empty, identifierList = identifierList:xs "," identifier:x -> [xs, x] | identifier, program = "implement" identifier:n ";" topDeclarationSequence:xs -> [`program, n, xs], topDeclarationSequence = topDeclarationSequence:xs topDeclaration:x -> [xs, x] | topDeclaration, topDeclaration = declaration | identifierList:xs ":=" expression:x ";" -> ["top:=", xs, x] | identifierList:xs "=" expression:x ";" -> ["top=", xs, x] | "(" identifierList:xs ")" ":=" expression:x ";" -> ["topTuple:=", xs, x] | moduleDeclaration | functionDeclaration | adtDeclaration, declaration = identifierList:xs ":" "con" expression:x ";" -> ["decl:con", xs, x] | identifierList:xs ":" "import" identifier:x ";" -> ["decl:import", xs, x] | identifierList:xs ":" "type" type:t ";" -> ["decl:type", xs, t] | identifierList:xs ":" type:t "=" expression:x ";" -> ["decl:val", xs, t, x] | identifierList:xs ":" type:t ";" -> ["decl:", xs, t] | "include" stringConstant, expressionList = expressionList:xs "," expression:x -> [xs, x] | expression, expressionList_opt = expressionList | empty, type = functionType | dataType, dataType = "byte" -> `byte | "int" -> `int | "big" -> `big | "real" -> `real | "string" -> `string | tupleType | "array" "of" dataType:t -> [`arrayOfType, t] | "list" "of" dataType:t -> [`listOfType, t] | "chan" "of" dataType:t -> [`chanOfType, t] | "ref" adtType:t -> [`ref, t] | adtType | moduleType | moduleQualifiedType | typeName, tupleType = "(" dataTypeList:t ")" -> [`tuple, t], dataTypeList = dataTypeList:xs "," dataType:x -> [xs, x] | dataType, adtType = moduleQualifiedType | identifier, moduleType = identifier:t -> [`modType, t], moduleQualifiedType = identifier:m "->" identifier:t -> [`modQualType, m, t], typeName = identifier:t -> [`typeName, t], functionType = "fn" functionArgRet:t -> [`fnType, t], functionArgRet = "(" formalArgList:xs ")" ":" dataType:x -> [`formalArgsRet, x, xs] | "(" formalArgList:xs ")" -> [`formalArgs, xs], formalArgList = formalArgList:xs "," formalArg:x -> [xs, x] | formalArg | empty, formalArg = nilOrD:x ":" "self" "ref" identifier:y -> [":selfRef", x, y] | nilOrD:x ":" "self" identifier:y -> [":self", x, y] | nilOrDList:xs ":" type:y -> [":", xs, y] | <"*">, nilOrDList = nilOrDList:xs "," nilOrD:x -> [xs, x] | nilOrD, nilOrD = <"nil"> | identifier, moduleDeclaration = identifier:x ":" "module" "{" modMemberList:xs "}" ";" -> [`modDecl, x, xs], modMemberList = modMemberList:xs modMember:x -> [xs, x] | modMember | empty, modMember = identifierList:xs ":" functionType:y ";" -> [":", xs, y] | adtDeclaration | identifierList:xs ":" "type" type:y ";" -> [":type", xs, y] | identifierList:xs ":" dataType:y ";" -> [":", xs, y], adtDeclaration = identifier:x ":" "adt" "{" adtMemberList:ys "}" ";" -> [":adt", x, ys], adtMemberList = adtMemberList:xs adtMember:x -> [xs, x] | adtMember | empty, adtMember = identifierList:xs ":" functionType:y ";" -> [":", xs, y] | identifierList:xs ":" cyclic:o dataType:y ";" -> [":", o, xs, y], cyclic = <"cyclic"> | empty, functionDefinition = functionNamePart:n functionArgRet:a "{" statements:xs "}" -> [`fnDef, n, a, xs], functionNamePart = functionNamePart:xs "." identifier:n -> [".", xs, n] | identifier, statements = statements:xs declaration:y -> [xs, "decl::", y] | statements:xs statement:y -> [xs, y] | empty, statement = "{" statements:xs "}" -> [`block, xs] | "if" "(" expression:p ")" statement:x "else" statement:y -> [`ifThenElse, p, x, y] | "if" "(" expression:p ")" statement:x -> [`ifThen, p, x] | label_opt:l "while" "(" expression_opt:p ")" statement:x -> [`while, l, p, x] | label_opt:l "do" statement:x "while" "(" expression_opt:p ")" -> [`doWhile, l, x, p] | label_opt:l "for" "(" expression_opt:x ";" expression_opt:p ";" expression_opt:y ")" statement:z -> [`for, x, p, y, z] | label_opt:l "case" expression:x "{" qualStatementSequence:ys "}" -> [`case, x, ys] | label_opt:l "alt" "{" qualStatementSequence:ys "}" -> [`alt, ys] | "break" identifier_opt:n ";" -> [`break, n] | "continue" expression_opt:x ";" -> [`continue, x] | "return" expression_opt:x ";" -> [`return, x] | "spawn" term:x "(" expressionList_opt:ys ")" ";" -> [`spawn, x, ys] | "exit" ";" -> [`exit] | expression:xs ";" -> [`stmt, xs] | ";" -> [`emptyStmt], label = identifier:l -> [`label, l], label_opt = label | empty, qualStatementSequence = qualStatementSequence:xs qualList:ys "=>" -> [`qual, xs, ys, "=>"] | qualStatementSequence:xs statement:y -> [`qual, xs, y] | qualStatementSequence:xs declaration:y -> [`qualDecl, xs, y] | qualList:xs "=>" -> [`qual, xs, "=>"], qualList = qualList:xs "or" qualifier:x -> ["qual:or", xs, x] | qualifier, qualifier = expression:x to expression:y -> ["qual:to", x, y] | expression | "*" -> "qual:star", expression = binaryExpression | lvalueExpression:l assignmentOperator:op expression:r -> ["=", op, l, r] | "(" lvalueExpressionList:l ")" "=" expression:r -> ["=tuple", l, r] | sendExpression | declareExpression | loadExpression, expression_opt = expression | empty, binaryExpression = binaryExpression:l binaryOperator:op binaryExpression:r -> ["binOp", op, l, r] | monadicExpression, binaryOperator = "*" | "/" | "%" | "+" | "-" | "<<" | ">>" | "<" | ">" | "<=" | ">=" | "==" | "!=" | "&" | "^" | "|" | "::" | "&&" | "||", assignmentOperator = "=" | "&=" | "|=" | "^=" | "<<=" | ">>=" | "+=" | "-=" | "*=" | "/=" | "%=", lvalueExpression = term:x "[" expression:y "]" -> [`lvalueIndex, x, y] | term:x "[" expression:y ":" "]" -> [`lvalueSlice, x, y] | term:x "." identifier:y -> [`lvalueDot, x, y] | "(" lvalueExpressionList:xs ")" -> [`lvalueTuple, xs] | "*" monadicExpression:x -> [`lvalueStar, x] | <"nil"> | identifier, lvalueExpressionList = lvalueExpressionList:xs "," lvalueExpression:x -> [xs, x] | lvalueExpression, monadicExpression = monadicOperator:op monadicExpression:x -> [`monOp, op, x] | "array" "[" expression:s "]" "of" dataType:t -> [`array, s, t] | "array" "[" expression_opt:s "]" "of" "{" initList:xs "}" -> [`arrayInit, s, xs] | "list" "of" "{" expressionList:xs "}" -> [`list, xs] | "chan" "of" dataType:t -> [`chan, t] | term | dataType:t monadicExpression:x -> [`cast, t, x], term = "(" expressionList:xs ")" -> ["()", xs] | term:x "." identifier:y -> [`dot, x, y] | term:x "->" term:y -> ["->", x, y] | term:fn "(" expressionList_opt:xs ")" -> [`fnCall, fn, xs] | term:x "[" expression:i "]" -> [`index, x, i] | term:x "[" expression:a ":" expression:b "]" -> [`slice, x, a, b] | term:x "[" expression:a ":" "]" -> [`sliceBegin, x, a] | term:x "++" -> [`incr, x] | term:x "--" -> [`decr, x] | <"nil"> | stringConstant | identifier, monadicOperator = "+" | "-" | "!" | "~" | "ref" | "*" | "<-" | "hd" | "tl" | "len", initList = initList:xs "," element:y -> [xs, y] | element, element = expression:x "=>" expression:y -> ["=>", x, y] | "*" "=>" expression:y -> ["*=>", y] | expression, sendExpression = lvalueExpression:l "<-" "=" expression:r -> [`send, l, r], declareExpression = lvalueExpression:l ":=" expression:r -> [":=", l, r], loadExpression = "load" identifier:n expression:x -> [`load, n, x] } input = """ load Sys Sys->PATH; """ LimboParser.matchAll(input, "loadExpression") [load, [name, Sys], [->, [name, Sys], [name, PATH]]]