/** * Class constructor. * * @param returns the number of values to return */ public StrCpyInstruction(int returns) { if (PageExInfo.in()) throw new NslContextException( EnumSet.of(NslContext.Section, NslContext.Function, NslContext.Global), name); if (returns != 1) throw new NslReturnValueException(name, 1); ArrayList<Expression> paramsList = Expression.matchList(); int paramsCount = paramsList.size(); if (paramsCount < 1 || paramsCount > 3) throw new NslArgumentException(name, 1, 3); this.string = paramsList.get(0); if (paramsCount > 1) { this.maxLen = paramsList.get(1); if (paramsCount > 2) { this.startOffset = paramsList.get(2); } else { this.startOffset = null; } } else { this.maxLen = null; this.startOffset = null; } }
/** Class constructor. */ public SwitchStatement() { if (!SectionInfo.in() && !FunctionInfo.in()) throw new NslContextException(EnumSet.of(NslContext.Section, NslContext.Function), "switch"); int lineNo = ScriptParser.tokenizer.lineno(); ScriptParser.tokenizer.matchOrDie('('); this.switchExpression = Expression.matchComplex(); ScriptParser.tokenizer.matchOrDie(')'); ScriptParser.tokenizer.matchOrDie('{'); // Set non-null values so that the block statement can contain break statements. CodeInfo.getCurrent().setBreakLabel(RelativeJump.Zero); this.statementList = new ArrayList<Statement>(); this.casesList = new ArrayList<SwitchCaseStatement>(); this.defaultCase = null; // Get the statements including case statements. while (true) { if (ScriptParser.tokenizer.match("case")) { Statement statement = new SwitchCaseStatement(); if (this.defaultCase != null) throw new NslException( "The \"default\" case in a \"switch\" statement must be the last case", true); this.casesList.add((SwitchCaseStatement) statement); this.statementList.add(statement); } else if (ScriptParser.tokenizer.match("default")) { this.defaultCase = new SwitchDefaultCaseStatement(); this.statementList.add(this.defaultCase); } else { Statement statement = Statement.match(); if (statement == null) break; this.statementList.add(statement); } } // No cases? if (this.casesList.isEmpty()) throw new NslException( "A \"switch\" statement must have at least one \"case\" statement", true); // Validate switch cases for jump instructions. if (this.switchExpression instanceof JumpExpression) ((JumpExpression) this.switchExpression).checkSwitchCases(this.casesList, lineNo); // Check the last statement is a break statement. boolean noBreak = true; if (!this.statementList.isEmpty()) { Statement last = this.statementList.get(this.statementList.size() - 1); if (last instanceof BlockStatement) last = ((BlockStatement) last).getLast(); if (last instanceof BreakStatement) noBreak = false; } if (noBreak) throw new NslException("A \"switch\" statement must end with a \"break\" statement", true); CodeInfo.getCurrent().setBreakLabel(null); ScriptParser.tokenizer.matchOrDie('}'); }
/** * Class constructor. * * @param returns the number of values to return */ public GetErrorLevelInstruction(int returns) { if (!SectionInfo.in() && !FunctionInfo.in()) throw new NslContextException(EnumSet.of(NslContext.Section, NslContext.Function), name); if (returns != 1) throw new NslReturnValueException(name, 1); ArrayList<Expression> paramsList = Expression.matchList(); if (!paramsList.isEmpty()) throw new NslArgumentException(name, 0); }
/** * Class constructor. * * @param returns the number of values to return */ public FlushINIInstruction(int returns) { if (!SectionInfo.in() && !FunctionInfo.in()) throw new NslContextException(EnumSet.of(NslContext.Section, NslContext.Function), name); if (returns > 0) throw new NslReturnValueException(name); ArrayList<Expression> paramsList = Expression.matchList(); if (paramsList.size() != 1) throw new NslArgumentException(name, 1); this.iniFile = paramsList.get(0); }
/** * Class constructor. * * @param returns the number of values to return */ public LockWindowInstruction(int returns) { if (!SectionInfo.in() && !FunctionInfo.in()) throw new NslContextException(EnumSet.of(NslContext.Section, NslContext.Function), name); if (returns > 0) throw new NslReturnValueException(name); ArrayList<Expression> paramsList = Expression.matchList(); if (paramsList.size() != 1) throw new NslArgumentException(name, 1); this.value = paramsList.get(0); if (!ExpressionType.isString(this.value)) throw new NslArgumentException(name, 1, ExpressionType.String); }
/** * Assembles the source code. * * @param var the variable to assign the value to */ @Override public void assemble(Register var) throws IOException { Expression varOrString = AssembleExpression.getRegisterOrExpression(this.string); if (this.maxLen != null) { Expression varOrMaxLen = AssembleExpression.getRegisterOrExpression(this.maxLen); if (this.startOffset != null) { Expression varOrStartOffset = AssembleExpression.getRegisterOrExpression(this.startOffset); ScriptParser.writeLine( name + " " + var + " " + varOrString + " " + varOrMaxLen + " " + varOrStartOffset); varOrStartOffset.setInUse(false); } else { ScriptParser.writeLine(name + " " + var + " " + varOrString + " " + varOrMaxLen); } varOrMaxLen.setInUse(false); } else { ScriptParser.writeLine(name + " " + var + " " + varOrString); } varOrString.setInUse(false); }
/** Assembles the source code. */ @Override public void assemble() throws IOException { Expression varOrIniFile = AssembleExpression.getRegisterOrExpression(this.iniFile); ScriptParser.writeLine(name + " " + varOrIniFile); varOrIniFile.setInUse(false); }
/** * Class constructor. * * @param returns the number of values to return */ public CreateFontInstruction(int returns) { if (PageExInfo.in()) throw new NslContextException( EnumSet.of(NslContext.Section, NslContext.Function, NslContext.Global), name); if (returns != 1) throw new NslReturnValueException(name); ArrayList<Expression> paramsList = Expression.matchList(); int paramsCount = paramsList.size(); if (paramsCount < 1 || paramsCount > 6) throw new NslArgumentException(name, 1, 6); this.fontFace = paramsList.get(0); if (!ExpressionType.isString(this.fontFace)) throw new NslArgumentException(name, 1, ExpressionType.String); if (paramsCount > 1) { this.height = paramsList.get(1); if (!ExpressionType.isInteger(this.height)) throw new NslArgumentException(name, 2, ExpressionType.Integer); if (paramsCount > 2) { this.weight = paramsList.get(2); if (!ExpressionType.isInteger(this.weight)) throw new NslArgumentException(name, 3, ExpressionType.Integer); if (paramsCount > 3) { this.italic = paramsList.get(3); if (!ExpressionType.isBoolean(this.italic)) throw new NslArgumentException(name, 4, ExpressionType.Boolean); if (paramsCount > 4) { this.underline = paramsList.get(4); if (!ExpressionType.isBoolean(this.underline)) throw new NslArgumentException(name, 5, ExpressionType.Boolean); if (paramsCount > 5) { this.strike = paramsList.get(5); if (!ExpressionType.isBoolean(this.strike)) throw new NslArgumentException(name, 6, ExpressionType.Boolean); } else { this.strike = null; } } else { this.underline = null; this.strike = null; } } else { this.italic = null; this.underline = null; this.strike = null; } } else { this.weight = null; this.italic = null; this.underline = null; this.strike = null; } } else { this.height = null; this.weight = null; this.italic = null; this.underline = null; this.strike = null; } }
/** * Assembles the source code. * * @throws IOException */ @Override public void assemble() throws IOException { // Do not assemble anything if there are no cases! if (this.casesList.isEmpty()) return; // Give each case a label. for (SwitchCaseStatement statement : this.casesList) statement.setLabel(LabelList.getCurrent().getNext()); if (this.defaultCase != null) this.defaultCase.setLabel(LabelList.getCurrent().getNext()); Label gotoEnd = LabelList.getCurrent().getNext(); Label gotoStart = LabelList.getCurrent().getNext(); // Go to the jump table which is assembled after the switch case labels and // statements. ScriptParser.writeLine("Goto " + gotoStart); // Using "break;" inside a switch jumps to the end. Label parentBreak = CodeInfo.getCurrent().setBreakLabel(gotoEnd); // Assemble all the statements inside the switch { }. This includes the // case labels. for (Statement statement : this.statementList) statement.assemble(); // Restore the parent break label. CodeInfo.getCurrent().setBreakLabel(parentBreak); // Label at the top of the jump table. gotoStart.write(); // Jump instructions can jump directly to the case labels. if (this.switchExpression instanceof JumpExpression) { ((JumpExpression) this.switchExpression).assemble(this.casesList); } // Other expressions we just assemble them if required and compare their // result. else { Expression varOrSwitchExpression = AssembleExpression.getRegisterOrExpression(this.switchExpression); for (SwitchCaseStatement caseStatement : this.casesList) { // Type is an integer; use IntCmp. if (caseStatement.getMatch().getType().equals(ExpressionType.Integer)) { ScriptParser.writeLine( String.format( "IntCmp %s %s %s", varOrSwitchExpression, caseStatement.getMatch(), caseStatement.getLabel())); } // Type is a string; use StrCmp or StrCmpS (if special `` quotes were // used). else { ScriptParser.writeLine( String.format( "StrCmp%s %s %s %s", caseStatement.getMatch().getType().equals(ExpressionType.StringSpecial) ? "S" : "", varOrSwitchExpression, caseStatement.getMatch(), caseStatement.getLabel())); } } varOrSwitchExpression.setInUse(false); } // Default case jump. if (this.defaultCase != null) ScriptParser.writeLine("Goto " + this.defaultCase.getLabel()); gotoEnd.write(); }