private static Operation astToFunction(ASTFunction node) throws SyntaxException { // Convert each of the arguments and check that the operation can appear // in a restricted context. int count = node.jjtGetNumChildren(); Operation[] ops = new Operation[count]; for (int i = 0; i < count; i++) { ops[i] = (astToDml((ASTOperation) node.jjtGetChild(i), true)); ops[i].checkRestrictedContext(); } // Explicitly disallow automatic variables being called as functions. if (AUTOMATIC_VARIABLES.contains(node.getName())) { throw SyntaxException.create( node.getSourceRange(), MSG_INVALID_FUNCTION_NAME, node.getName()); } // Process 'normal' built-in functions. These don't need special // processing of the arguments. The constructor takes a source range and // a list of operations. Method c = functionConstructors.get(node.getName()); if (c != null) { // Built-in function. Look up constructor in table and create new // instance. try { return (Operation) c.invoke(null, node.getSourceRange(), ops); } catch (InvocationTargetException ite) { // There may be SyntaxExceptions thrown during construction. // If so, rethrow them. All other exceptions are not expected // and should generate a compiler error. Throwable t = ite.getCause(); if (t instanceof SyntaxException) { throw (SyntaxException) t; } else { CompilerError error = CompilerError.create(MSG_UNEXPECTED_EXCEPTION_ENCOUNTERED); error.initCause(t); throw error; } } catch (IllegalAccessException iae) { CompilerError error = CompilerError.create(MSG_UNEXPECTED_EXCEPTION_ENCOUNTERED); error.initCause(iae); throw error; } catch (ClassCastException cce) { CompilerError error = CompilerError.create(MSG_UNEXPECTED_EXCEPTION_ENCOUNTERED); error.initCause(cce); throw error; } } else { // User-defined function. Create generic function wrapper. return new Function(node.getSourceRange(), node.getName(), ops); } }
public void handleFunction(ASTFunction node) { // Get the function's symbol table, set it's previous to the // calling function's, and then set it to current. connector.startSnap(node.getLineNumber()); if (node.getName().equals("main")) { connector.addQuestion(startQuestion); connector.showScope("main"); } else { } connector.endSnap(); if (!node.getUsed()) { return; } SymbolTable currentSymbolTable = node.getSymbolTable(); for (String p : node.getParameters()) { ByNameVariable v = new ByNameVariable(); v.setParam(); currentSymbolTable.put(p, v); } Global.setCurrentSymbolTable(currentSymbolTable); node.jjtGetChild(0).jjtAccept(this, null); leaveScope(); }
// returning false means we're done executing now. public Boolean handleDeclaration(ASTDeclaration node) { // System.out.println("Visiting decl"); SimpleNode child = (SimpleNode) node.jjtGetChild(0); if (child.getId() == JJTFUNCTION) { System.out.println("Found a function"); startQuestion = questionFactory.getStartQuestion(); connector.endPar(); // ENDPAR connector.endSnap(); ASTFunction main = Global.getFunction("main"); connector.addScope(main.getSymbolTable(), "main", "Global"); main.jjtAccept(this, null); return false; } else { node.jjtGetChild(0).jjtAccept(this, null); // update(); return true; } }
public Integer handleCall(ASTCall node) { boolean gotAQuestion = true; // FIXME HACK // Get the correct function head node ASTFunction fun = Global.getFunction(node.getName()); System.out.println("Calling: " + fun.getName()); // Get the parameters and put the correct values in the symbolTable SymbolTable st = fun.getSymbolTable(); String name = fun.getName(); ArrayList<String> parameters = fun.getParameters(); JustCalling = true; ArrayList<Integer> args = (ArrayList<Integer>) node.jjtGetChild(0).jjtAccept(this, null); JustCalling = false; ArrayList<ASTVar> argNames = ((ASTArgs) node.jjtGetChild(0)).getArgs(); for (int i = 0; i < args.size(); i++) { ByNameVariable v = (ByNameVariable) st.getVariable(parameters.get(i)); v.setRef(argNames.get(i)); ByNameVariable argVar = (ByNameVariable) st.getVariable(argNames.get(i).getName() + "_"); } HashMap<String, String> pa = new HashMap<String, String>(); // Maps args to params for (int i = 0; i < parameters.size(); i++) { pa.put(parameters.get(i), argNames.get(i).getName()); } Global.setCurrentParamToArg(pa); // QUESTION!!! callQuestion = questionFactory.getCallQuestion(name, pa); if (callQuestion == null) { System.out.println("No question"); gotAQuestion = false; } // Drawing Stuff connector.addScope(new SymbolTable(null), fun.getName(), "Global", true); connector.startPar(); // STARTPAR connector.showScope(node.getName()); if (gotAQuestion) { System.out.println("Adding the call question"); connector.addQuestion(callQuestion); } connector.endPar(); // ENDPAR connector.endSnap(); fun.jjtAccept(this, null); // and we gogogo if (gotAQuestion) { int answer = 0; try { answer = Global.getFunction("main").getSymbolTable().get(callQuestion.getVariable()); } catch (Exception e) { System.out.println(e); } System.out.println(callQuestion.getVariable() + " is " + answer); if (callQuestion instanceof FIBQuestion) { ((FIBQuestion) callQuestion).addAnswer(answer + ""); } else if (callQuestion instanceof TFQuestion) { int qa = answer; // Getting the value of the var at the end of the function String paramName = Global.getCurrentParamToArg().get(callQuestion.getVariable()); int prevVal = 0; try { Global.getFunction("foo").getSymbolTable().get(paramName); } catch (Exception e) { System.out.println(e); } Random r = new Random(); int choose = r.nextInt(3); switch (choose) { case 0: qa = callQuestion.getValue(); System.out.println(qa + "getValue"); ((TFQuestion) callQuestion).setAnswer(false); if (qa == answer) // Value is the same anyway { ((TFQuestion) callQuestion).setAnswer(true); } break; case 1: case 2: System.out.println(qa + "value"); ((TFQuestion) callQuestion).setAnswer(true); break; } callQuestion.setText(callQuestion.getText() + qa); } else { } } connector.startSnap(Global.getFunction("main").getLineNumber()); System.out.println("leaving call"); return 0; }