Main { {{ static SymbolTable symbolTable; static boolean stopSimulation = false; }} public static void main(String args[]) throws Exception {{ ClassGraph cg = new ClassGraph(true,false); Main m = parse(System.in); //System.out.println ("parsed input file"); //System.out.println(m.get_s()); //m.universal_trv0(new DisplayVisitor()); m.run_simulation(); }} public void run_simulation() {{ Mortgage mort = new Mortgage(); symbolTable = SymbolTable.parse(""); System.out.println ("\nInitializing symbol table"); initSymbolTable(new InitSymbolTableVisitor()); // Initialize date/state, other required variables. // If the user has declared these variables, these will be ignored. Symbol start_month = addDefaultVariable("start_month 1"); Symbol start_year = addDefaultVariable("start_year 2000"); Symbol current_month = addDefaultVariable("current_month"); Symbol current_year = addDefaultVariable("current_year"); Symbol sumOfAssets = addDefaultVariable("sum_of_assets"); Symbol sumOfLiabilities = addDefaultVariable("sum_of_liabilities"); Symbol startup = addDefaultVariable("startup 1"); Symbol savings = addDefaultVariable("savings 0"); // Initialize the default columns addDefaultColumn("column \"Expenses\" is sum_of_liabilities"); addDefaultColumn("column \"Income\" is sum_of_assets"); addDefaultColumn("column \"NetIncome\" is sum_of_assets - sum_of_liabilities"); addDefaultColumn("column \"Savings\" is savings"); addDefaultColumn("column \"Month\" is current_month"); addDefaultColumn("column \"Year\" is current_year"); // Initialize mortgage-related variables and state mort.init(); System.out.println ("\n\nThe initial symbol table is:"); symbolTable.allSymbols(new DumpSymbolTableVisitor()); // This is the catch-all termination date, so that the sim doesn't // run forever if the user forgets to declare a STOP event. int end_year = 2030; current_month.setValue(start_month.getValue()); current_year.setValue(start_year.getValue()); System.out.println ("\n\nStarting the simulation"); // print table heading printColumnTitle(); // this is used for summing the assets and liabilities GetAttributeVisitor attribVisitor = new GetAttributeVisitor(); // Main loop while (current_year.getValue() <= end_year) { double year = current_year.getValue(); while (current_month.getValue() <= 12) { double month = current_month.getValue(); mort.do_processing(); // Search for events that should be triggered now and // execute their associated statements. Remembers the // names of events that triggers. EventVisitor ev = new EventVisitor (year, month); doEvents(ev); symbolTable.allAttribs(attribVisitor); sumOfAssets.setValue(attribVisitor.getAssets()); sumOfLiabilities.setValue(attribVisitor.getLiabilities()); savings.setValue(savings.getValue() + sumOfAssets.getValue() - sumOfLiabilities.getValue()); printColumnValue(ev.getNames()); if (stopSimulation) { return; } current_month.setValue(month + 1.0); startup.setValue(0); } current_month.setValue(1.0); current_year.setValue(year + 1.0); } System.out.println ("Stopping simulation due to date limit"); }} // This is a shortcut for adding a variable to symbol table static Symbol addDefaultVariable (String symbolString) {{ // symbolString has the format Symbol symbol = Symbol.parse(symbolString); // check if symbol is in table Symbol foundSymbol = Main.symbolTable.findSymbol(symbol.get_varname().toString()); if (foundSymbol == null) { // not in table, so add it Main.symbolTable.get_symbol_list().addElement(symbol); foundSymbol = symbol; } return foundSymbol; }} // This is a shortcut for adding a column to the output void addDefaultColumn (String columnString) {{ // Column = "column" Title [Width] "is" <expr> Expr. Column col = Column.parse(columnString); get_s().push(col); }} {{ // This class encapsulates the mortgage-related computations. // The results of the computations are symbols in the symbol table. class Mortgage { boolean started; int remaining_months; Symbol mortgage_rate; Symbol mortgage_payment; Symbol minimum_percent_down; Symbol closing_costs; Symbol loan_term; Symbol house_price; Symbol reserve_savings; Symbol term_start; // corresponds to an event Symbol term_end; // corresponds to an event Symbol savings; void init() { started = false; remaining_months = 0; house_price = Main.addDefaultVariable("house_price 200000"); minimum_percent_down = Main.addDefaultVariable("minimum_percent_down 20"); closing_costs = Main.addDefaultVariable("closing_costs 4000"); reserve_savings = Main.addDefaultVariable("reserve_savings 10000"); loan_term = Main.addDefaultVariable("loan_term 15"); mortgage_rate = Main.addDefaultVariable("mortgage_rate 0.090"); term_start = Main.addDefaultVariable("term_start 0"); term_end = Main.addDefaultVariable("term_end 0"); mortgage_payment = Main.addDefaultVariable("mortgage_payment liability 0"); savings = Main.symbolTable.findSymbol("savings"); } void do_processing() { term_start.setValue(0); // The user can define events that trigger term_end.setValue(0); // off these symbols. if (!started) { // determine if we should initiate the loan double perc_down = minimum_percent_down.getValue()/100; double upfront_costs = closing_costs.getValue() + house_price.getValue() * perc_down; if (savings.getValue() >= upfront_costs + reserve_savings.getValue()) { // Get that loan! double r = mortgage_rate.getValue() / 12; double principal = house_price.getValue() * (1-perc_down); double y = loan_term.getValue(); mortgage_payment.setValue((principal*r) / (1 - 1/power((1+r),(int)y*12))); savings.setValue(savings.getValue() - upfront_costs); remaining_months = 12 * (int)y; term_start.setValue(1); started = true; } } else { // have already started loan remaining_months -= 1; if (remaining_months == 0) { mortgage_payment.setValue(0); term_end.setValue(1); } } } // compute base ** exponent double power (double base, int exponent) { if (exponent <= 0) { return 1; } else { double result = base; for (int i=1; i<exponent; i++) { result = result * base; } return result; } } } }} }