/** * @param argumentNode the ARGUMENTS AST node * @param args list of ASExpression objects to be used as the new argument list */ public static void overwriteArgsWithExpressionList(LinkedListTree argumentNode, List args) { // get rid of any old arguments, ASTUtils.deleteAllChildren(argumentNode); // add the new arguments, for (Iterator i = args.iterator(); i.hasNext(); ) { ASTExpression arg = (ASTExpression) i.next(); argumentNode.addChildWithTokens(arg.getAST()); if (i.hasNext()) { argumentNode.appendToken(TokenBuilder.newComma()); argumentNode.appendToken(TokenBuilder.newSpace()); } } }
public Expression gen(Context ctx) throws SemanticException { Expression res = null; Expression srcExpr = null; String opname = fOp.getText(); if (fSrcExpr != null) { srcExpr = fSrcExpr.gen(ctx); res = gen1(ctx, srcExpr); } else { // if no source expression is given, it is either a // variable or a reference to expression determined by // context. In the latter case we use the context as // source expression and proceed as if it has been given // explicitly. if (!fHasParentheses) { // variable? // (7) check for variable Type type = ctx.varTable().lookup(opname); if (type != null) res = new ExpVariable(opname, type); } // do we have a context expression that is implicitly // assumed to be the source expression? if (res == null) { ExprContext ec = ctx.exprContext(); if (!ec.isEmpty()) { // construct source expression ExprContext.Entry e = ec.peek(); srcExpr = new ExpVariable(e.fName, e.fType); if (e.fType.isCollection()) fFollowsArrow = true; res = gen1(ctx, srcExpr); } else throw new SemanticException( fOp, "Undefined " + (fHasParentheses ? "operation" : "variable") + " `" + opname + "'."); } } if (fIsPre) { if (!ctx.insidePostCondition()) throw new SemanticException(fOp, "Modifier @pre is only allowed in postconditions."); res.setIsPre(); } if (opname.equals("oclIsNew")) { if (!ctx.insidePostCondition()) throw new SemanticException(fOp, "Operation oclIsNew is only allowed in postconditions."); } return res; }
public Object visit(ASTExpression node, Object data) { System.out.println("Visiting ASTExpression node"); return node.childrenAccept(this, data); }
public Expression gen(Context ctx) throws SemanticException { String opname = fOp.getText(); Expression res = null; Expression range, expr; // check for empty range: do we have a context expression that // is implicitly assumed to be the source expression? if (fRange != null) range = fRange.gen(ctx); else { ExprContext ec = ctx.exprContext(); if (!ec.isEmpty()) { // construct source expression ExprContext.Entry e = ec.peek(); range = new ExpVariable(e.fName, e.fType); } else throw new SemanticException(fOp, "Need a collection to apply `" + opname + "'."); } if (!range.type().isCollection()) throw new SemanticException( fOp, "Source of `" + opname + "' expression must be a collection, " + "found source expression of type `" + range.type() + "'."); VarDeclList declList = new VarDeclList(true); if (fDeclList.isEmpty()) { // when there are no explicit var decls, we declare an // internal variable with the element type ExprContext ec = ctx.exprContext(); CollectionType ct = (CollectionType) range.type(); String var = ec.push(ct.elemType()); expr = fExpr.gen(ctx); ec.pop(); // use the generated element variable VarDecl decl = new VarDecl(var, ct.elemType()); declList.add(decl); } else { declList = fDeclList.gen(ctx, range); // enter declared variable into scope before evaluating // the argument expression Symtable vars = ctx.varTable(); vars.enterScope(); fDeclList.addVariablesToSymtable(vars, declList.varDecl(0).type()); expr = fExpr.gen(ctx); vars.exitScope(); } try { Integer id = (Integer) GParser.queryIdentMap.get(opname); if (id == null) throw new SemanticException( fOp, "Internal error: unknown query operation `" + opname + "'."); int idval = id.intValue(); switch (idval) { case GParser.Q_SELECT_ID: case GParser.Q_COLLECT_ID: case GParser.Q_REJECT_ID: case GParser.Q_ISUNIQUE_ID: case GParser.Q_SORTEDBY_ID: case GParser.Q_ANY_ID: case GParser.Q_ONE_ID: VarDecl decl; if (declList.isEmpty()) decl = null; else if (declList.size() == 1) decl = declList.varDecl(0); else throw new SemanticException( fOp, "Only one element variable in " + opname + " expression allowed."); switch (idval) { case GParser.Q_SELECT_ID: res = new ExpSelect(decl, range, expr); break; case GParser.Q_COLLECT_ID: res = new ExpCollect(decl, range, expr); break; case GParser.Q_REJECT_ID: res = new ExpReject(decl, range, expr); break; case GParser.Q_ISUNIQUE_ID: res = new ExpIsUnique(decl, range, expr); break; case GParser.Q_SORTEDBY_ID: res = new ExpSortedBy(decl, range, expr); break; case GParser.Q_ANY_ID: res = new ExpAny(decl, range, expr); break; case GParser.Q_ONE_ID: res = new ExpOne(decl, range, expr); break; } break; case GParser.Q_EXISTS_ID: res = new ExpExists(declList, range, expr); break; case GParser.Q_FORALL_ID: res = new ExpForAll(declList, range, expr); break; default: // internal error throw new SemanticException( fOp, "Internal error: unknown query operation `" + opname + "'."); } } catch (ExpInvalidException ex) { throw new SemanticException(fOp, ex); } return res; }
public Integer handleExpression(ASTExpression node) { Integer value = (Integer) node.jjtGetChild(0).jjtAccept(this, null); return value; }
public Integer handleVar(ASTVar node) { System.out.println(node.jjtGetParent()); Integer value = -256; int index = -10000; String name = node.getName(); if (node.isArg()) { name += "_"; } if (JustCalling) { return value; } Variable v = Global.getCurrentSymbolTable().getVariable(name); if (v instanceof ByNameVariable) { v = Global.getCurrentSymbolTable().getCacheVariable(name); System.out.println(v + " should be null the first time"); if (v != null) { int ret = 0; try { ret = v.getValue(); } catch (VizIndexOutOfBoundsException e) { System.out.println(e); } return ret; } } else { v = Global.getCurrentSymbolTable().getVariable(name); } boolean cached = false; if (v == null) { v = Global.getCurrentSymbolTable().getVariable(name); System.out.println(v); int val = 0; try { val = v.getValue(); Global.getCurrentSymbolTable().addCacheVariable(name, val); } catch (VizIndexOutOfBoundsException e) { System.out.println(e); } if (node.getIsArray()) { name += "[" + ((SimpleNode) node.jjtGetChild(0)).getCode() + "]"; } connector.addVariableToCache(name, val, "foo"); } else { cached = true; } if (v instanceof ByNameVariable) { try { value = v.getValue(); } catch (VizIndexOutOfBoundsException e) { System.out.println(e); } } else { if (node.getIsArray()) { index = (Integer) node.jjtGetChild(0).jjtAccept(this, null); node.setIndex(index); try { value = v.getValue(index); } catch (VizIndexOutOfBoundsException e) { System.out.println(e); ASTExpression exp = (ASTExpression) node.jjtGetChild(0); ASTNum num = new ASTNum(JJTNUM); Random r = new Random(); num.setValue(r.nextInt(6)); exp.jjtAddChild(num, 0); try { index = (Integer) exp.jjtAccept(this, null); value = v.getValue(index); } catch (VizIndexOutOfBoundsException f) { System.out.println("oops..."); } program.codeBuilt = false; Global.lineNumber = 1; program.buildCode(); } } else { try { value = v.getValue(); } catch (VizIndexOutOfBoundsException f) { System.out.println(f); } } System.out.println("F*****g " + value + v + cached); } if (v instanceof ByNameVariable) { if (cached) { connector.highlightVarByName(v); } else { connector.greyScope("foo"); connector.highlightScopeByName("main"); if (((ByNameVariable) v).getVariable().getIsArray()) { connector.highlightVarByName( ((ByNameVariable) v).getVariable(), ((ByNameVariable) v).getIndex()); } else { connector.highlightVarByName(((ByNameVariable) v).getVariable()); } } } else { if (node.getIsArray()) { // connector.highlightVarByName(v, index); } else { // connector.highlightVarByName(v); } } return value; }
private Expression gen1(Context ctx, Expression srcExpr) throws SemanticException { Expression res = null; String opname = fOp.getText(); Type srcType = srcExpr.type(); // generate argument expressions fArgExprs = new Expression[fArgs.size() + 1]; fArgExprs[0] = srcExpr; Iterator it = fArgs.iterator(); int i = 1; while (it.hasNext()) { ASTExpression astExpr = (ASTExpression) it.next(); fArgExprs[i++] = astExpr.gen(ctx); } // flags for various cases final int SRC_SIMPLE_TYPE = 0x100; final int SRC_OBJECT_TYPE = 0x200; final int SRC_COLLECTION_TYPE = 0x400; final int DOT = 0x010; final int ARROW = 0x020; final int NO_PARENTHESES = 0x000; final int PARENTHESES = 0x001; int opcase; if (srcType.isObjectType()) opcase = SRC_OBJECT_TYPE; else if (srcType.isCollection()) opcase = SRC_COLLECTION_TYPE; else opcase = SRC_SIMPLE_TYPE; opcase += fFollowsArrow ? ARROW : DOT; opcase += fHasParentheses ? PARENTHESES : NO_PARENTHESES; switch (opcase) { case SRC_SIMPLE_TYPE + DOT + NO_PARENTHESES: case SRC_SIMPLE_TYPE + DOT + PARENTHESES: case SRC_COLLECTION_TYPE + ARROW + PARENTHESES: case SRC_COLLECTION_TYPE + ARROW + NO_PARENTHESES: // (1) predefined OCL operation res = genStdOperation(ctx, fOp, opname, fArgExprs); break; case SRC_SIMPLE_TYPE + ARROW + NO_PARENTHESES: case SRC_SIMPLE_TYPE + ARROW + PARENTHESES: ctx.reportWarning( fOp, "application of `" + opname + "' to a single value should be done with `.' " + "instead of `->'."); // (1) predefined OCL operation res = genStdOperation(ctx, fOp, opname, fArgExprs); break; case SRC_OBJECT_TYPE + DOT + NO_PARENTHESES: MClass srcClass = ((ObjectType) srcType).cls(); MAttribute attr = srcClass.attribute(opname, true); if (attr != null) { // (2) attribute operation on object type (no arguments) res = new ExpAttrOp(attr, srcExpr); } else { // (4) navigation operation on object type // must be a role name MAssociationEnd dstEnd = srcClass.navigableEnd(opname); if (dstEnd != null) res = genNavigation(fOp, srcClass, srcExpr, dstEnd); else { // (1) predefined OCL operation res = genStdOperation(ctx, fOp, opname, fArgExprs); } } break; case SRC_OBJECT_TYPE + DOT + PARENTHESES: // (3) "isQuery" operation on object type (possibly with // arguments) or (1) MClass srcClass2 = ((ObjectType) srcType).cls(); res = genObjOperation(ctx, srcClass2, srcExpr); break; case SRC_OBJECT_TYPE + ARROW + NO_PARENTHESES: case SRC_OBJECT_TYPE + ARROW + PARENTHESES: // (6) set operation on single object resulting from // navigation over associations with multiplicity zero // or one (p. 7-13 of OMG UML 1.3) if (srcExpr instanceof ExpNavigation) { // first map object to set with internal operation Expression mappedSrcExpr = new ExpObjAsSet(srcExpr); // replace receiver in arg list fArgExprs[0] = mappedSrcExpr; try { // lookup collection operation res = ExpStdOp.create(opname, fArgExprs); } catch (ExpInvalidException ex) { throw new SemanticException(fOp, ex); } } else { throw new SemanticException( fOp, "An arrow operation treating a single object as a " + "set may only be applied, if the object results " + "from a navigation to an association end with " + "multiplicity 0..1."); } break; case SRC_COLLECTION_TYPE + DOT + NO_PARENTHESES: // c.op 200 (5) with implicit (2,4,1) if (Options.disableCollectShorthand) throw new SemanticException(fOp, MSG_DISABLE_COLLECT_SHORTHAND); res = collectShorthandWithOutArgs(opname, srcExpr); break; case SRC_COLLECTION_TYPE + DOT + PARENTHESES: // c.op() 201 (5) with implicit (3,1) if (Options.disableCollectShorthand) throw new SemanticException(fOp, MSG_DISABLE_COLLECT_SHORTHAND); res = collectShorthandWithArgs(opname, srcExpr); break; // throw new SemanticException(fOp, // "If you want to apply an operation to a collection, please use an `->' instead of a // `.'. If you are trying to apply the shorthand notation for `collect' - sorry, this is not // yet supported. Please use the explicit notation."); default: throw new RuntimeException("case " + Integer.toHexString(opcase) + " not handled"); } if (fIsPre) res.setIsPre(); return res; }