|
| 1 | +@license{ |
| 2 | + Copyright (c) 2009-2015 CWI |
| 3 | + All rights reserved. This program and the accompanying materials |
| 4 | + are made available under the terms of the Eclipse Public License v1.0 |
| 5 | + which accompanies this distribution, and is available at |
| 6 | + http://www.eclipse.org/legal/epl-v10.html |
| 7 | +} |
| 8 | +module lang::rascal::scaffold::GenOperators |
| 9 | + |
| 10 | +import Relation; |
| 11 | +import Set; |
| 12 | +import List; |
| 13 | + |
| 14 | +public int numOfCases() = |
| 15 | + ( 0 | it + size(unOps[op]) | op <- unOps ) |
| 16 | + + ( 0 | it + size(binOps[op]) | op <- binOps ) |
| 17 | + + ( 0 | it + size(triOps[op]) | op <- triOps ); |
| 18 | + |
| 19 | +public map[str,set[str]] unOps = ( |
| 20 | + "FieldAccess": {"tuple", "loc", "map", "cons", "datetime"}, |
| 21 | + "FieldProject": {"rel"}, |
| 22 | + "Is": {"cons", "node"}, |
| 23 | + "Has": {"cons", "tuple", "rel", "map", "node"}, |
| 24 | + "TransitiveClosure": {"rel", "list"}, |
| 25 | + "TransitiveReflexiveClosure": {"rel", "list"}, |
| 26 | + "IsDefined": {"map"}, |
| 27 | + "Negation": {"bool"}, |
| 28 | + "Negative": {"num", "int", "real", "rat"}, |
| 29 | + "Splice": {"list", "set"} |
| 30 | +); |
| 31 | + |
| 32 | +public map[str, rel[str,str]] binOps = ( |
| 33 | + "Subscript": {<"tuple", "int">, <"list", "int">, <"node", "int">, |
| 34 | + <"map", "value">, <"rel", "value">, <"str", "int">}, |
| 35 | + "FieldUpdate": {<"tuple", "value">, <"loc", "value">, <"map", "value">, <"cons", "value">, |
| 36 | + <"datetime", "value">}, |
| 37 | + "SetAnnotation": {<"cons", "value">, <"node", "value">}, |
| 38 | + "GetAnnotation": {<"cons", "value">, <"node", "value">}, |
| 39 | + "Composition": {"fun", "map", "rel", "list"} * {"fun", "map", "rel", "list"}, |
| 40 | + "Product": {"set", "map", "list"} * {"set", "map", "list"} + |
| 41 | + {"int", "real", "rat", "num"} * {"int", "real", "rat", "num"} + |
| 42 | + {"int"} * {"list", "str", "set"}, |
| 43 | + "Join": {"set", "map", "list"} * {"set", "map", "list"}, |
| 44 | + "Remainder": {"int", "num", "rat"} * {"int", "num", "rat"}, |
| 45 | + "Division": {"int", "num", "real", "rat"} * {"int", "num", "real", "rat"}, |
| 46 | + "Intersection": {"set", "map", "list"} * {"set", "map", "list"}, |
| 47 | + "Addition": {"set", "list"} * {"set", "list"} + {<"map", "map">, <"str", "str">,<"fun", "fun">} + |
| 48 | + {"int", "num", "real", "rat"} * {"int", "num", "real", "rat"}, |
| 49 | + "Subtraction": {"set", "list"} * {"set", "list"} + {<"map", "map">, |
| 50 | + <"map", "list">, <"map", "set">, <"str", "str">} + |
| 51 | + {"int", "num", "real", "rat"} * {"int", "num", "real", "rat"}, |
| 52 | + "InsertAfter": {"set", "list"} * {"value"} + {<"str", "str">, <"int", "int">}, |
| 53 | + "InsertBefore": {"value"} * {"set", "list"} + {<"str", "str">, <"int", "int">}, |
| 54 | + "Modulo": {<"int", "int">, <"rat", "rat">}, |
| 55 | + "NotIn": {"value"} * {"set", "list", "map"} + {<"str", "str">}, |
| 56 | + "In": {"value"} * {"set", "list", "map"} + {<"str", "str">}, |
| 57 | + "GreaterThanOrEq": {"int", "rat", "real", "num"} * {"int", "rat", "real", "num"} + |
| 58 | + ident({"set", "list", "map", "str", "tuple", "loc", "datetime", "bool"}), |
| 59 | + "LessThanOrEq": {"int", "rat", "real", "num"} * {"int", "rat", "real", "num"} + |
| 60 | + ident({"set", "list", "map", "str", "tuple", "loc", "datetime", "bool"}), |
| 61 | + "LessThan": {"int", "rat", "real", "num"} * {"int", "rat", "real", "num", "bool"} + |
| 62 | + ident({"set", "list", "map", "str", "tuple", "loc", "datetime", "bool"}), |
| 63 | + "GreaterThan": {"int", "rat", "real", "num"} * {"int", "rat", "real", "num", "bool"} + |
| 64 | + ident({"set", "list", "map", "str", "tuple", "loc", "datetime", "bool"}), |
| 65 | + "Equals": ident({"int", "real", "num", "set", "list", "map", "str", "loc", "tuple", |
| 66 | + "datetime", "value", "cons", "node"}), |
| 67 | + "NonEquals": ident({"int", "real", "num", "rat", "set", "list", "map", "str", "loc", "tuple", |
| 68 | + "datetime", "value", "cons", "node", "bool"}), |
| 69 | + "IfDefinedOtherwise": {<"value", "value">}, |
| 70 | + "NoMatch": {<"value", "value">}, |
| 71 | + "Match": {<"value", "value">}, |
| 72 | + "Implication": {<"bool", "bool">}, |
| 73 | + "Equivalence": {<"bool", "bool">}, |
| 74 | + "And": {<"bool", "bool">}, |
| 75 | + "Or": {<"bool", "bool">} |
| 76 | +); |
| 77 | + |
| 78 | + public map[str, rel[str,str,str]] triOps = |
| 79 | + ("IfThenElse": {<"bool", "value", "value">}); |
| 80 | + |
| 81 | +public set[str] allTypes |
| 82 | + = ( {} | it + carrier(binOps[op]) | op <- binOps ) |
| 83 | + + ( {} | it + carrier(triOps[op]) | op <- triOps ) |
| 84 | + + ( {} | it + unOps[op] | op <- unOps ); |
| 85 | + |
| 86 | + // println(( "" | it + "public str type2iface(\"<t>\") = \"\";\n" | t <- allTypes )) |
| 87 | +public str type2iface("fun") = "FunctionType"; |
| 88 | +public str type2iface("list") = "IList"; |
| 89 | +public str type2iface("real") = "IReal"; |
| 90 | +public str type2iface("map") = "IMap"; |
| 91 | +public str type2iface("datetime") = "IDateTime"; |
| 92 | +public str type2iface("rel") = "IRelation"; |
| 93 | +public str type2iface("cons") = "IConstructor"; |
| 94 | +public str type2iface("str") = "IString"; |
| 95 | +public str type2iface("value") = "IValue"; |
| 96 | +public str type2iface("int") = "IInteger"; |
| 97 | +public str type2iface("bool") = "IBool"; |
| 98 | +public str type2iface("tuple") = "ITuple"; |
| 99 | +public str type2iface("num") = "INumber"; |
| 100 | +public str type2iface("rat") = "IRational"; |
| 101 | +public str type2iface("set") = "ISet"; |
| 102 | +public str type2iface("node") = "INode"; |
| 103 | +public str type2iface("loc") = "ISourceLocation"; |
| 104 | + |
| 105 | + |
| 106 | + |
| 107 | +public str genClasses() { |
| 108 | + ms = for (op <- binOps) { |
| 109 | + append genBinClass(op, binOps[op]); |
| 110 | + } |
| 111 | + return intercalate("\n\n", ms); |
| 112 | +} |
| 113 | + |
| 114 | +public str genBinClass(str op, rel[str,str] args) { |
| 115 | + return "public abstract class <classNameForOp(op)> extends Expression { |
| 116 | + ' <for (<a1, a2> <- args) {> |
| 117 | + ' <genMethod(op, [a1, a2])> |
| 118 | + ' <}> |
| 119 | + '}"; |
| 120 | +} |
| 121 | + |
| 122 | +public str classNameForOp(str op) = op; |
| 123 | + |
| 124 | +public str genMethod(str op, list[str] types) { |
| 125 | + // todo: do we need the return type or will we just cast? |
| 126 | + types = [ type2iface(t) | t <- types ]; |
| 127 | + params = [ "<types[i]> arg<i>" | i <- [0,1..size(types)] ]; |
| 128 | + return "public static abstract class <op>On<intercalate("And", types)> extends <classNameForOp(op)> { |
| 129 | + ' public IValue interpret(<intercalate(", ", params)>) { |
| 130 | + ' throw new ImplementationError(\"Operator <op> is not implemented for argument types <intercalate(" and ", types)>\"); |
| 131 | + ' } |
| 132 | + '}"; |
| 133 | +} |
| 134 | + |
0 commit comments