mirror of
https://github.com/badvision/lawless-legends.git
synced 2024-07-05 01:28:57 +00:00
Merge branch 'master' of https://github.com/badvision/lawless-legends
This commit is contained in:
commit
8f8cdb075c
@ -269,6 +269,28 @@ def strlen(strptr)
|
||||
return ^strptr
|
||||
end
|
||||
```
|
||||
Pointers to structures or arrays can be referenced with the `->` and `=>` operators, pointing to `byte` or `word` sized elements.
|
||||
```
|
||||
const elem_id = 0
|
||||
const elem_addr = 1
|
||||
|
||||
def addentry(entry, id, addr)
|
||||
entry->elem_id = id ; set ID byte
|
||||
entry=>elem_addr = addr ; set address
|
||||
return entry + 3 ; return next enry address
|
||||
end
|
||||
```
|
||||
The above is equivalent to:
|
||||
```
|
||||
const elem_id = 0
|
||||
const elem_addr = 1
|
||||
|
||||
def addentry(entry, id, addr)
|
||||
(entry).elem_id = id ; set ID byte
|
||||
(entry):elem_addr = addr ; set address
|
||||
return entry + 3 ; return next enry address
|
||||
end
|
||||
```
|
||||
|
||||
##### Addresses of Data/Code
|
||||
Along with dereferencing a pointer, there is the question of getting the address of a variable. The `@` operator prepended to a variable name or a function definition name, will return the address of the variable/definition. From the previous example, the call to `strlen` would look like:
|
||||
@ -403,13 +425,16 @@ The complex test case is handled with `when`. Basically a `if`, `elsifF`, `else`
|
||||
when key
|
||||
is 'A'
|
||||
; handle A character
|
||||
break
|
||||
is 'B'
|
||||
; handle B character
|
||||
break
|
||||
```
|
||||
...
|
||||
```
|
||||
is 'Z'
|
||||
; handle Z character
|
||||
break
|
||||
otherwise
|
||||
; Not a known key
|
||||
wend
|
||||
@ -424,12 +449,15 @@ byte a
|
||||
when TRUE
|
||||
is (a <= 10)
|
||||
; 10 or less
|
||||
break
|
||||
is (a > 10) AND (a < 20)
|
||||
; between 10 and 20
|
||||
break
|
||||
is (a >= 20)
|
||||
; 20 or greater
|
||||
wend
|
||||
```
|
||||
A `when` clause can fall-through to the following clause, just like C `switch` statements by leaving out the `break` at the end of a clause.
|
||||
|
||||
##### FOR \<TO,DOWNTO\> [STEP]/NEXT
|
||||
Iteration over a range is handled with the `for`/`next` loop. When iterating from a smaller to larger value, the `to` construct is used; when iterating from larger to smaller, the `downto` construct is used.
|
||||
|
@ -29,6 +29,7 @@ import org.badvision.outlaweditor.data.TileUtils;
|
||||
import org.badvision.outlaweditor.data.xml.Map;
|
||||
import org.badvision.outlaweditor.data.xml.Script;
|
||||
import org.badvision.outlaweditor.data.xml.Tile;
|
||||
import org.badvision.outlaweditor.ui.ToolType;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -118,11 +119,17 @@ public class MapEditor extends Editor<Map, MapEditor.DrawMode> implements EventH
|
||||
public void assignScript(Script script, double x, double y) {
|
||||
int xx = (int) (x / tileWidth);
|
||||
int yy = (int) (y / tileHeight);
|
||||
System.out.println("Dropped " + script.getName() + " at " + xx + "," + yy);
|
||||
getCurrentMap().putLocationScript(xx, yy, script);
|
||||
redraw();
|
||||
}
|
||||
|
||||
public void unassignScripts(double x, double y) {
|
||||
int xx = (int) (x / tileWidth);
|
||||
int yy = (int) (y / tileHeight);
|
||||
getCurrentMap().removeLocationScripts(xx, yy);
|
||||
redraw();
|
||||
}
|
||||
|
||||
public void togglePanZoom() {
|
||||
anchorPane.getChildren().stream().filter((n) -> !(n == drawCanvas)).forEach((n) -> {
|
||||
n.setVisible(!n.isVisible());
|
||||
@ -238,8 +245,8 @@ public class MapEditor extends Editor<Map, MapEditor.DrawMode> implements EventH
|
||||
}
|
||||
}
|
||||
|
||||
private static final int dashLength=3;
|
||||
|
||||
private static final int dashLength = 3;
|
||||
|
||||
private void highlightScripts(int x, int y, List<Script> scripts) {
|
||||
if (scripts == null || scripts.isEmpty()) {
|
||||
return;
|
||||
@ -249,41 +256,41 @@ public class MapEditor extends Editor<Map, MapEditor.DrawMode> implements EventH
|
||||
double xx = x * tileWidth;
|
||||
double yy = y * tileHeight;
|
||||
gc.setLineWidth(4);
|
||||
for (int i = 0; i < tileWidth-2; i += dashLength) {
|
||||
for (int i = 0; i < tileWidth - 2; i += dashLength) {
|
||||
idx = (idx + 1) % scripts.size();
|
||||
gc.beginPath();
|
||||
gc.moveTo(xx,yy);
|
||||
gc.setStroke(currentMap.getScriptColor(scripts.get(idx)));
|
||||
gc.moveTo(xx, yy);
|
||||
currentMap.getScriptColor(scripts.get(idx)).ifPresent(gc::setStroke);
|
||||
xx += dashLength;
|
||||
gc.lineTo(xx, yy);
|
||||
gc.setEffect(new DropShadow(2, Color.BLACK));
|
||||
gc.stroke();
|
||||
}
|
||||
for (int i = 0; i < tileHeight-2; i += dashLength) {
|
||||
for (int i = 0; i < tileHeight - 2; i += dashLength) {
|
||||
idx = (idx + 1) % scripts.size();
|
||||
gc.beginPath();
|
||||
gc.moveTo(xx,yy);
|
||||
gc.setStroke(currentMap.getScriptColor(scripts.get(idx)));
|
||||
gc.moveTo(xx, yy);
|
||||
currentMap.getScriptColor(scripts.get(idx)).ifPresent(gc::setStroke);
|
||||
yy += dashLength;
|
||||
gc.lineTo(xx, yy);
|
||||
gc.setEffect(new DropShadow(2, Color.BLACK));
|
||||
gc.stroke();
|
||||
}
|
||||
for (int i = 0; i < tileWidth-2; i += dashLength) {
|
||||
for (int i = 0; i < tileWidth - 2; i += dashLength) {
|
||||
idx = (idx + 1) % scripts.size();
|
||||
gc.beginPath();
|
||||
gc.moveTo(xx,yy);
|
||||
gc.setStroke(currentMap.getScriptColor(scripts.get(idx)));
|
||||
gc.moveTo(xx, yy);
|
||||
currentMap.getScriptColor(scripts.get(idx)).ifPresent(gc::setStroke);
|
||||
xx -= dashLength;
|
||||
gc.lineTo(xx, yy);
|
||||
gc.setEffect(new DropShadow(2, Color.BLACK));
|
||||
gc.stroke();
|
||||
}
|
||||
for (int i = 0; i < tileHeight-2; i += dashLength) {
|
||||
for (int i = 0; i < tileHeight - 2; i += dashLength) {
|
||||
idx = (idx + 1) % scripts.size();
|
||||
gc.beginPath();
|
||||
gc.moveTo(xx,yy);
|
||||
gc.setStroke(currentMap.getScriptColor(scripts.get(idx)));
|
||||
gc.moveTo(xx, yy);
|
||||
currentMap.getScriptColor(scripts.get(idx)).ifPresent(gc::setStroke);
|
||||
yy -= dashLength;
|
||||
gc.lineTo(xx, yy);
|
||||
gc.setEffect(new DropShadow(2, Color.BLACK));
|
||||
@ -291,10 +298,13 @@ public class MapEditor extends Editor<Map, MapEditor.DrawMode> implements EventH
|
||||
}
|
||||
}
|
||||
|
||||
public void setupDragDrop(TransferHelper<Script> scriptHelper) {
|
||||
public void setupDragDrop(TransferHelper<Script> scriptHelper, TransferHelper<ToolType> toolHelper) {
|
||||
scriptHelper.registerDropSupport(drawCanvas, (Script script, double x, double y) -> {
|
||||
assignScript(script, x, y);
|
||||
});
|
||||
toolHelper.registerDropSupport(drawCanvas, (ToolType tool, double x, double y) -> {
|
||||
unassignScripts(x, y);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@ package org.badvision.outlaweditor;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.scene.ImageCursor;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.input.ClipboardContent;
|
||||
import javafx.scene.input.DataFormat;
|
||||
@ -11,6 +11,7 @@ import javafx.scene.input.DragEvent;
|
||||
import javafx.scene.input.Dragboard;
|
||||
import javafx.scene.input.MouseEvent;
|
||||
import javafx.scene.input.TransferMode;
|
||||
import org.badvision.outlaweditor.ui.ToolType;
|
||||
|
||||
/**
|
||||
* Simplify management of drag/drop operations
|
||||
@ -27,6 +28,7 @@ public class TransferHelper<T> {
|
||||
static Map<String, DataFormat> dataFormats = new HashMap<>();
|
||||
|
||||
public interface DropEventHandler<T> {
|
||||
|
||||
public void handle(T object, double x, double y);
|
||||
}
|
||||
|
||||
@ -50,35 +52,50 @@ public class TransferHelper<T> {
|
||||
source.setOnDragDetected((MouseEvent event) -> {
|
||||
registry.put(id, object);
|
||||
Dragboard db = source.startDragAndDrop(TransferMode.LINK);
|
||||
if (type.isAssignableFrom(ToolType.class)) {
|
||||
ToolType tool = (ToolType) object;
|
||||
tool.getIcon().ifPresent(db::setDragView);
|
||||
}
|
||||
ClipboardContent content = new ClipboardContent();
|
||||
content.put(format, id);
|
||||
db.setContent(content);
|
||||
event.consume();
|
||||
dropSupportRegisterHandler.run();
|
||||
});
|
||||
source.setOnDragDone((DragEvent event) -> {
|
||||
registry.remove(id);
|
||||
dropSupportRegisterHandler.run();
|
||||
});
|
||||
}
|
||||
|
||||
Runnable dropSupportRegisterHandler;
|
||||
Runnable dropSupportUnregisterHandler;
|
||||
|
||||
public void registerDropSupport(final Node target, final DropEventHandler<T> handler) {
|
||||
target.setOnDragOver((DragEvent event) -> {
|
||||
Dragboard db = event.getDragboard();
|
||||
if (db.getContentTypes().contains(format)) {
|
||||
event.acceptTransferModes(TransferMode.LINK);
|
||||
}
|
||||
event.consume();
|
||||
});
|
||||
target.setOnDragDropped((DragEvent event) -> {
|
||||
Dragboard db = event.getDragboard();
|
||||
if (db.getContentTypes().contains(format)) {
|
||||
event.setDropCompleted(true);
|
||||
String id = (String) db.getContent(format);
|
||||
T object = (T) registry.get(id);
|
||||
handler.handle(object, event.getX(), event.getY());
|
||||
} else {
|
||||
event.setDropCompleted(false);
|
||||
}
|
||||
event.consume();
|
||||
});
|
||||
dropSupportUnregisterHandler = () -> {
|
||||
target.setOnDragOver(null);
|
||||
target.setOnDragDropped(null);
|
||||
};
|
||||
dropSupportRegisterHandler = () -> {
|
||||
target.setOnDragOver((DragEvent event) -> {
|
||||
Dragboard db = event.getDragboard();
|
||||
if (db.getContentTypes().contains(format)) {
|
||||
event.acceptTransferModes(TransferMode.LINK);
|
||||
}
|
||||
event.consume();
|
||||
});
|
||||
target.setOnDragDropped((DragEvent event) -> {
|
||||
Dragboard db = event.getDragboard();
|
||||
if (db.getContentTypes().contains(format)) {
|
||||
event.setDropCompleted(true);
|
||||
String id = (String) db.getContent(format);
|
||||
T object = (T) registry.get(id);
|
||||
handler.handle(object, event.getX(), event.getY());
|
||||
} else {
|
||||
event.setDropCompleted(false);
|
||||
}
|
||||
event.consume();
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import javafx.scene.image.WritableImage;
|
||||
import javafx.scene.paint.Color;
|
||||
@ -45,11 +46,11 @@ public class TileMap extends ArrayList<ArrayList<Tile>> implements Serializable
|
||||
public static double HUE = 180;
|
||||
private final java.util.Map<Integer, List<Script>> locationScripts = new HashMap<>();
|
||||
private final java.util.Map<Script, Color> scriptColors = new HashMap<>();
|
||||
|
||||
public Color getScriptColor(Script s) {
|
||||
return scriptColors.get(s);
|
||||
|
||||
public Optional<Color> getScriptColor(Script s) {
|
||||
return Optional.ofNullable(scriptColors.get(s));
|
||||
}
|
||||
|
||||
|
||||
public List<Script> getLocationScripts(int x, int y) {
|
||||
List<Script> list = locationScripts.get(getMortonNumber(x, y));
|
||||
if (list != null) {
|
||||
@ -67,6 +68,20 @@ public class TileMap extends ArrayList<ArrayList<Tile>> implements Serializable
|
||||
registerLocationScript(x, y, s);
|
||||
}
|
||||
|
||||
public void removeLocationScripts(int x, int y) {
|
||||
int loc = getMortonNumber(x, y);
|
||||
List<Script> scripts = locationScripts.get(loc);
|
||||
if (scripts != null) {
|
||||
scripts.forEach(s -> {
|
||||
s.getLocationTrigger().removeIf(t -> {
|
||||
return t.getX() == x && t.getY() == y;
|
||||
});
|
||||
});
|
||||
}
|
||||
locationScripts.remove(loc);
|
||||
Application.getInstance().getController().redrawScripts();
|
||||
}
|
||||
|
||||
private void registerLocationScript(int x, int y, Script s) {
|
||||
if (!scriptColors.containsKey(s)) {
|
||||
scriptColors.put(s, Color.hsb(HUE, SATURATION, VALUE));
|
||||
@ -79,6 +94,7 @@ public class TileMap extends ArrayList<ArrayList<Tile>> implements Serializable
|
||||
locationScripts.put(loc, list);
|
||||
}
|
||||
list.add(s);
|
||||
Application.getInstance().getController().redrawScripts();
|
||||
}
|
||||
|
||||
private int getMortonNumber(int x, int y) {
|
||||
@ -157,7 +173,7 @@ public class TileMap extends ArrayList<ArrayList<Tile>> implements Serializable
|
||||
)
|
||||
);
|
||||
}
|
||||
m.getChunk().forEach( c-> {
|
||||
m.getChunk().forEach(c -> {
|
||||
int y = c.getY();
|
||||
for (JAXBElement<List<String>> row : c.getRow()) {
|
||||
int x = c.getX();
|
||||
|
@ -2,6 +2,7 @@ package org.badvision.outlaweditor.ui;
|
||||
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.CheckBox;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.control.ListView;
|
||||
@ -52,7 +53,9 @@ public abstract class MapEditorTabController {
|
||||
protected TextField mapWidthField; // Value injected by FXMLLoader
|
||||
@FXML // fx:id="mapWrapAround"
|
||||
protected CheckBox mapWrapAround; // Value injected by FXMLLoader
|
||||
|
||||
@FXML
|
||||
protected Button scriptEraseTool;
|
||||
|
||||
@FXML
|
||||
abstract public void mapDraw1(ActionEvent event);
|
||||
|
||||
|
@ -0,0 +1,20 @@
|
||||
package org.badvision.outlaweditor.ui;
|
||||
|
||||
import java.util.Optional;
|
||||
import javafx.scene.image.Image;
|
||||
|
||||
public enum ToolType {
|
||||
ERASER("images/eraser.png"), FILL(null), SELECT(null), MOVE(null), DRAW(null);
|
||||
|
||||
ToolType(String iconPath) {
|
||||
if (iconPath != null) {
|
||||
icon = Optional.of(new Image(iconPath));
|
||||
} else {
|
||||
icon = Optional.empty();
|
||||
}
|
||||
}
|
||||
Optional<Image> icon;
|
||||
public Optional<Image> getIcon() {
|
||||
return icon;
|
||||
}
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
package org.badvision.outlaweditor.ui.impl;
|
||||
|
||||
import org.badvision.outlaweditor.ui.EntitySelectorCell;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javafx.event.ActionEvent;
|
||||
@ -12,19 +11,21 @@ import javafx.scene.image.ImageView;
|
||||
import javafx.scene.image.WritableImage;
|
||||
import javafx.util.Callback;
|
||||
import org.badvision.outlaweditor.Application;
|
||||
import org.badvision.outlaweditor.MapEditor;
|
||||
import org.badvision.outlaweditor.TransferHelper;
|
||||
import static org.badvision.outlaweditor.Application.currentPlatform;
|
||||
import static org.badvision.outlaweditor.Application.gameData;
|
||||
import static org.badvision.outlaweditor.ui.UIAction.confirm;
|
||||
import static org.badvision.outlaweditor.ui.UIAction.createAndEditScript;
|
||||
import org.badvision.outlaweditor.MapEditor;
|
||||
import org.badvision.outlaweditor.TransferHelper;
|
||||
import static org.badvision.outlaweditor.data.PropertyHelper.bind;
|
||||
import static org.badvision.outlaweditor.data.PropertyHelper.stringProp;
|
||||
import org.badvision.outlaweditor.data.TileUtils;
|
||||
import org.badvision.outlaweditor.data.xml.Script;
|
||||
import org.badvision.outlaweditor.data.xml.Map;
|
||||
import org.badvision.outlaweditor.data.xml.Script;
|
||||
import org.badvision.outlaweditor.ui.EntitySelectorCell;
|
||||
import org.badvision.outlaweditor.ui.MapEditorTabController;
|
||||
import org.badvision.outlaweditor.ui.ToolType;
|
||||
import org.badvision.outlaweditor.ui.UIAction;
|
||||
import static org.badvision.outlaweditor.ui.UIAction.confirm;
|
||||
import static org.badvision.outlaweditor.ui.UIAction.createAndEditScript;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -32,6 +33,7 @@ import org.badvision.outlaweditor.ui.UIAction;
|
||||
*/
|
||||
public class MapEditorTabControllerImpl extends MapEditorTabController {
|
||||
final TransferHelper<Script> scriptDragDrop = new TransferHelper<>(Script.class);
|
||||
final TransferHelper<ToolType> toolDragDrop = new TransferHelper<>(ToolType.class);
|
||||
|
||||
@Override
|
||||
public void mapDraw1(ActionEvent event) {
|
||||
@ -234,7 +236,7 @@ public class MapEditorTabControllerImpl extends MapEditorTabController {
|
||||
e.setEntity(m);
|
||||
e.buildEditorUI(mapEditorAnchorPane);
|
||||
setCurrentEditor(e);
|
||||
e.setupDragDrop(scriptDragDrop);
|
||||
e.setupDragDrop(scriptDragDrop, toolDragDrop);
|
||||
}
|
||||
redrawMapScripts();
|
||||
}
|
||||
@ -270,6 +272,7 @@ public class MapEditorTabControllerImpl extends MapEditorTabController {
|
||||
public void finishUpdate(Map item) {
|
||||
}
|
||||
});
|
||||
toolDragDrop.registerDragSupport(scriptEraseTool, ToolType.ERASER);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -306,6 +309,7 @@ public class MapEditorTabControllerImpl extends MapEditorTabController {
|
||||
if (empty || item == null) {
|
||||
setText("");
|
||||
} else {
|
||||
getCurrentEditor().getCurrentMap().getScriptColor(item).ifPresent(this::setTextFill);
|
||||
setText(item.getName());
|
||||
scriptDragDrop.registerDragSupport(this, item);
|
||||
}
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
<?import java.lang.*?>
|
||||
<?import java.net.*?>
|
||||
<?import javafx.collections.*?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
|
||||
@ -10,29 +9,28 @@
|
||||
<children>
|
||||
<VBox prefHeight="500.0" prefWidth="800.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<children>
|
||||
<fx:include fx:id="menu" source="Menubar.fxml"/>
|
||||
<fx:include fx:id="menu" source="Menubar.fxml" />
|
||||
<TabPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="455.0" prefWidth="676.9998779296875" tabClosingPolicy="UNAVAILABLE" VBox.vgrow="ALWAYS">
|
||||
<tabs>
|
||||
<Tab onSelectionChanged="#tileTabActivated" text="Tiles">
|
||||
<content>
|
||||
<fx:include fx:id="tile" source="tileEditorTab.fxml"/>
|
||||
<fx:include fx:id="tile" source="tileEditorTab.fxml" />
|
||||
</content>
|
||||
</Tab>
|
||||
<Tab onSelectionChanged="#mapTabActivated" text="Maps">
|
||||
<content>
|
||||
<fx:include fx:id="map" source="mapEditorTab.fxml"/>
|
||||
<fx:include fx:id="map" source="mapEditorTab.fxml" />
|
||||
</content>
|
||||
</Tab>
|
||||
<Tab onSelectionChanged="#imageTabActivated" text="Images">
|
||||
<content>
|
||||
<fx:include fx:id="image" source="imageEditorTab.fxml"/>
|
||||
<fx:include fx:id="image" source="imageEditorTab.fxml" />
|
||||
</content>
|
||||
</Tab>
|
||||
</tabs>
|
||||
</TabPane>
|
||||
</children>
|
||||
</VBox>
|
||||
<HBox layoutX="300.0" layoutY="200.0" prefHeight="100.0" prefWidth="200.0" />
|
||||
</children>
|
||||
<stylesheets>
|
||||
<URL value="@styles/applicationui.css" />
|
||||
|
@ -1,23 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import java.lang.*?>
|
||||
<?import javafx.scene.*?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import org.tbee.javafx.scene.layout.fxml.MigPane?>
|
||||
<?import layouttests.migfxml.sample1.*?>
|
||||
|
||||
<MigPane id="rootPane" fx:controller="org.badvision.outlaweditor.HelloController"
|
||||
styleClass="main-panel"
|
||||
layout="insets 20"
|
||||
cols="[label, pref!][grow, 50::]"
|
||||
rows=""
|
||||
xmlns:fx="http://javafx.com/fxml">
|
||||
|
||||
<Label text="First Name:" /> <TextField fx:id="firstNameField" prefColumnCount="30" MigPane.cc="growx, wrap" />
|
||||
<Label text="Last Name:" /> <TextField fx:id="lastNameField" prefColumnCount="30" MigPane.cc="growx, wrap" />
|
||||
|
||||
<Button text="Say Hello" onAction="#sayHello" MigPane.cc="skip, gap :push, gaptop 15, wrap" />
|
||||
|
||||
<Label fx:id="messageLabel" styleClass="hello-message" MigPane.cc="span, growx, gaptop 15" />
|
||||
|
||||
</MigPane >
|
BIN
OutlawEditor/src/main/resources/images/eraser-icon.png
Normal file
BIN
OutlawEditor/src/main/resources/images/eraser-icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 774 B |
BIN
OutlawEditor/src/main/resources/images/eraser.png
Normal file
BIN
OutlawEditor/src/main/resources/images/eraser.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
@ -59,7 +59,7 @@
|
||||
<items>
|
||||
<Button mnemonicParsing="false" onAction="#onMapScriptAddPressed" text="+" />
|
||||
<Button mnemonicParsing="false" onAction="#onMapScriptDeletePressed" text="-" />
|
||||
<Button mnemonicParsing="false" onAction="#onMapScriptClonePressed" text="Clone" />
|
||||
<Button mnemonicParsing="false" onAction="#onMapScriptClonePressed" text="Clone" /><Button fx:id="scriptEraseTool" mnemonicParsing="false" prefHeight="34.0" prefWidth="29.0" styleClass="eraseButton" text="E" />
|
||||
</items>
|
||||
</ToolBar><TextArea fx:id="scriptInfo" editable="false" layoutY="340.0" prefHeight="100.0" prefWidth="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" />
|
||||
</children>
|
||||
|
@ -7,19 +7,25 @@
|
||||
}
|
||||
|
||||
.moveButton {
|
||||
-fx-graphic: url("../images/arrowUp.png");
|
||||
-fx-graphic: url("../images/arrowUp.png");
|
||||
}
|
||||
|
||||
.zoomOutButton {
|
||||
-fx-graphic: url("../images/zoomOut.png");
|
||||
-fx-graphic: url("../images/zoomOut.png");
|
||||
}
|
||||
|
||||
.zoomInButton {
|
||||
-fx-graphic: url("../images/zoomIn.png");
|
||||
-fx-graphic: url("../images/zoomIn.png");
|
||||
}
|
||||
|
||||
.moveButton, .zoomInButton, .zoomOutButton{
|
||||
-fx-background-color: rgba(0,0,0,0);
|
||||
-fx-content-display: graphic-only;
|
||||
-fx-effect: dropshadow(gaussian, navy, 10, 0.5, 0, 0);
|
||||
-fx-background-color: rgba(0,0,0,0);
|
||||
-fx-content-display: graphic-only;
|
||||
-fx-effect: dropshadow(gaussian, navy, 10, 0.5, 0, 0);
|
||||
}
|
||||
|
||||
.eraseButton {
|
||||
-fx-graphic: url("../images/eraser-icon.png");
|
||||
-fx-content-display: graphic-only;
|
||||
-fx-background-color: rgba(0,0,0,0);
|
||||
}
|
@ -268,26 +268,33 @@ Control structures affect the flow of control through the program. There are co
|
||||
fin
|
||||
```
|
||||
|
||||
The when/is/otherwise/wend statement is similar to the if/elsif/else/fin construct except that it is more efficient. It selects one path based on the evaluated expressions, then merges the code path back together at the end. However only the 'when' value is compared against a list of expressions. The expressions do not need to be constants, they can be any valid expression. The list of expressions is evaluated in order, so for efficiency sake, place the most common cases earlier in the list.
|
||||
The when/is/otherwise/wend statement is similar to the if/elsif/else/fin construct except that it is more efficient. It selects one path based on the evaluated expressions, then merges the code path back together at the end. However only the 'when' value is compared against a list of expressions. The expressions do not need to be constants, they can be any valid expression. The list of expressions is evaluated in order, so for efficiency sake, place the most common cases earlier in the list. Just as in C programs, a 'break' statement is required to keep one clause from falling through to the next. Falling through from one clause to the next can have it's uses, so this behavior has been added to PLASMA.
|
||||
|
||||
```
|
||||
when keypressed
|
||||
is keyarrowup
|
||||
cursup
|
||||
break
|
||||
is keyarrowdown
|
||||
cursdown
|
||||
break
|
||||
is keyarrowleft
|
||||
cursleft
|
||||
break
|
||||
is keyarrowright
|
||||
cursright
|
||||
break
|
||||
is keyctrlx
|
||||
cutline
|
||||
break
|
||||
is keyctrlv
|
||||
pasteline
|
||||
break
|
||||
is keyescape
|
||||
cursoff
|
||||
cmdmode
|
||||
redraw
|
||||
break
|
||||
otherwise
|
||||
bell
|
||||
wend
|
||||
|
@ -812,8 +812,8 @@ def addsym(sym, addr)
|
||||
lastsym = lastsym + 1
|
||||
sym = sym + 1
|
||||
loop
|
||||
(lastsym).0 = ^sym
|
||||
(lastsym):1 = addr
|
||||
lastsym->0 = ^sym
|
||||
lastsym=>1 = addr
|
||||
lastsym = lastsym + 3
|
||||
^lastsym = 0
|
||||
end
|
||||
@ -839,7 +839,7 @@ def lookupextern(esd, index)
|
||||
while ^esd
|
||||
sym = esd
|
||||
esd = esd + dcitos(esd, @str)
|
||||
if (esd).0 & $10 and (esd).1 == index
|
||||
if esd->0 & $10 and esd->1 == index
|
||||
addr = lookupsym(sym)
|
||||
if !addr
|
||||
perr = $81
|
||||
@ -858,18 +858,18 @@ def adddef(bank, addr, deflast)
|
||||
defentry = *deflast
|
||||
*deflast = defentry + 5
|
||||
if bank
|
||||
(defentry):1 = $03DC ; JSR $03DC (AUX MEM INTERP)
|
||||
defentry=>1 = $03DC ; JSR $03DC (AUX MEM INTERP)
|
||||
else
|
||||
(defentry):1 = $03D6 ; JSR $03D6 (MAIN MEM INTERP)
|
||||
defentry=>1 = $03D6 ; JSR $03D6 (MAIN MEM INTERP)
|
||||
fin
|
||||
(defentry).0 = $20
|
||||
(defentry):3 = addr
|
||||
(defentry).5 = 0 ; NULL out next entry
|
||||
defentry->0 = $20
|
||||
defentry=>3 = addr
|
||||
defentry->5 = 0 ; NULL out next entry
|
||||
return defentry
|
||||
end
|
||||
def lookupdef(addr, deftbl)
|
||||
while (deftbl).0 == $20
|
||||
if (deftbl):3 == addr
|
||||
while deftbl->0 == $20
|
||||
if deftbl=>3 == addr
|
||||
return deftbl
|
||||
fin
|
||||
deftbl = deftbl + 5
|
||||
@ -983,9 +983,9 @@ def loadmod(mod)
|
||||
;
|
||||
; This is a bytcode def entry - add it to the def directory.
|
||||
;
|
||||
adddef(defbank, (rld):1 - defofst + defaddr, @deflast)
|
||||
adddef(defbank, rld=>1 - defofst + defaddr, @deflast)
|
||||
else
|
||||
addr = (rld):1 + modfix
|
||||
addr = rld=>1 + modfix
|
||||
if uword_isge(addr, modaddr) ; Skip fixups to header
|
||||
if ^rld & $80 ; WORD sized fixup.
|
||||
fixup = *addr
|
||||
@ -993,7 +993,7 @@ def loadmod(mod)
|
||||
fixup = ^addr
|
||||
fin
|
||||
if ^rld & $10 ; EXTERN reference.
|
||||
fixup = fixup + lookupextern(esd, (rld).3)
|
||||
fixup = fixup + lookupextern(esd, rld->3)
|
||||
else ; INTERN fixup.
|
||||
fixup = fixup + modfix - MODADDR
|
||||
if uword_isge(fixup, bytecode)
|
||||
@ -1022,7 +1022,7 @@ def loadmod(mod)
|
||||
;
|
||||
; EXPORT symbol - add it to the global symbol table.
|
||||
;
|
||||
addr = (esd):1 + modfix - MODADDR
|
||||
addr = esd=>1 + modfix - MODADDR
|
||||
if uword_isge(addr, bytecode)
|
||||
;
|
||||
; Use the def directory address for bytecode.
|
||||
@ -1123,10 +1123,10 @@ def catalog(optpath)
|
||||
if type & $F0 == $D0 ; Is it a directory?
|
||||
cout('/')
|
||||
len = len + 1
|
||||
elsif (entry).$10 == $FF
|
||||
elsif entry->$10 == $FF
|
||||
cout('-')
|
||||
len = len + 1
|
||||
elsif (entry).$10 == $FE
|
||||
elsif entry->$10 == $FE
|
||||
cout('+')
|
||||
len = len + 1
|
||||
fin
|
||||
@ -1250,8 +1250,8 @@ heap = *freemem
|
||||
stodci(@stdlibstr, heap)
|
||||
addmod(heap, @version)
|
||||
while *stdlibsym
|
||||
stodci((stdlibsym):0, heap)
|
||||
addsym(heap, (stdlibsym):2)
|
||||
stodci(stdlibsym=>0, heap)
|
||||
addsym(heap, stdlibsym=>2)
|
||||
stdlibsym = stdlibsym + 4
|
||||
loop
|
||||
;
|
||||
|
@ -22,28 +22,28 @@ t_token keywords[] = {
|
||||
ENDCASE_TOKEN, 'W', 'E', 'N', 'D',
|
||||
FOR_TOKEN, 'F', 'O', 'R',
|
||||
TO_TOKEN, 'T', 'O',
|
||||
DOWNTO_TOKEN, 'D', 'O', 'W', 'N', 'T', 'O',
|
||||
DOWNTO_TOKEN, 'D', 'O', 'W', 'N', 'T', 'O',
|
||||
STEP_TOKEN, 'S', 'T', 'E', 'P',
|
||||
NEXT_TOKEN, 'N', 'E', 'X', 'T',
|
||||
REPEAT_TOKEN, 'R', 'E', 'P', 'E', 'A', 'T',
|
||||
UNTIL_TOKEN, 'U', 'N', 'T', 'I', 'L',
|
||||
BREAK_TOKEN, 'B', 'R', 'E', 'A', 'K',
|
||||
UNTIL_TOKEN, 'U', 'N', 'T', 'I', 'L',
|
||||
BREAK_TOKEN, 'B', 'R', 'E', 'A', 'K',
|
||||
ASM_TOKEN, 'A', 'S', 'M',
|
||||
DEF_TOKEN, 'D', 'E', 'F',
|
||||
EXPORT_TOKEN, 'E', 'X', 'P', 'O', 'R', 'T',
|
||||
IMPORT_TOKEN, 'I', 'M', 'P', 'O', 'R', 'T',
|
||||
EXPORT_TOKEN, 'E', 'X', 'P', 'O', 'R', 'T',
|
||||
IMPORT_TOKEN, 'I', 'M', 'P', 'O', 'R', 'T',
|
||||
RETURN_TOKEN, 'R', 'E', 'T', 'U', 'R', 'N',
|
||||
END_TOKEN, 'E', 'N', 'D',
|
||||
EXIT_TOKEN, 'E', 'X', 'I', 'T',
|
||||
DONE_TOKEN, 'D', 'O', 'N', 'E',
|
||||
LOGIC_NOT_TOKEN, 'N', 'O', 'T',
|
||||
LOGIC_AND_TOKEN, 'A', 'N', 'D',
|
||||
LOGIC_OR_TOKEN, 'O', 'R',
|
||||
LOGIC_OR_TOKEN, 'O', 'R',
|
||||
BYTE_TOKEN, 'B', 'Y', 'T', 'E',
|
||||
WORD_TOKEN, 'W', 'O', 'R', 'D',
|
||||
CONST_TOKEN, 'C', 'O', 'N', 'S', 'T',
|
||||
PREDEF_TOKEN, 'P', 'R', 'E', 'D', 'E', 'F',
|
||||
SYSFLAGS_TOKEN, 'S', 'Y', 'S', 'F', 'L', 'A', 'G', 'S',
|
||||
SYSFLAGS_TOKEN, 'S', 'Y', 'S', 'F', 'L', 'A', 'G', 'S',
|
||||
EOL_TOKEN
|
||||
};
|
||||
|
||||
@ -293,6 +293,11 @@ t_token scan(void)
|
||||
scantoken = EQ_TOKEN;
|
||||
scanpos += 2;
|
||||
}
|
||||
else if (scanpos[1] == '>')
|
||||
{
|
||||
scantoken = PTRW_TOKEN;
|
||||
scanpos += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
scantoken = SET_TOKEN;
|
||||
@ -317,6 +322,11 @@ t_token scan(void)
|
||||
scantoken = DEC_TOKEN;
|
||||
scanpos += 2;
|
||||
}
|
||||
else if (scanpos[1] == '>')
|
||||
{
|
||||
scantoken = PTRB_TOKEN;
|
||||
scanpos += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
scantoken = SUB_TOKEN;
|
||||
|
@ -288,108 +288,25 @@ int parse_value(int rvalue)
|
||||
*/
|
||||
while (scan() == OPEN_PAREN_TOKEN
|
||||
|| scantoken == OPEN_BRACKET_TOKEN
|
||||
|| scantoken == PTRB_TOKEN
|
||||
|| scantoken == PTRW_TOKEN
|
||||
|| scantoken == DOT_TOKEN
|
||||
|| scantoken == COLON_TOKEN)
|
||||
{
|
||||
if (scantoken == OPEN_BRACKET_TOKEN)
|
||||
switch (scantoken)
|
||||
{
|
||||
/*
|
||||
* Array
|
||||
*/
|
||||
if (!emit_value)
|
||||
{
|
||||
if (type & ADDR_TYPE)
|
||||
{
|
||||
if (type & LOCAL_TYPE)
|
||||
emit_localaddr(value);
|
||||
else
|
||||
emit_globaladdr(value, 0, type);
|
||||
}
|
||||
else if (type & CONST_TYPE)
|
||||
{
|
||||
emit_const(value);
|
||||
}
|
||||
emit_value = 1;
|
||||
}
|
||||
if (type & PTR_TYPE)
|
||||
emit_lw();
|
||||
if (!parse_expr())
|
||||
{
|
||||
parse_error("Bad expression");
|
||||
return (0);
|
||||
}
|
||||
if (scantoken != CLOSE_BRACKET_TOKEN)
|
||||
{
|
||||
parse_error("Missing closing bracket");
|
||||
return (0);
|
||||
}
|
||||
if (type & WORD_TYPE)
|
||||
{
|
||||
//type |= WPTR_TYPE;
|
||||
type = WPTR_TYPE;
|
||||
emit_indexword();
|
||||
}
|
||||
else
|
||||
{
|
||||
//type |= BPTR_TYPE;
|
||||
type = BPTR_TYPE;
|
||||
emit_indexbyte();
|
||||
}
|
||||
//type &= ~(ADDR_TYPE | CONST_TYPE);
|
||||
}
|
||||
else if (scantoken == DOT_TOKEN || scantoken == COLON_TOKEN)
|
||||
{
|
||||
/*
|
||||
* Structure member offset or array of arrays
|
||||
*/
|
||||
elem_type = (scantoken == DOT_TOKEN) ? BPTR_TYPE : WPTR_TYPE;
|
||||
if (parse_constval(&elem_offset, &elem_size))
|
||||
{
|
||||
case OPEN_BRACKET_TOKEN:
|
||||
/*
|
||||
* Constant member offset
|
||||
*/
|
||||
if (!emit_value)
|
||||
{
|
||||
if (type & VAR_TYPE)
|
||||
{
|
||||
elem_type = (type & ~VAR_TYPE) | (elem_type == BPTR_TYPE ? BYTE_TYPE : WORD_TYPE);
|
||||
}
|
||||
else if (type & CONST_TYPE)
|
||||
{
|
||||
value += elem_offset;
|
||||
emit_const(value);
|
||||
elem_offset = 0;
|
||||
emit_value = 1;
|
||||
}
|
||||
else // FUNC_TYPE
|
||||
{
|
||||
emit_globaladdr(value, elem_offset, type);
|
||||
emit_value = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (elem_offset != 0)
|
||||
{
|
||||
emit_const(elem_offset);
|
||||
emit_op(ADD_TOKEN);
|
||||
elem_offset = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (scantoken == OPEN_BRACKET_TOKEN)
|
||||
{
|
||||
/*
|
||||
* Array of arrays
|
||||
* Array
|
||||
*/
|
||||
if (!emit_value)
|
||||
{
|
||||
if (type & ADDR_TYPE)
|
||||
{
|
||||
if (type & LOCAL_TYPE)
|
||||
emit_localaddr(value + elem_offset);
|
||||
emit_localaddr(value);
|
||||
else
|
||||
emit_globaladdr(value, elem_offset, type);
|
||||
emit_globaladdr(value, 0, type);
|
||||
}
|
||||
else if (type & CONST_TYPE)
|
||||
{
|
||||
@ -397,75 +314,181 @@ int parse_value(int rvalue)
|
||||
}
|
||||
emit_value = 1;
|
||||
}
|
||||
while (parse_expr())
|
||||
{
|
||||
if (scantoken != COMMA_TOKEN)
|
||||
break;
|
||||
emit_indexword();
|
||||
if (type & PTR_TYPE)
|
||||
emit_lw();
|
||||
if (!parse_expr())
|
||||
{
|
||||
parse_error("Bad expression");
|
||||
return (0);
|
||||
}
|
||||
if (scantoken != CLOSE_BRACKET_TOKEN)
|
||||
{
|
||||
parse_error("Missing closing bracket");
|
||||
return (0);
|
||||
}
|
||||
if (elem_type & WPTR_TYPE)
|
||||
emit_indexword();
|
||||
else
|
||||
emit_indexbyte();
|
||||
}
|
||||
else
|
||||
{
|
||||
parse_error("Invalid member offset");
|
||||
return (0);
|
||||
}
|
||||
type = elem_type; //(type & ~(ADDR_TYPE | CONST_TYPE)) | elem_type;
|
||||
}
|
||||
else if (scantoken == OPEN_PAREN_TOKEN)
|
||||
{
|
||||
/*
|
||||
* Function call
|
||||
*/
|
||||
if (emit_value && !(type & (FUNC_TYPE | CONST_TYPE)))
|
||||
{
|
||||
if (scan_lookahead() != CLOSE_PAREN_TOKEN)
|
||||
emit_push();
|
||||
}
|
||||
cparams = 0;
|
||||
while (parse_expr())
|
||||
{
|
||||
cparams++;
|
||||
if (scantoken != COMMA_TOKEN)
|
||||
break;
|
||||
}
|
||||
if (scantoken != CLOSE_PAREN_TOKEN)
|
||||
{
|
||||
parse_error("Missing closing parenthesis");
|
||||
return (0);
|
||||
}
|
||||
if (type & (FUNC_TYPE | CONST_TYPE))
|
||||
emit_call(value, type);
|
||||
else
|
||||
{
|
||||
if (!emit_value)
|
||||
if (type & WORD_TYPE)
|
||||
{
|
||||
if (type & VAR_TYPE)
|
||||
{
|
||||
if (type & LOCAL_TYPE)
|
||||
emit_llw(value + elem_offset);
|
||||
else
|
||||
emit_law(value, elem_offset, type);
|
||||
}
|
||||
else if (type & PTR_TYPE)
|
||||
emit_lw();
|
||||
//type |= WPTR_TYPE;
|
||||
type = WPTR_TYPE;
|
||||
emit_indexword();
|
||||
}
|
||||
else
|
||||
if (cparams)
|
||||
emit_pull();
|
||||
emit_ical();
|
||||
}
|
||||
emit_value = 1;
|
||||
type = WORD_TYPE; //(type & ~(FUNC_TYPE | CONST_TYPE)) | WORD_TYPE;
|
||||
{
|
||||
//type |= BPTR_TYPE;
|
||||
type = BPTR_TYPE;
|
||||
emit_indexbyte();
|
||||
}
|
||||
//type &= ~(ADDR_TYPE | CONST_TYPE);
|
||||
break;
|
||||
case PTRB_TOKEN:
|
||||
case PTRW_TOKEN:
|
||||
if (!emit_value)
|
||||
{
|
||||
if (type & FUNC_TYPE)
|
||||
emit_call(value, type);
|
||||
else if (type & VAR_TYPE)
|
||||
{
|
||||
if (type & LOCAL_TYPE)
|
||||
(type & BYTE_TYPE) ? emit_llb(value + elem_offset) : emit_llw(value + elem_offset);
|
||||
else
|
||||
(type & BYTE_TYPE) ? emit_lab(value, elem_offset, type) : emit_law(value, elem_offset, type);
|
||||
}
|
||||
else
|
||||
(type & BPTR_TYPE) ? emit_lb() : emit_lw();
|
||||
}
|
||||
emit_value = 1;
|
||||
type &= ~(VAR_TYPE | ADDR_TYPE);
|
||||
type |= WORD_TYPE;
|
||||
scantoken = scantoken == PTRB_TOKEN ? DOT_TOKEN : COLON_TOKEN;
|
||||
case DOT_TOKEN:
|
||||
case COLON_TOKEN:
|
||||
/*
|
||||
* Structure member offset or array of arrays
|
||||
*/
|
||||
elem_type = (scantoken == DOT_TOKEN) ? BPTR_TYPE : WPTR_TYPE;
|
||||
if (parse_constval(&elem_offset, &elem_size))
|
||||
{
|
||||
/*
|
||||
* Constant member offset
|
||||
*/
|
||||
if (!emit_value)
|
||||
{
|
||||
if (type & VAR_TYPE)
|
||||
{
|
||||
elem_type = (type & ~VAR_TYPE) | (elem_type == BPTR_TYPE ? BYTE_TYPE : WORD_TYPE);
|
||||
}
|
||||
else if (type & CONST_TYPE)
|
||||
{
|
||||
value += elem_offset;
|
||||
emit_const(value);
|
||||
elem_offset = 0;
|
||||
emit_value = 1;
|
||||
}
|
||||
else // FUNC_TYPE
|
||||
{
|
||||
emit_globaladdr(value, elem_offset, type);
|
||||
emit_value = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (elem_offset != 0)
|
||||
{
|
||||
emit_const(elem_offset);
|
||||
emit_op(ADD_TOKEN);
|
||||
elem_offset = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (scantoken == OPEN_BRACKET_TOKEN)
|
||||
{
|
||||
/*
|
||||
* Array of arrays
|
||||
*/
|
||||
if (!emit_value)
|
||||
{
|
||||
if (type & ADDR_TYPE)
|
||||
{
|
||||
if (type & LOCAL_TYPE)
|
||||
emit_localaddr(value + elem_offset);
|
||||
else
|
||||
emit_globaladdr(value, elem_offset, type);
|
||||
}
|
||||
else if (type & CONST_TYPE)
|
||||
{
|
||||
emit_const(value);
|
||||
}
|
||||
emit_value = 1;
|
||||
}
|
||||
while (parse_expr())
|
||||
{
|
||||
if (scantoken != COMMA_TOKEN)
|
||||
break;
|
||||
emit_indexword();
|
||||
emit_lw();
|
||||
}
|
||||
if (scantoken != CLOSE_BRACKET_TOKEN)
|
||||
{
|
||||
parse_error("Missing closing bracket");
|
||||
return (0);
|
||||
}
|
||||
if (elem_type & WPTR_TYPE)
|
||||
emit_indexword();
|
||||
else
|
||||
emit_indexbyte();
|
||||
}
|
||||
else
|
||||
{
|
||||
parse_error("Invalid member offset");
|
||||
return (0);
|
||||
}
|
||||
type = elem_type; //(type & ~(ADDR_TYPE | CONST_TYPE)) | elem_type;
|
||||
break;
|
||||
case OPEN_PAREN_TOKEN:
|
||||
/*
|
||||
* Function call
|
||||
*/
|
||||
if (emit_value && !(type & (FUNC_TYPE | CONST_TYPE)))
|
||||
{
|
||||
if (scan_lookahead() != CLOSE_PAREN_TOKEN)
|
||||
emit_push();
|
||||
}
|
||||
cparams = 0;
|
||||
while (parse_expr())
|
||||
{
|
||||
cparams++;
|
||||
if (scantoken != COMMA_TOKEN)
|
||||
break;
|
||||
}
|
||||
if (scantoken != CLOSE_PAREN_TOKEN)
|
||||
{
|
||||
parse_error("Missing closing parenthesis");
|
||||
return (0);
|
||||
}
|
||||
if (type & (FUNC_TYPE | CONST_TYPE))
|
||||
emit_call(value, type);
|
||||
else
|
||||
{
|
||||
if (!emit_value)
|
||||
{
|
||||
if (type & VAR_TYPE)
|
||||
{
|
||||
if (type & LOCAL_TYPE)
|
||||
emit_llw(value + elem_offset);
|
||||
else
|
||||
emit_law(value, elem_offset, type);
|
||||
}
|
||||
else if (type & PTR_TYPE)
|
||||
emit_lw();
|
||||
}
|
||||
else
|
||||
if (cparams)
|
||||
emit_pull();
|
||||
emit_ical();
|
||||
}
|
||||
emit_value = 1;
|
||||
type = WORD_TYPE; //(type & ~(FUNC_TYPE | CONST_TYPE)) | WORD_TYPE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (emit_value)
|
||||
@ -611,15 +634,15 @@ int parse_expr()
|
||||
}
|
||||
int parse_stmnt(void)
|
||||
{
|
||||
int tag_prevbrk, tag_else, tag_endif, tag_while, tag_wend, tag_repeat, tag_for, tag_choice, type, addr, step;
|
||||
int tag_prevbrk, tag_else, tag_endif, tag_while, tag_wend, tag_repeat, tag_for, tag_choice, tag_of;
|
||||
int type, addr, step;
|
||||
char *idptr;
|
||||
|
||||
/*
|
||||
* Optimization for last function LEAVE
|
||||
* Optimization for last function LEAVE and OF clause.
|
||||
*/
|
||||
if (scantoken != END_TOKEN && scantoken != DONE_TOKEN)
|
||||
if (scantoken != END_TOKEN && scantoken != DONE_TOKEN && scantoken != OF_TOKEN && scantoken != DEFAULT_TOKEN)
|
||||
prevstmnt = scantoken;
|
||||
|
||||
switch (scantoken)
|
||||
{
|
||||
case IF_TOKEN:
|
||||
@ -779,6 +802,7 @@ int parse_stmnt(void)
|
||||
tag_prevbrk = break_tag;
|
||||
break_tag = tag_new(BRANCH_TYPE);
|
||||
tag_choice = tag_new(BRANCH_TYPE);
|
||||
tag_of = tag_new(BRANCH_TYPE);
|
||||
if (!parse_expr())
|
||||
{
|
||||
parse_error("Bad CASE expression");
|
||||
@ -795,13 +819,18 @@ int parse_stmnt(void)
|
||||
return (0);
|
||||
}
|
||||
emit_brne(tag_choice);
|
||||
emit_codetag(tag_of);
|
||||
while (parse_stmnt()) next_line();
|
||||
emit_brnch(break_tag);
|
||||
tag_of = tag_new(BRANCH_TYPE);
|
||||
if (prevstmnt != BREAK_TOKEN) // Fall through to next OF if no break
|
||||
emit_brnch(tag_of);
|
||||
emit_codetag(tag_choice);
|
||||
tag_choice = tag_new(BRANCH_TYPE);
|
||||
}
|
||||
else if (scantoken == DEFAULT_TOKEN)
|
||||
{
|
||||
emit_codetag(tag_of);
|
||||
tag_of = 0;
|
||||
scan();
|
||||
while (parse_stmnt()) next_line();
|
||||
if (scantoken != ENDCASE_TOKEN)
|
||||
@ -816,6 +845,8 @@ int parse_stmnt(void)
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
if (tag_of)
|
||||
emit_codetag(tag_of);
|
||||
emit_codetag(break_tag);
|
||||
emit_drop();
|
||||
break_tag = tag_prevbrk;
|
||||
|
@ -630,16 +630,16 @@ LNOT1 EOR #$FF
|
||||
;*
|
||||
;* LOGICAL AND
|
||||
;*
|
||||
LAND LDA ESTKL,X
|
||||
ORA ESTKH,X
|
||||
BEQ LAND1
|
||||
LDA ESTKL+1,X
|
||||
LAND LDA ESTKL+1,X
|
||||
ORA ESTKH+1,X
|
||||
BEQ LAND2
|
||||
LDA ESTKL,X
|
||||
ORA ESTKH,X
|
||||
BEQ LAND1
|
||||
LDA #$FF
|
||||
LAND1 STA ESTKL+1,X
|
||||
STA ESTKH+1,X
|
||||
INX
|
||||
LAND2 INX
|
||||
JMP NEXTOP
|
||||
;*
|
||||
;* LOGICAL OR
|
||||
@ -650,9 +650,9 @@ LOR LDA ESTKL,X
|
||||
ORA ESTKH+1,X
|
||||
BEQ LOR1
|
||||
LDA #$FF
|
||||
LOR1 STA ESTKL+1,X
|
||||
STA ESTKL+1,X
|
||||
STA ESTKH+1,X
|
||||
INX
|
||||
LOR1 INX
|
||||
JMP NEXTOP
|
||||
;*
|
||||
;* SWAP TOS WITH TOS-1
|
||||
|
@ -17,6 +17,7 @@ byte a2e[] = "//e"
|
||||
byte a2c[] = "//c"
|
||||
byte a3[] = "///"
|
||||
word struct[] = 1, 10, 100, 1000, 10000
|
||||
word ptr
|
||||
byte spaces[] = " "
|
||||
|
||||
;
|
||||
@ -61,21 +62,36 @@ export def main(range)
|
||||
when MACHID & $C8
|
||||
is $08
|
||||
puts(@a1)
|
||||
break
|
||||
is $00
|
||||
puts(@a2)
|
||||
break
|
||||
is $40
|
||||
puts(@a2p)
|
||||
break
|
||||
is $80
|
||||
puts(@a2e)
|
||||
break
|
||||
is $88
|
||||
puts(@a2c)
|
||||
break
|
||||
is $C0
|
||||
puts(@a3)
|
||||
break
|
||||
otherwise
|
||||
putc('?')
|
||||
wend
|
||||
putln
|
||||
end
|
||||
|
||||
ptr=@struct
|
||||
main(@struct:6)
|
||||
puti((ptr):6)
|
||||
putln
|
||||
puti(ptr=>6)
|
||||
putln
|
||||
puti((ptr).6)
|
||||
putln
|
||||
puti(ptr->6)
|
||||
putln
|
||||
done
|
||||
|
@ -85,6 +85,8 @@
|
||||
#define DEC_TOKEN TOKEN('K')
|
||||
#define BPTR_TOKEN TOKEN('^')
|
||||
#define WPTR_TOKEN TOKEN('*')
|
||||
#define PTRB_TOKEN TOKEN('b')
|
||||
#define PTRW_TOKEN TOKEN('w')
|
||||
#define POST_INC_TOKEN TOKEN('p')
|
||||
#define POST_DEC_TOKEN TOKEN('k')
|
||||
#define OPEN_PAREN_TOKEN TOKEN('(')
|
||||
|
Loading…
Reference in New Issue
Block a user