2003-06-01 19:49:04 +00:00
|
|
|
/*
|
|
|
|
* AppleCommander - An Apple ][ image utility.
|
2022-01-19 03:55:20 +00:00
|
|
|
* Copyright (C) 2003-2022 by Robert Greene
|
2003-06-01 19:49:04 +00:00
|
|
|
* robgreene at users.sourceforge.net
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
|
|
* under the terms of the GNU General Public License as published by the
|
|
|
|
* Free Software Foundation; either version 2 of the License, or (at your
|
|
|
|
* option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
|
|
* for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
*/
|
|
|
|
package com.webcodepro.applecommander.compiler;
|
|
|
|
|
2003-06-03 05:47:57 +00:00
|
|
|
import java.io.IOException;
|
|
|
|
import java.io.InputStream;
|
|
|
|
import java.lang.reflect.InvocationTargetException;
|
|
|
|
import java.lang.reflect.Method;
|
2003-06-01 19:49:04 +00:00
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Map;
|
2003-06-03 05:47:57 +00:00
|
|
|
import java.util.Properties;
|
2003-06-14 02:44:43 +00:00
|
|
|
import java.util.Stack;
|
2003-06-01 19:49:04 +00:00
|
|
|
|
2004-06-09 03:58:00 +00:00
|
|
|
import com.webcodepro.applecommander.storage.FileEntry;
|
|
|
|
import com.webcodepro.applecommander.util.ApplesoftToken;
|
|
|
|
import com.webcodepro.applecommander.util.ApplesoftTokenizer;
|
|
|
|
import com.webcodepro.applecommander.util.ApplesoftTokens;
|
2004-07-11 15:05:29 +00:00
|
|
|
import com.webcodepro.applecommander.util.TextBundle;
|
2004-06-09 03:58:00 +00:00
|
|
|
|
2003-06-01 19:49:04 +00:00
|
|
|
/**
|
2003-12-04 23:54:56 +00:00
|
|
|
* Compile the given Applesoft file. The result will be an assembly
|
|
|
|
* program (ultimately assembled). This is not intended to be anything
|
|
|
|
* sophisticated.
|
2003-06-01 19:49:04 +00:00
|
|
|
* <p>
|
|
|
|
* Date created: Nov 2, 2002 10:04:10 PM
|
2004-06-18 05:15:33 +00:00
|
|
|
* @author Rob Greene
|
2003-06-01 19:49:04 +00:00
|
|
|
*/
|
|
|
|
public class ApplesoftCompiler implements ApplesoftTokens {
|
2004-07-11 15:05:29 +00:00
|
|
|
private TextBundle textBundle = CompilerBundle.getInstance();
|
2003-12-14 18:59:21 +00:00
|
|
|
/**
|
|
|
|
* Tokenized the Applesoft program.
|
|
|
|
*/
|
2003-06-01 19:49:04 +00:00
|
|
|
private ApplesoftTokenizer tokenizer;
|
2003-12-14 18:59:21 +00:00
|
|
|
/**
|
|
|
|
* Holds a token that was "peeked" at, if any. A null indicates
|
|
|
|
* that there is no value peeked at.
|
|
|
|
*/
|
2003-06-03 05:47:57 +00:00
|
|
|
private ApplesoftToken tokenAlreadySeen;
|
2003-12-14 18:59:21 +00:00
|
|
|
/**
|
|
|
|
* Used internally to construct the assembly representation of
|
|
|
|
* the Applesoft code. This variable should really be passed
|
|
|
|
* between methods.
|
|
|
|
*/
|
2003-06-03 05:47:57 +00:00
|
|
|
private StringBuffer sourceAssembly = new StringBuffer();
|
2003-12-14 18:59:21 +00:00
|
|
|
/**
|
|
|
|
* Used internally to construct the original Applesoft source
|
|
|
|
* line. This variable should really be passed between methods.
|
|
|
|
*/
|
2003-06-03 05:47:57 +00:00
|
|
|
private StringBuffer sourceLine = new StringBuffer();
|
|
|
|
/**
|
|
|
|
* Contains a list of all known Apple ROM addresses that may be used
|
|
|
|
* by the compiled program. This map is keyed by the name of the
|
|
|
|
* address and the value is the address.
|
|
|
|
*/
|
2017-11-09 21:03:03 +00:00
|
|
|
private Map<String,String> knownAddresses = new HashMap<>();
|
2003-06-03 05:47:57 +00:00
|
|
|
/**
|
|
|
|
* Lists the names of all addresses used by the compiled program.
|
|
|
|
* To identify the value, use the knownAddresses map.
|
|
|
|
*/
|
2017-11-09 21:03:03 +00:00
|
|
|
private List<String> usedAddresses = new ArrayList<>();
|
2003-06-03 05:47:57 +00:00
|
|
|
/**
|
|
|
|
* Contains a list of all variables declared or used by the
|
|
|
|
* program.
|
|
|
|
*/
|
2017-11-09 21:03:03 +00:00
|
|
|
private List<Variable> variables = new ArrayList<>();
|
2003-06-03 05:47:57 +00:00
|
|
|
/**
|
|
|
|
* Dynamically created map of commands to Methods.
|
|
|
|
*/
|
2017-11-09 21:03:03 +00:00
|
|
|
private Map<String,Method> commandMethods = new HashMap<>();
|
2003-06-14 02:44:43 +00:00
|
|
|
/**
|
|
|
|
* Track FOR loop variables.
|
|
|
|
*/
|
2017-11-09 21:03:03 +00:00
|
|
|
private Stack<String> loopVariables = new Stack<>();
|
2003-12-14 18:59:21 +00:00
|
|
|
/**
|
|
|
|
* Indicates integer math operations only.
|
|
|
|
*/
|
|
|
|
private boolean integerOnlyMath;
|
2003-06-01 19:49:04 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructor for ApplesoftCompiler.
|
|
|
|
*/
|
|
|
|
public ApplesoftCompiler(FileEntry fileEntry) {
|
|
|
|
super();
|
|
|
|
tokenizer = new ApplesoftTokenizer(fileEntry);
|
2003-06-03 05:47:57 +00:00
|
|
|
initializeKnownAddresses();
|
2003-06-01 19:49:04 +00:00
|
|
|
}
|
2003-06-03 05:47:57 +00:00
|
|
|
|
2003-06-01 19:49:04 +00:00
|
|
|
/**
|
2003-06-03 05:47:57 +00:00
|
|
|
* Load known memory addresses from AppleMemoryAddresses.properties.
|
2003-06-01 19:49:04 +00:00
|
|
|
*/
|
2003-06-03 05:47:57 +00:00
|
|
|
protected void initializeKnownAddresses() {
|
|
|
|
InputStream inputStream =
|
2004-07-11 15:05:29 +00:00
|
|
|
getClass().getResourceAsStream("AppleMemoryAddresses.properties"); //$NON-NLS-1$
|
2003-06-03 05:47:57 +00:00
|
|
|
Properties properties = new Properties();
|
|
|
|
try {
|
|
|
|
properties.load(inputStream);
|
2019-10-06 18:05:10 +00:00
|
|
|
for (String key : properties.stringPropertyNames()) {
|
2003-06-03 05:47:57 +00:00
|
|
|
knownAddresses.put(key, properties.getProperty(key));
|
2003-06-01 19:49:04 +00:00
|
|
|
}
|
2003-06-03 05:47:57 +00:00
|
|
|
} catch (IOException ex) {
|
|
|
|
ex.printStackTrace();
|
2003-06-01 19:49:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2003-06-03 05:47:57 +00:00
|
|
|
* Answers true if there are more tokens to process.
|
2003-06-01 19:49:04 +00:00
|
|
|
*/
|
2003-06-03 05:47:57 +00:00
|
|
|
protected boolean hasMoreTokens() {
|
|
|
|
return peekToken() != null;
|
2003-06-01 19:49:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2003-06-03 05:47:57 +00:00
|
|
|
* Get the next token.
|
2003-06-01 19:49:04 +00:00
|
|
|
*/
|
2003-06-03 05:47:57 +00:00
|
|
|
protected ApplesoftToken nextToken() {
|
|
|
|
ApplesoftToken token = tokenAlreadySeen;
|
|
|
|
if (tokenAlreadySeen != null) {
|
|
|
|
tokenAlreadySeen = null;
|
2003-06-01 19:49:04 +00:00
|
|
|
} else {
|
2003-06-03 05:47:57 +00:00
|
|
|
token = tokenizer.getNextToken();
|
2003-06-01 19:49:04 +00:00
|
|
|
}
|
2003-06-03 05:47:57 +00:00
|
|
|
if (token == null) {
|
|
|
|
// No more tokens
|
|
|
|
} else if (token.isLineNumber()) {
|
2004-07-11 15:05:29 +00:00
|
|
|
sourceLine.append("* "); //$NON-NLS-1$
|
2003-06-03 05:47:57 +00:00
|
|
|
sourceLine.append(token.getLineNumber());
|
2004-07-11 15:05:29 +00:00
|
|
|
sourceLine.append(" "); //$NON-NLS-1$
|
2003-06-03 05:47:57 +00:00
|
|
|
} else if (token.isToken()) {
|
|
|
|
sourceLine.append(token.getTokenString());
|
|
|
|
} else if (token.isString()) {
|
|
|
|
sourceLine.append(token.getStringValue());
|
|
|
|
}
|
|
|
|
return token;
|
2003-06-01 19:49:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2003-06-03 05:47:57 +00:00
|
|
|
* Take a peek at the next token.
|
|
|
|
*/
|
|
|
|
protected ApplesoftToken peekToken() {
|
|
|
|
if (tokenAlreadySeen == null) {
|
|
|
|
tokenAlreadySeen = tokenizer.getNextToken();
|
|
|
|
}
|
|
|
|
return tokenAlreadySeen;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Compile the given FileEntry and return the assembly code.
|
2003-06-01 19:49:04 +00:00
|
|
|
*/
|
2003-06-03 05:47:57 +00:00
|
|
|
public byte[] compile() throws CompileException {
|
|
|
|
StringBuffer programCode = new StringBuffer();
|
|
|
|
while (hasMoreTokens()) {
|
|
|
|
ApplesoftToken token = nextToken();
|
|
|
|
if (!token.isLineNumber()) {
|
2004-07-11 15:05:29 +00:00
|
|
|
throw new CompileException(textBundle.
|
|
|
|
get("ApplesoftCompiler.ExpectLineNumberError")); //$NON-NLS-1$
|
2003-06-01 19:49:04 +00:00
|
|
|
}
|
2004-07-11 15:05:29 +00:00
|
|
|
sourceAssembly.append("LINE"); //$NON-NLS-1$
|
2003-06-03 05:47:57 +00:00
|
|
|
sourceAssembly.append(token.getLineNumber());
|
2004-07-11 15:05:29 +00:00
|
|
|
sourceAssembly.append("\n"); //$NON-NLS-1$
|
2003-06-03 05:47:57 +00:00
|
|
|
do {
|
|
|
|
evaluateCommand();
|
|
|
|
token = peekToken();
|
|
|
|
if (token != null && token.isCommandSeparator()) {
|
|
|
|
token = nextToken();
|
|
|
|
}
|
|
|
|
} while (token != null && token.isCommandSeparator());
|
|
|
|
programCode.append(sourceLine);
|
2004-07-11 15:05:29 +00:00
|
|
|
programCode.append("\n"); //$NON-NLS-1$
|
2003-06-03 05:47:57 +00:00
|
|
|
programCode.append(sourceAssembly);
|
2004-07-11 15:05:29 +00:00
|
|
|
programCode.append("\n"); //$NON-NLS-1$
|
Added support for FLASH, HCOLOR=, HTAB, INVERSE, NORMAL,
PRINT, VTAB.
Added methods addLoadAddress, addLoadByteValue, addLoadFac,
addLoadWordValue, evaluateExpression.
Memory listing is read from properties file.
2003-06-06 03:28:44 +00:00
|
|
|
sourceLine.setLength(0);
|
|
|
|
sourceAssembly.setLength(0);
|
2003-06-01 19:49:04 +00:00
|
|
|
}
|
2003-06-03 05:47:57 +00:00
|
|
|
programCode.insert(0, buildUsedAddresses());
|
2003-06-14 02:44:43 +00:00
|
|
|
programCode.append(buildVariableSection());
|
|
|
|
sourceLine.setLength(0);
|
|
|
|
sourceAssembly.setLength(0);
|
|
|
|
return programCode.toString().getBytes();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Build a list of ROM and Zero-page addresses that are used
|
|
|
|
* within this specific program.
|
|
|
|
*/
|
|
|
|
protected StringBuffer buildUsedAddresses() {
|
|
|
|
StringBuffer buf = new StringBuffer();
|
|
|
|
if (usedAddresses.size() > 0) {
|
2004-07-11 15:05:29 +00:00
|
|
|
buf.append("* Addresses:\n"); //$NON-NLS-1$
|
2003-06-14 02:44:43 +00:00
|
|
|
for (int i=0; i<usedAddresses.size(); i++) {
|
|
|
|
String label = (String) usedAddresses.get(i);
|
|
|
|
buf.append(label);
|
2004-07-11 15:05:29 +00:00
|
|
|
buf.append(" = "); //$NON-NLS-1$
|
2003-06-14 02:44:43 +00:00
|
|
|
buf.append((String) knownAddresses.get(label));
|
2004-07-11 15:05:29 +00:00
|
|
|
buf.append("\n"); //$NON-NLS-1$
|
2003-06-14 02:44:43 +00:00
|
|
|
}
|
2004-07-11 15:05:29 +00:00
|
|
|
buf.append("\n"); //$NON-NLS-1$
|
2003-06-14 02:44:43 +00:00
|
|
|
}
|
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Build the variable section that is placed at the end of the
|
|
|
|
* assembly listing.
|
|
|
|
* <p>
|
|
|
|
* <b>Warning:</b> This method re-uses the global sourceAssembly
|
|
|
|
* variables since the addAssembly method is used to format the
|
|
|
|
* code.
|
|
|
|
*/
|
|
|
|
protected StringBuffer buildVariableSection() {
|
|
|
|
sourceAssembly.setLength(0);
|
Added support for FLASH, HCOLOR=, HTAB, INVERSE, NORMAL,
PRINT, VTAB.
Added methods addLoadAddress, addLoadByteValue, addLoadFac,
addLoadWordValue, evaluateExpression.
Memory listing is read from properties file.
2003-06-06 03:28:44 +00:00
|
|
|
for (int i=0; i<variables.size(); i++) {
|
|
|
|
if (i == 0) {
|
2004-07-11 15:05:29 +00:00
|
|
|
sourceAssembly.append("\n"); //$NON-NLS-1$
|
|
|
|
sourceAssembly.append("* Variables:\n"); //$NON-NLS-1$
|
Added support for FLASH, HCOLOR=, HTAB, INVERSE, NORMAL,
PRINT, VTAB.
Added methods addLoadAddress, addLoadByteValue, addLoadFac,
addLoadWordValue, evaluateExpression.
Memory listing is read from properties file.
2003-06-06 03:28:44 +00:00
|
|
|
}
|
|
|
|
Variable variable = (Variable) variables.get(i);
|
|
|
|
if (variable.isConstantInteger()) {
|
2004-07-11 15:05:29 +00:00
|
|
|
addAssembly(variable.getName(), "DW", variable.getValue()); //$NON-NLS-1$
|
Added support for FLASH, HCOLOR=, HTAB, INVERSE, NORMAL,
PRINT, VTAB.
Added methods addLoadAddress, addLoadByteValue, addLoadFac,
addLoadWordValue, evaluateExpression.
Memory listing is read from properties file.
2003-06-06 03:28:44 +00:00
|
|
|
} else if (variable.isConstantFloat()) {
|
|
|
|
// FIXME
|
|
|
|
} else if (variable.isConstantString()) {
|
2004-07-11 15:05:29 +00:00
|
|
|
addAssembly(variable.getName(), "ASC", variable.getValue()); //$NON-NLS-1$
|
|
|
|
addAssembly(null, "HEX", "00"); //$NON-NLS-1$ //$NON-NLS-2$
|
Added support for FLASH, HCOLOR=, HTAB, INVERSE, NORMAL,
PRINT, VTAB.
Added methods addLoadAddress, addLoadByteValue, addLoadFac,
addLoadWordValue, evaluateExpression.
Memory listing is read from properties file.
2003-06-06 03:28:44 +00:00
|
|
|
} else if (variable.isTypeFloat()) {
|
2004-07-11 15:05:29 +00:00
|
|
|
addAssembly(variable.getName(), "HEX", "8400000000"); // = 0.0 //$NON-NLS-1$ //$NON-NLS-2$
|
Added support for FLASH, HCOLOR=, HTAB, INVERSE, NORMAL,
PRINT, VTAB.
Added methods addLoadAddress, addLoadByteValue, addLoadFac,
addLoadWordValue, evaluateExpression.
Memory listing is read from properties file.
2003-06-06 03:28:44 +00:00
|
|
|
} else if (variable.isTypeInteger()) {
|
2004-07-11 15:05:29 +00:00
|
|
|
addAssembly(variable.getName(), "DS", "2"); //$NON-NLS-1$ //$NON-NLS-2$
|
Added support for FLASH, HCOLOR=, HTAB, INVERSE, NORMAL,
PRINT, VTAB.
Added methods addLoadAddress, addLoadByteValue, addLoadFac,
addLoadWordValue, evaluateExpression.
Memory listing is read from properties file.
2003-06-06 03:28:44 +00:00
|
|
|
} else if (variable.isTypeString()) {
|
|
|
|
// FIXME
|
|
|
|
}
|
|
|
|
}
|
2003-06-14 02:44:43 +00:00
|
|
|
return sourceAssembly;
|
2003-06-01 19:49:04 +00:00
|
|
|
}
|
2003-06-03 05:47:57 +00:00
|
|
|
|
|
|
|
protected void evaluateCommand() {
|
|
|
|
ApplesoftToken token = nextToken();
|
|
|
|
while (token != null && token.isCommandSeparator()) {
|
|
|
|
token = nextToken();
|
|
|
|
}
|
|
|
|
if (token == null || !token.isToken()) {
|
|
|
|
return; // end of line (no command on line...)
|
|
|
|
}
|
|
|
|
Method method = getMethod(token);
|
|
|
|
if (method != null) {
|
|
|
|
try {
|
|
|
|
method.invoke(this, new Object[0]);
|
|
|
|
} catch (IllegalArgumentException e) {
|
2004-07-11 15:05:29 +00:00
|
|
|
System.err.println(textBundle.
|
|
|
|
format("ApplesoftCompiler.UnableToLocateError", //$NON-NLS-1$
|
|
|
|
method.getName()));
|
2003-06-03 05:47:57 +00:00
|
|
|
e.printStackTrace();
|
|
|
|
} catch (IllegalAccessException e) {
|
2004-07-11 15:05:29 +00:00
|
|
|
System.err.println(textBundle.
|
|
|
|
format("ApplesoftCompiler.UnableToLocateError", //$NON-NLS-1$
|
|
|
|
method.getName()));
|
2003-06-03 05:47:57 +00:00
|
|
|
e.printStackTrace();
|
|
|
|
} catch (InvocationTargetException e) {
|
2004-07-11 15:05:29 +00:00
|
|
|
System.err.println(textBundle.
|
|
|
|
format("ApplesoftCompiler.UnableToLocateError", //$NON-NLS-1$
|
|
|
|
method.getName()));
|
2003-06-03 05:47:57 +00:00
|
|
|
e.printStackTrace();
|
2003-06-01 19:49:04 +00:00
|
|
|
}
|
|
|
|
} else {
|
2003-06-03 05:47:57 +00:00
|
|
|
// FIXME: Just during development - this should throw an exception!
|
|
|
|
while (peekToken() != null && !peekToken().isCommandSeparator() && !peekToken().isLineNumber()) {
|
|
|
|
nextToken();
|
|
|
|
}
|
2003-06-01 19:49:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-06-03 05:47:57 +00:00
|
|
|
protected Method getMethod(ApplesoftToken token) {
|
Added support for FLASH, HCOLOR=, HTAB, INVERSE, NORMAL,
PRINT, VTAB.
Added methods addLoadAddress, addLoadByteValue, addLoadFac,
addLoadWordValue, evaluateExpression.
Memory listing is read from properties file.
2003-06-06 03:28:44 +00:00
|
|
|
StringBuffer buf = new StringBuffer();
|
2004-07-11 15:05:29 +00:00
|
|
|
buf.append("evaluate"); //$NON-NLS-1$
|
Added support for FLASH, HCOLOR=, HTAB, INVERSE, NORMAL,
PRINT, VTAB.
Added methods addLoadAddress, addLoadByteValue, addLoadFac,
addLoadWordValue, evaluateExpression.
Memory listing is read from properties file.
2003-06-06 03:28:44 +00:00
|
|
|
buf.append(token.getTokenString().trim());
|
|
|
|
for (int i=buf.length()-1; i>=0; i--) {
|
|
|
|
if (buf.charAt(i) == '=') {
|
|
|
|
buf.deleteCharAt(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
String tokenName = buf.toString();
|
2003-06-03 05:47:57 +00:00
|
|
|
Method method = (Method) commandMethods.get(tokenName);
|
|
|
|
if (method == null) {
|
|
|
|
try {
|
|
|
|
method = getClass().getMethod(tokenName, new Class[0]);
|
|
|
|
commandMethods.put(tokenName, method);
|
|
|
|
} catch (SecurityException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
return null;
|
|
|
|
} catch (NoSuchMethodException e) {
|
2003-12-04 23:54:56 +00:00
|
|
|
// FIXME: This is actually valid (during development anyway)
|
2003-06-03 05:47:57 +00:00
|
|
|
//e.printStackTrace();
|
|
|
|
return null;
|
2003-06-01 19:49:04 +00:00
|
|
|
}
|
|
|
|
}
|
2003-06-03 05:47:57 +00:00
|
|
|
return method;
|
2003-06-01 19:49:04 +00:00
|
|
|
}
|
|
|
|
|
2003-06-03 05:47:57 +00:00
|
|
|
protected void addAssembly(String label, String mnemonic, String parameter) {
|
|
|
|
if (label != null) {
|
|
|
|
sourceAssembly.append(label);
|
2003-06-14 02:44:43 +00:00
|
|
|
// sourceAssembly.append(":\n");
|
2003-06-03 05:47:57 +00:00
|
|
|
}
|
|
|
|
if (mnemonic != null) {
|
2004-07-11 15:05:29 +00:00
|
|
|
sourceAssembly.append(" "); //$NON-NLS-1$
|
2003-06-03 05:47:57 +00:00
|
|
|
sourceAssembly.append(mnemonic);
|
|
|
|
if (parameter != null) {
|
2004-07-11 15:05:29 +00:00
|
|
|
sourceAssembly.append(" "); //$NON-NLS-1$
|
2003-06-03 05:47:57 +00:00
|
|
|
sourceAssembly.append(parameter);
|
Added support for FLASH, HCOLOR=, HTAB, INVERSE, NORMAL,
PRINT, VTAB.
Added methods addLoadAddress, addLoadByteValue, addLoadFac,
addLoadWordValue, evaluateExpression.
Memory listing is read from properties file.
2003-06-06 03:28:44 +00:00
|
|
|
if (!usedAddresses.contains(parameter)
|
|
|
|
&& knownAddresses.containsKey(parameter)) {
|
2003-06-03 05:47:57 +00:00
|
|
|
usedAddresses.add(parameter);
|
|
|
|
}
|
|
|
|
}
|
2004-07-11 15:05:29 +00:00
|
|
|
sourceAssembly.append("\n"); //$NON-NLS-1$
|
2003-06-03 05:47:57 +00:00
|
|
|
}
|
2003-06-01 19:49:04 +00:00
|
|
|
}
|
|
|
|
|
2003-06-03 05:47:57 +00:00
|
|
|
public void evaluateHOME() {
|
2004-07-11 15:05:29 +00:00
|
|
|
addAssembly(null, "JSR", "HOME"); //$NON-NLS-1$ //$NON-NLS-2$
|
2003-06-01 19:49:04 +00:00
|
|
|
}
|
|
|
|
|
2003-06-03 05:47:57 +00:00
|
|
|
public void evaluateTEXT() {
|
2004-07-11 15:05:29 +00:00
|
|
|
addAssembly(null, "JSR", "TEXT"); //$NON-NLS-1$ //$NON-NLS-2$
|
2003-06-03 05:47:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void evaluateRETURN() {
|
2004-07-11 15:05:29 +00:00
|
|
|
addAssembly(null, "RTS", null); //$NON-NLS-1$
|
2003-06-03 05:47:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void evaluateEND() {
|
|
|
|
evaluateRETURN();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void evaluateHGR() {
|
2004-07-11 15:05:29 +00:00
|
|
|
addAssembly(null, "JSR", "HGR"); //$NON-NLS-1$ //$NON-NLS-2$
|
2003-06-03 05:47:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void evaluateHGR2() {
|
2004-07-11 15:05:29 +00:00
|
|
|
addAssembly(null, "JSR", "HGR2"); //$NON-NLS-1$ //$NON-NLS-2$
|
2003-06-03 05:47:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void evaluateGR() {
|
2004-07-11 15:05:29 +00:00
|
|
|
addAssembly(null, "JSR", "GR"); //$NON-NLS-1$ //$NON-NLS-2$
|
2003-06-01 19:49:04 +00:00
|
|
|
}
|
2003-06-03 05:47:57 +00:00
|
|
|
|
|
|
|
public void evaluateINVERSE() {
|
2004-07-11 15:05:29 +00:00
|
|
|
addAssembly(null, "LDA", "#$3F"); //$NON-NLS-1$ //$NON-NLS-2$
|
|
|
|
addAssembly(null, "STA", "INVFLAG"); //$NON-NLS-1$ //$NON-NLS-2$
|
2003-06-03 05:47:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void evaluateNORMAL() {
|
2004-07-11 15:05:29 +00:00
|
|
|
addAssembly(null, "LDA", "#$FF"); //$NON-NLS-1$ //$NON-NLS-2$
|
|
|
|
addAssembly(null, "STA", "INVFLAG"); //$NON-NLS-1$ //$NON-NLS-2$
|
2003-06-03 05:47:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void evaluateFLASH() {
|
2004-07-11 15:05:29 +00:00
|
|
|
addAssembly(null, "LDA", "#$7F"); //$NON-NLS-1$ //$NON-NLS-2$
|
|
|
|
addAssembly(null, "STA", "INVFLAG"); //$NON-NLS-1$ //$NON-NLS-2$
|
Added support for FLASH, HCOLOR=, HTAB, INVERSE, NORMAL,
PRINT, VTAB.
Added methods addLoadAddress, addLoadByteValue, addLoadFac,
addLoadWordValue, evaluateExpression.
Memory listing is read from properties file.
2003-06-06 03:28:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
protected Variable evaluateExpression() throws CompileException {
|
|
|
|
// FIXME: no type checking available
|
|
|
|
// FIXME: needs to evaluate all valid expressions
|
2003-12-21 01:11:58 +00:00
|
|
|
ApplesoftToken token = peekToken();
|
|
|
|
if (token.isEndOfCommand()) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
token = nextToken();
|
Added support for FLASH, HCOLOR=, HTAB, INVERSE, NORMAL,
PRINT, VTAB.
Added methods addLoadAddress, addLoadByteValue, addLoadFac,
addLoadWordValue, evaluateExpression.
Memory listing is read from properties file.
2003-06-06 03:28:44 +00:00
|
|
|
if (token.isString()) {
|
|
|
|
String value = token.getStringValue();
|
|
|
|
Variable variable = null;
|
|
|
|
for (int i=0; i<variables.size(); i++) {
|
|
|
|
variable = (Variable) variables.get(i);
|
|
|
|
if (value.equals(variable.getValue())) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
variable = null;
|
|
|
|
}
|
|
|
|
if (variable == null) {
|
|
|
|
if (isIntegerNumber(value)) {
|
2004-07-11 15:05:29 +00:00
|
|
|
variable = new Variable("INT" + value, Variable.CONST_INTEGER, value); //$NON-NLS-1$
|
|
|
|
} else if (value.startsWith("\"")) { //$NON-NLS-1$
|
|
|
|
variable = new Variable("STR" + variables.size(), Variable.CONST_STRING, value); //$NON-NLS-1$
|
Added support for FLASH, HCOLOR=, HTAB, INVERSE, NORMAL,
PRINT, VTAB.
Added methods addLoadAddress, addLoadByteValue, addLoadFac,
addLoadWordValue, evaluateExpression.
Memory listing is read from properties file.
2003-06-06 03:28:44 +00:00
|
|
|
} else { // assume variable name
|
2004-07-11 15:05:29 +00:00
|
|
|
if (value.endsWith("$")) { //$NON-NLS-1$
|
|
|
|
variable = new Variable("VAR" + value, Variable.TYPE_STRING, value); //$NON-NLS-1$
|
|
|
|
} else if (value.endsWith("%") || isIntegerOnlyMath()) { //$NON-NLS-1$
|
|
|
|
variable = new Variable("VAR" + value, Variable.TYPE_INTEGER, value); //$NON-NLS-1$
|
Added support for FLASH, HCOLOR=, HTAB, INVERSE, NORMAL,
PRINT, VTAB.
Added methods addLoadAddress, addLoadByteValue, addLoadFac,
addLoadWordValue, evaluateExpression.
Memory listing is read from properties file.
2003-06-06 03:28:44 +00:00
|
|
|
} else {
|
2004-07-11 15:05:29 +00:00
|
|
|
variable = new Variable("VAR" + value, Variable.TYPE_FLOAT, value); //$NON-NLS-1$
|
Added support for FLASH, HCOLOR=, HTAB, INVERSE, NORMAL,
PRINT, VTAB.
Added methods addLoadAddress, addLoadByteValue, addLoadFac,
addLoadWordValue, evaluateExpression.
Memory listing is read from properties file.
2003-06-06 03:28:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
variables.add(variable);
|
|
|
|
}
|
|
|
|
return variable;
|
|
|
|
}
|
2004-07-11 15:05:29 +00:00
|
|
|
throw new CompileException(textBundle.get("ApplesoftCompiler.UnableToEvaluateError")); //$NON-NLS-1$
|
Added support for FLASH, HCOLOR=, HTAB, INVERSE, NORMAL,
PRINT, VTAB.
Added methods addLoadAddress, addLoadByteValue, addLoadFac,
addLoadWordValue, evaluateExpression.
Memory listing is read from properties file.
2003-06-06 03:28:44 +00:00
|
|
|
}
|
|
|
|
|
2003-06-14 02:44:43 +00:00
|
|
|
protected Variable evaluateNumber() throws CompileException {
|
|
|
|
Variable variable = evaluateExpression();
|
|
|
|
if (variable.isNumber()) {
|
|
|
|
return variable;
|
|
|
|
}
|
2004-07-11 15:05:29 +00:00
|
|
|
throw new CompileException(textBundle.get("ApplesoftCompiler.NumberRequiredError")); //$NON-NLS-1$
|
2003-06-14 02:44:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Answer with the line number label. Used by GOTO and ON expr GOTO
|
|
|
|
* statements.
|
|
|
|
*/
|
|
|
|
protected String getLineNumberLabel() throws CompileException {
|
|
|
|
ApplesoftToken token = nextToken();
|
|
|
|
if (token.isString() && isIntegerNumber(token.getStringValue())) {
|
2004-07-11 15:05:29 +00:00
|
|
|
return "LINE" + token.getStringValue(); //$NON-NLS-1$
|
2003-06-14 02:44:43 +00:00
|
|
|
}
|
2004-07-11 15:05:29 +00:00
|
|
|
throw new CompileException(textBundle.
|
|
|
|
format("ApplesoftCompiler.ExpectingLineNumberError", //$NON-NLS-1$
|
|
|
|
token.toString()));
|
2003-06-14 02:44:43 +00:00
|
|
|
}
|
|
|
|
|
Added support for FLASH, HCOLOR=, HTAB, INVERSE, NORMAL,
PRINT, VTAB.
Added methods addLoadAddress, addLoadByteValue, addLoadFac,
addLoadWordValue, evaluateExpression.
Memory listing is read from properties file.
2003-06-06 03:28:44 +00:00
|
|
|
protected void addLoadByteValue(Variable variable, char register) throws CompileException {
|
|
|
|
if (variable.isConstantInteger()) {
|
2004-07-11 15:05:29 +00:00
|
|
|
addAssembly(null, "LD" + register, "#" + variable.getValue()); //$NON-NLS-1$ //$NON-NLS-2$
|
Added support for FLASH, HCOLOR=, HTAB, INVERSE, NORMAL,
PRINT, VTAB.
Added methods addLoadAddress, addLoadByteValue, addLoadFac,
addLoadWordValue, evaluateExpression.
Memory listing is read from properties file.
2003-06-06 03:28:44 +00:00
|
|
|
} else if(variable.isTypeInteger()) {
|
2004-07-11 15:05:29 +00:00
|
|
|
addAssembly(null, "LD" + register, variable.getName()); //$NON-NLS-1$
|
Added support for FLASH, HCOLOR=, HTAB, INVERSE, NORMAL,
PRINT, VTAB.
Added methods addLoadAddress, addLoadByteValue, addLoadFac,
addLoadWordValue, evaluateExpression.
Memory listing is read from properties file.
2003-06-06 03:28:44 +00:00
|
|
|
} else if (variable.isConstantFloat() || variable.isTypeFloat()) {
|
2004-07-11 15:05:29 +00:00
|
|
|
addAssembly(null, "LDY", "#>" + variable.getName()); //$NON-NLS-1$ //$NON-NLS-2$
|
|
|
|
addAssembly(null, "LDA", "#<" + variable.getName()); //$NON-NLS-1$ //$NON-NLS-2$
|
|
|
|
addAssembly(null, "JSR","MOVFM"); //$NON-NLS-1$ //$NON-NLS-2$
|
|
|
|
addAssembly(null, "JSR", "QINT"); //$NON-NLS-1$ //$NON-NLS-2$
|
|
|
|
addAssembly(null, "LD" + register, "FACLO"); //$NON-NLS-1$ //$NON-NLS-2$
|
Added support for FLASH, HCOLOR=, HTAB, INVERSE, NORMAL,
PRINT, VTAB.
Added methods addLoadAddress, addLoadByteValue, addLoadFac,
addLoadWordValue, evaluateExpression.
Memory listing is read from properties file.
2003-06-06 03:28:44 +00:00
|
|
|
} else {
|
2004-07-11 15:05:29 +00:00
|
|
|
throw new CompileException(textBundle.
|
|
|
|
format("ApplesoftCompiler.InvalidByteFormatError", //$NON-NLS-1$
|
|
|
|
variable.getName()));
|
Added support for FLASH, HCOLOR=, HTAB, INVERSE, NORMAL,
PRINT, VTAB.
Added methods addLoadAddress, addLoadByteValue, addLoadFac,
addLoadWordValue, evaluateExpression.
Memory listing is read from properties file.
2003-06-06 03:28:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void addLoadWordValue(Variable variable, char registerHi, char registerLo) throws CompileException {
|
|
|
|
if (variable.isConstantInteger()) {
|
2004-07-11 15:05:29 +00:00
|
|
|
addAssembly(null, "LD" + registerHi, "#>" + variable.getValue()); //$NON-NLS-1$ //$NON-NLS-2$
|
|
|
|
addAssembly(null, "LD" + registerLo, "#<" + variable.getValue()); //$NON-NLS-1$ //$NON-NLS-2$
|
Added support for FLASH, HCOLOR=, HTAB, INVERSE, NORMAL,
PRINT, VTAB.
Added methods addLoadAddress, addLoadByteValue, addLoadFac,
addLoadWordValue, evaluateExpression.
Memory listing is read from properties file.
2003-06-06 03:28:44 +00:00
|
|
|
} else if (variable.isTypeInteger()) {
|
2004-07-11 15:05:29 +00:00
|
|
|
addAssembly(null, "LD" + registerHi, variable.getName() + "+1"); //$NON-NLS-1$ //$NON-NLS-2$
|
|
|
|
addAssembly(null, "LD" + registerLo, variable.getName()); //$NON-NLS-1$
|
Added support for FLASH, HCOLOR=, HTAB, INVERSE, NORMAL,
PRINT, VTAB.
Added methods addLoadAddress, addLoadByteValue, addLoadFac,
addLoadWordValue, evaluateExpression.
Memory listing is read from properties file.
2003-06-06 03:28:44 +00:00
|
|
|
} else if (variable.isConstantFloat() || variable.isTypeFloat()) {
|
|
|
|
addLoadFac(variable);
|
2004-07-11 15:05:29 +00:00
|
|
|
addAssembly(null, "JSR", "QINT"); //$NON-NLS-1$ //$NON-NLS-2$
|
|
|
|
addAssembly(null, "LD" + registerHi, "FACMO"); //$NON-NLS-1$ //$NON-NLS-2$
|
|
|
|
addAssembly(null, "LD" + registerLo, "FACLO"); //$NON-NLS-1$ //$NON-NLS-2$
|
Added support for FLASH, HCOLOR=, HTAB, INVERSE, NORMAL,
PRINT, VTAB.
Added methods addLoadAddress, addLoadByteValue, addLoadFac,
addLoadWordValue, evaluateExpression.
Memory listing is read from properties file.
2003-06-06 03:28:44 +00:00
|
|
|
} else {
|
2004-07-11 15:05:29 +00:00
|
|
|
throw new CompileException(textBundle.
|
|
|
|
format("ApplesoftCompiler.InvalidWordFormatError", //$NON-NLS-1$
|
|
|
|
variable.getName()));
|
Added support for FLASH, HCOLOR=, HTAB, INVERSE, NORMAL,
PRINT, VTAB.
Added methods addLoadAddress, addLoadByteValue, addLoadFac,
addLoadWordValue, evaluateExpression.
Memory listing is read from properties file.
2003-06-06 03:28:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void addLoadAddress(Variable variable, char registerHi, char registerLo) {
|
2004-07-11 15:05:29 +00:00
|
|
|
addAssembly(null, "LD" + registerHi, "#>" + variable.getName()); //$NON-NLS-1$ //$NON-NLS-2$
|
|
|
|
addAssembly(null, "LD" + registerLo, "#<" + variable.getName()); //$NON-NLS-1$ //$NON-NLS-2$
|
Added support for FLASH, HCOLOR=, HTAB, INVERSE, NORMAL,
PRINT, VTAB.
Added methods addLoadAddress, addLoadByteValue, addLoadFac,
addLoadWordValue, evaluateExpression.
Memory listing is read from properties file.
2003-06-06 03:28:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
protected void addLoadFac(Variable variable) throws CompileException {
|
|
|
|
if (variable.isConstantFloat() || variable.isTypeFloat()) {
|
2003-06-14 02:44:43 +00:00
|
|
|
addLoadAddress(variable, 'Y', 'A');
|
2004-07-11 15:05:29 +00:00
|
|
|
addAssembly(null, "JSR","MOVFM"); //$NON-NLS-1$ //$NON-NLS-2$
|
2003-06-14 02:44:43 +00:00
|
|
|
} else if (variable.isConstantInteger() || variable.isTypeInteger()) {
|
|
|
|
addLoadWordValue(variable, 'A', 'Y');
|
2004-07-11 15:05:29 +00:00
|
|
|
addAssembly(null, "JSR", "GIVAYF"); //$NON-NLS-1$ //$NON-NLS-2$
|
Added support for FLASH, HCOLOR=, HTAB, INVERSE, NORMAL,
PRINT, VTAB.
Added methods addLoadAddress, addLoadByteValue, addLoadFac,
addLoadWordValue, evaluateExpression.
Memory listing is read from properties file.
2003-06-06 03:28:44 +00:00
|
|
|
} else {
|
2004-07-11 15:05:29 +00:00
|
|
|
throw new CompileException(textBundle.
|
|
|
|
format("ApplesoftCompiler.InvalidFloatTypeError", //$NON-NLS-1$
|
|
|
|
variable.getName()));
|
Added support for FLASH, HCOLOR=, HTAB, INVERSE, NORMAL,
PRINT, VTAB.
Added methods addLoadAddress, addLoadByteValue, addLoadFac,
addLoadWordValue, evaluateExpression.
Memory listing is read from properties file.
2003-06-06 03:28:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-06-14 02:44:43 +00:00
|
|
|
protected void addCopyFac(Variable variable) throws CompileException {
|
|
|
|
if (variable.isTypeFloat()) {
|
|
|
|
addLoadAddress(variable, 'Y', 'X');
|
2004-07-11 15:05:29 +00:00
|
|
|
addAssembly(null, "JSR", "MOVMF"); //$NON-NLS-1$ //$NON-NLS-2$
|
2003-06-14 02:44:43 +00:00
|
|
|
} else {
|
|
|
|
throw new CompileException(
|
2004-07-11 15:05:29 +00:00
|
|
|
textBundle.get("ApplesoftCompiler.CannotCopyToFloatError")); //$NON-NLS-1$
|
2003-06-14 02:44:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Added support for FLASH, HCOLOR=, HTAB, INVERSE, NORMAL,
PRINT, VTAB.
Added methods addLoadAddress, addLoadByteValue, addLoadFac,
addLoadWordValue, evaluateExpression.
Memory listing is read from properties file.
2003-06-06 03:28:44 +00:00
|
|
|
public void evaluateHTAB() throws CompileException {
|
|
|
|
addLoadByteValue(evaluateExpression(), 'A');
|
2004-07-11 15:05:29 +00:00
|
|
|
addAssembly(null, "STA", "CH"); //$NON-NLS-1$ //$NON-NLS-2$
|
Added support for FLASH, HCOLOR=, HTAB, INVERSE, NORMAL,
PRINT, VTAB.
Added methods addLoadAddress, addLoadByteValue, addLoadFac,
addLoadWordValue, evaluateExpression.
Memory listing is read from properties file.
2003-06-06 03:28:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void evaluateVTAB() throws CompileException {
|
|
|
|
addLoadByteValue(evaluateExpression(), 'X');
|
2004-07-11 15:05:29 +00:00
|
|
|
addAssembly(null, "DEX", null); //$NON-NLS-1$
|
|
|
|
addAssembly(null, "STX", "CV"); //$NON-NLS-1$ //$NON-NLS-2$
|
|
|
|
addAssembly(null, "JSR", "LF"); //$NON-NLS-1$ //$NON-NLS-2$
|
Added support for FLASH, HCOLOR=, HTAB, INVERSE, NORMAL,
PRINT, VTAB.
Added methods addLoadAddress, addLoadByteValue, addLoadFac,
addLoadWordValue, evaluateExpression.
Memory listing is read from properties file.
2003-06-06 03:28:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void evaluateHCOLOR() throws CompileException {
|
|
|
|
addLoadByteValue(evaluateExpression(), 'X');
|
2004-07-11 15:05:29 +00:00
|
|
|
addAssembly(null, "JSR", "SETHCOL"); //$NON-NLS-1$ //$NON-NLS-2$
|
Added support for FLASH, HCOLOR=, HTAB, INVERSE, NORMAL,
PRINT, VTAB.
Added methods addLoadAddress, addLoadByteValue, addLoadFac,
addLoadWordValue, evaluateExpression.
Memory listing is read from properties file.
2003-06-06 03:28:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void evaluatePRINT() throws CompileException {
|
|
|
|
ApplesoftToken token = null;
|
|
|
|
do {
|
|
|
|
Variable variable = evaluateExpression();
|
2003-12-21 01:11:58 +00:00
|
|
|
if (variable == null) {
|
2004-07-11 15:05:29 +00:00
|
|
|
addAssembly(null, "JSR", "PRCR"); //$NON-NLS-1$ //$NON-NLS-2$
|
2003-12-21 01:11:58 +00:00
|
|
|
} else if (variable.isConstantFloat() || variable.isTypeFloat()) {
|
Added support for FLASH, HCOLOR=, HTAB, INVERSE, NORMAL,
PRINT, VTAB.
Added methods addLoadAddress, addLoadByteValue, addLoadFac,
addLoadWordValue, evaluateExpression.
Memory listing is read from properties file.
2003-06-06 03:28:44 +00:00
|
|
|
addLoadFac(variable);
|
2004-07-11 15:05:29 +00:00
|
|
|
addAssembly(null, "JSR", "PRNTFAC"); //$NON-NLS-1$ //$NON-NLS-2$
|
Added support for FLASH, HCOLOR=, HTAB, INVERSE, NORMAL,
PRINT, VTAB.
Added methods addLoadAddress, addLoadByteValue, addLoadFac,
addLoadWordValue, evaluateExpression.
Memory listing is read from properties file.
2003-06-06 03:28:44 +00:00
|
|
|
} else if (variable.isConstantInteger() || variable.isTypeInteger()) {
|
|
|
|
addLoadWordValue(variable, 'X', 'A');
|
2004-07-11 15:05:29 +00:00
|
|
|
addAssembly(null, "JSR", "LINPRT"); //$NON-NLS-1$ //$NON-NLS-2$
|
Added support for FLASH, HCOLOR=, HTAB, INVERSE, NORMAL,
PRINT, VTAB.
Added methods addLoadAddress, addLoadByteValue, addLoadFac,
addLoadWordValue, evaluateExpression.
Memory listing is read from properties file.
2003-06-06 03:28:44 +00:00
|
|
|
} else if (variable.isConstantString()) {
|
|
|
|
addLoadAddress(variable, 'Y', 'A');
|
2004-07-11 15:05:29 +00:00
|
|
|
addAssembly(null, "JSR", "STROUT"); //$NON-NLS-1$ //$NON-NLS-2$
|
Added support for FLASH, HCOLOR=, HTAB, INVERSE, NORMAL,
PRINT, VTAB.
Added methods addLoadAddress, addLoadByteValue, addLoadFac,
addLoadWordValue, evaluateExpression.
Memory listing is read from properties file.
2003-06-06 03:28:44 +00:00
|
|
|
} else if (variable.isTypeString()) {
|
2004-07-11 15:05:29 +00:00
|
|
|
throw new CompileException(textBundle.get("ApplesoftCompiler.StringPrintUnsupported")); //$NON-NLS-1$
|
Added support for FLASH, HCOLOR=, HTAB, INVERSE, NORMAL,
PRINT, VTAB.
Added methods addLoadAddress, addLoadByteValue, addLoadFac,
addLoadWordValue, evaluateExpression.
Memory listing is read from properties file.
2003-06-06 03:28:44 +00:00
|
|
|
}
|
|
|
|
// check if we have separators to skip over...
|
|
|
|
token = peekToken();
|
|
|
|
if (token != null && token.isExpressionSeparator()) {
|
|
|
|
nextToken();
|
|
|
|
}
|
|
|
|
// see if we should continue processing the print statement
|
|
|
|
token = peekToken();
|
|
|
|
} while (token != null && !token.isEndOfCommand());
|
|
|
|
}
|
2003-06-14 02:44:43 +00:00
|
|
|
|
|
|
|
public void evaluateGOTO() throws CompileException {
|
2004-07-11 15:05:29 +00:00
|
|
|
addAssembly(null, "JMP", getLineNumberLabel()); //$NON-NLS-1$
|
2003-06-14 02:44:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
protected void checkSyntax(byte tokenValue, String expectedToken) throws CompileException {
|
|
|
|
ApplesoftToken token = nextToken();
|
|
|
|
if (token.getTokenValue() != tokenValue) {
|
|
|
|
// FIXME: Should this read token from master token list?
|
2004-07-11 15:05:29 +00:00
|
|
|
throw new CompileException(textBundle.
|
|
|
|
format("ApplesoftCompiler.SyntaxError", expectedToken)); //$NON-NLS-1$
|
2003-06-14 02:44:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void checkSyntax(String stringValue, String expectedToken) throws CompileException {
|
|
|
|
ApplesoftToken token = nextToken();
|
|
|
|
if (!stringValue.equals(token.getStringValue())) {
|
|
|
|
// FIXME: Should this read token from master token list?
|
2004-07-11 15:05:29 +00:00
|
|
|
throw new CompileException(textBundle.
|
|
|
|
format("ApplesoftCompiler.SyntaxError", expectedToken)); //$NON-NLS-1$
|
2003-06-14 02:44:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void evaluateFOR() throws CompileException {
|
|
|
|
Variable loopVariable = evaluateExpression();
|
2003-12-14 18:59:21 +00:00
|
|
|
if (!loopVariable.isTypeFloat() && !loopVariable.isTypeInteger()) {
|
2003-06-14 02:44:43 +00:00
|
|
|
throw new CompileException(
|
2004-07-11 15:05:29 +00:00
|
|
|
textBundle.get("ApplesoftCompiler.ForStatementUnsupportedTypeError")); //$NON-NLS-1$
|
2003-06-14 02:44:43 +00:00
|
|
|
}
|
2004-07-11 15:05:29 +00:00
|
|
|
checkSyntax(EQUALS, "="); //$NON-NLS-1$
|
2003-06-14 02:44:43 +00:00
|
|
|
Variable startValue = evaluateNumber();
|
2004-07-11 15:05:29 +00:00
|
|
|
checkSyntax(TO, "TO"); //$NON-NLS-1$
|
2003-06-14 02:44:43 +00:00
|
|
|
Variable endValue = evaluateNumber();
|
|
|
|
// FIXME: Need to handle STEP
|
2004-07-11 15:05:29 +00:00
|
|
|
String loopName = "FOR" + loopVariables.size(); //$NON-NLS-1$
|
2003-06-14 02:44:43 +00:00
|
|
|
loopVariables.add(loopName);
|
|
|
|
addLoadFac(startValue);
|
|
|
|
addCopyFac(loopVariable);
|
|
|
|
addAssembly(loopName, null, null);
|
|
|
|
addLoadFac(endValue);
|
|
|
|
addLoadAddress(loopVariable, 'Y', 'A');
|
2004-07-11 15:05:29 +00:00
|
|
|
addAssembly(null, "JSR", "FCOMP"); //$NON-NLS-1$ //$NON-NLS-2$
|
|
|
|
addAssembly(null, "CMP", "#$FF"); // loopVariable > endValue //$NON-NLS-1$ //$NON-NLS-2$
|
|
|
|
addAssembly(null, "BEQ", "END" + loopName); //$NON-NLS-1$ //$NON-NLS-2$
|
2003-06-14 02:44:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void evaluateHPLOT() throws CompileException {
|
|
|
|
boolean firstCoordinate = true;
|
|
|
|
while (peekToken() != null && !peekToken().isEndOfCommand()) {
|
|
|
|
if (!firstCoordinate) {
|
2004-07-11 15:05:29 +00:00
|
|
|
checkSyntax(TO, "TO"); //$NON-NLS-1$
|
2003-06-14 02:44:43 +00:00
|
|
|
}
|
|
|
|
Variable coordX = evaluateNumber();
|
2004-07-11 15:05:29 +00:00
|
|
|
checkSyntax(",", ", (comma)"); //$NON-NLS-1$ //$NON-NLS-2$
|
2003-06-14 02:44:43 +00:00
|
|
|
Variable coordY = evaluateNumber();
|
|
|
|
if (firstCoordinate) {
|
|
|
|
addLoadWordValue(coordX, 'Y', 'X');
|
|
|
|
addLoadByteValue(coordY, 'A');
|
2004-07-11 15:05:29 +00:00
|
|
|
addAssembly(null, "JSR", "HPOSN"); //$NON-NLS-1$ //$NON-NLS-2$
|
2003-06-14 02:44:43 +00:00
|
|
|
firstCoordinate = false;
|
|
|
|
} else {
|
|
|
|
addLoadWordValue(coordX, 'X', 'A');
|
|
|
|
addLoadByteValue(coordY, 'Y');
|
2004-07-11 15:05:29 +00:00
|
|
|
addAssembly(null, "JSR", "HLIN"); //$NON-NLS-1$ //$NON-NLS-2$
|
2003-06-14 02:44:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void evaluateNEXT() throws CompileException {
|
2003-12-14 18:59:21 +00:00
|
|
|
// FIXME: Next requires variable name given...
|
2003-06-14 02:44:43 +00:00
|
|
|
Variable variable = null;
|
|
|
|
if (!peekToken().isCommandSeparator()) {
|
|
|
|
// FIXME: This does not ensure that we only have a variable!
|
|
|
|
variable = evaluateExpression();
|
|
|
|
}
|
2003-12-14 18:59:21 +00:00
|
|
|
if (variable.isTypeFloat()) {
|
2004-07-11 15:05:29 +00:00
|
|
|
addAssembly(null, "LDY", "#1"); //$NON-NLS-1$ //$NON-NLS-2$
|
|
|
|
addAssembly(null, "JSR", "SNGFLT"); //$NON-NLS-1$ //$NON-NLS-2$
|
2003-12-14 18:59:21 +00:00
|
|
|
addLoadAddress(variable, 'Y', 'A');
|
2004-07-11 15:05:29 +00:00
|
|
|
addAssembly(null, "JSR", "FADD"); //$NON-NLS-1$ //$NON-NLS-2$
|
2003-12-14 18:59:21 +00:00
|
|
|
addCopyFac(variable);
|
|
|
|
} else if (variable.isTypeInteger()) {
|
2004-07-11 15:05:29 +00:00
|
|
|
addAssembly(null, "INC", variable.getName()); //$NON-NLS-1$
|
|
|
|
addAssembly(null, "BNE", ":1"); //$NON-NLS-1$ //$NON-NLS-2$
|
|
|
|
addAssembly(null, "INC", variable.getName() + "+1"); //$NON-NLS-1$ //$NON-NLS-2$
|
|
|
|
addAssembly(":1", null, null); //$NON-NLS-1$
|
2003-12-14 18:59:21 +00:00
|
|
|
}
|
2003-06-14 02:44:43 +00:00
|
|
|
String loopName = (String) loopVariables.pop();
|
2004-07-11 15:05:29 +00:00
|
|
|
addAssembly(null, "JMP", loopName); //$NON-NLS-1$
|
|
|
|
addAssembly("END" + loopName, null, null); //$NON-NLS-1$
|
2003-06-14 02:44:43 +00:00
|
|
|
}
|
Added support for FLASH, HCOLOR=, HTAB, INVERSE, NORMAL,
PRINT, VTAB.
Added methods addLoadAddress, addLoadByteValue, addLoadFac,
addLoadWordValue, evaluateExpression.
Memory listing is read from properties file.
2003-06-06 03:28:44 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Indicates if this string is a number.
|
|
|
|
*/
|
|
|
|
protected boolean isIntegerNumber(String value) {
|
|
|
|
for (int i=0; i<value.length(); i++) {
|
|
|
|
if (!Character.isDigit(value.charAt(i))) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
2003-06-03 05:47:57 +00:00
|
|
|
}
|
2003-12-14 18:59:21 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Indicates integer math only.
|
|
|
|
*/
|
|
|
|
public boolean isIntegerOnlyMath() {
|
|
|
|
return integerOnlyMath;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets integer only math.
|
|
|
|
*/
|
|
|
|
public void setIntegerOnlyMath(boolean integerOnlyMath) {
|
|
|
|
this.integerOnlyMath = integerOnlyMath;
|
|
|
|
}
|
2003-06-01 19:49:04 +00:00
|
|
|
}
|