mirror of
https://gitlab.com/jusax23/raspberry-pi-pico-machine-code-emulator.git
synced 2024-11-22 06:36:45 +01:00
Initial Commit
This commit is contained in:
parent
323dff45f4
commit
981b014f37
10 changed files with 1912 additions and 75 deletions
0
.gitignore
vendored
Normal file
0
.gitignore
vendored
Normal file
137
README.md
137
README.md
|
@ -1,92 +1,79 @@
|
||||||
# Raspberry Pi Pico Machine Code Emulator with compiler for LISP
|
# Raspberry Pi Pico Machine Code Emulator with compiler for LISP
|
||||||
|
|
||||||
|
Recently I was wondering if it is possible to run a program from the pico's ram. That's my answer!
|
||||||
|
|
||||||
|
## Try it?
|
||||||
|
|
||||||
## Getting started
|
- Download the git repository.
|
||||||
|
- Flash pico.ino with the arduino ide.
|
||||||
|
- Write a program with my LISP Syntax
|
||||||
|
- Compile it with: sh build.sh [lisp-file-input] [assembly-file-output] [hex-file-output]
|
||||||
|
- Copy and Past the Binary in Hex in the Serial Monitor
|
||||||
|
- Type start to run your Program
|
||||||
|
|
||||||
To make it easy for you to get started with GitLab, here's a list of recommended next steps.
|
## Syntax in LISP
|
||||||
|
|
||||||
Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)!
|
### DataTypes
|
||||||
|
|
||||||
## Add your files
|
- uint8
|
||||||
|
- uint16
|
||||||
|
- uint32
|
||||||
|
- int8
|
||||||
|
- int16
|
||||||
|
- int32
|
||||||
|
- float
|
||||||
|
- bool
|
||||||
|
|
||||||
- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files
|
### Calculation
|
||||||
- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command:
|
```lisp
|
||||||
|
(+ a b)
|
||||||
|
(+ a b c) ;...
|
||||||
|
|
||||||
|
(- a b)
|
||||||
|
(- a b c) ;...
|
||||||
|
|
||||||
|
(* a b)
|
||||||
|
(* a b c) ;...
|
||||||
|
|
||||||
|
(/ a b)
|
||||||
|
(/ a b c) ;...
|
||||||
```
|
```
|
||||||
cd existing_repo
|
###print
|
||||||
git remote add origin https://gitlab.com/jusax23/raspberry-pi-pico-machine-code-emulator.git
|
|
||||||
git branch -M main
|
```lisp
|
||||||
git push -uf origin main
|
(print a)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Integrate with your tools
|
###Comparisons and Branches
|
||||||
|
|
||||||
- [ ] [Set up project integrations](https://gitlab.com/jusax23/raspberry-pi-pico-machine-code-emulator/-/settings/integrations)
|
```lisp
|
||||||
|
(< 4 5)
|
||||||
|
(> 5 4)
|
||||||
|
(= 6 6)
|
||||||
|
|
||||||
## Collaborate with your team
|
(if (< 4 5) (print 1) (print 0))
|
||||||
|
;if [condition] [then] [else]
|
||||||
|
```
|
||||||
|
|
||||||
- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/)
|
### Variables
|
||||||
- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html)
|
Define Variables:
|
||||||
- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically)
|
```lisp
|
||||||
- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/)
|
(defvar myvar1:uint32 4)
|
||||||
- [ ] [Automatically merge when pipeline succeeds](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html)
|
(defvar myvar2:float (+ 5 1.5))
|
||||||
|
```
|
||||||
|
Set Variables:
|
||||||
|
```lisp
|
||||||
|
(let myvar1 4)
|
||||||
|
(let myvar2 (+ 5 1))
|
||||||
|
```
|
||||||
|
|
||||||
## Test and Deploy
|
###Functions
|
||||||
|
Define and call Functions:
|
||||||
|
|
||||||
Use the built-in continuous integration in GitLab.
|
```lisp
|
||||||
|
(defun faculty:uint32 (input:uint32)
|
||||||
- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html)
|
(print input)
|
||||||
- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing(SAST)](https://docs.gitlab.com/ee/user/application_security/sast/)
|
(if (< in 2) 1 (* input (faculty (- input 1))))
|
||||||
- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html)
|
)
|
||||||
- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/)
|
(print (faculty 10))
|
||||||
- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html)
|
```
|
||||||
|
|
||||||
***
|
|
||||||
|
|
||||||
# Editing this README
|
|
||||||
|
|
||||||
When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thank you to [makeareadme.com](https://www.makeareadme.com/) for this template.
|
|
||||||
|
|
||||||
## Suggestions for a good README
|
|
||||||
Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information.
|
|
||||||
|
|
||||||
## Name
|
|
||||||
Choose a self-explaining name for your project.
|
|
||||||
|
|
||||||
## Description
|
|
||||||
Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors.
|
|
||||||
|
|
||||||
## Badges
|
|
||||||
On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge.
|
|
||||||
|
|
||||||
## Visuals
|
|
||||||
Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method.
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection.
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README.
|
|
||||||
|
|
||||||
## Support
|
|
||||||
Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc.
|
|
||||||
|
|
||||||
## Roadmap
|
|
||||||
If you have ideas for releases in the future, it is a good idea to list them in the README.
|
|
||||||
|
|
||||||
## Contributing
|
|
||||||
State if you are open to contributions and what your requirements are for accepting them.
|
|
||||||
|
|
||||||
For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self.
|
|
||||||
|
|
||||||
You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser.
|
|
||||||
|
|
||||||
## Authors and acknowledgment
|
|
||||||
Show your appreciation to those who have contributed to the project.
|
|
||||||
|
|
||||||
## License
|
|
||||||
For open source projects, say how it is licensed.
|
|
||||||
|
|
||||||
## Project status
|
|
||||||
If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers.
|
|
||||||
|
|
11
compiler/build.sh
Normal file
11
compiler/build.sh
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]
|
||||||
|
then
|
||||||
|
echo "Use command with folloing Arguments: sh build.sh [lisp-file-input] [assembly-file-output] [hex-file-output]"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Compiling to Assembly: "
|
||||||
|
node tools/lispToAs.js $1 $2 || exit 1
|
||||||
|
echo "Compiling to Binary: "
|
||||||
|
node tools/asToBinary.js $2 $3 || exit 1
|
||||||
|
echo "done"
|
129
compiler/output/faculty.as
Normal file
129
compiler/output/faculty.as
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
|
||||||
|
arg0 = 0;4
|
||||||
|
return2 = 4;4
|
||||||
|
SHS 8
|
||||||
|
;code
|
||||||
|
|
||||||
|
LIA .faculty
|
||||||
|
|
||||||
|
;print: executing value:
|
||||||
|
|
||||||
|
;1 Argument
|
||||||
|
|
||||||
|
;num: Loading num
|
||||||
|
LIA 10
|
||||||
|
|
||||||
|
STA 4 arg0
|
||||||
|
|
||||||
|
;excute function
|
||||||
|
JSR .faculty
|
||||||
|
;loading return value
|
||||||
|
LDA 4 return2
|
||||||
|
|
||||||
|
;print Value
|
||||||
|
OUT 0
|
||||||
|
|
||||||
|
HLT
|
||||||
|
;functions
|
||||||
|
faculty:
|
||||||
|
|
||||||
|
;function reserve Stackspace
|
||||||
|
|
||||||
|
PSH 4
|
||||||
|
;function place variable pointers
|
||||||
|
arg1 = 0;4
|
||||||
|
|
||||||
|
|
||||||
|
;function copy args
|
||||||
|
LDA 4 arg0
|
||||||
|
STA 20 arg1
|
||||||
|
|
||||||
|
;function code:
|
||||||
|
|
||||||
|
;if: executing value:
|
||||||
|
|
||||||
|
;<: execute first
|
||||||
|
|
||||||
|
;var: load Variable
|
||||||
|
LDA 20 arg1
|
||||||
|
|
||||||
|
PSH 4
|
||||||
|
;<: execute secound
|
||||||
|
|
||||||
|
;num: Loading num
|
||||||
|
LIA 2
|
||||||
|
|
||||||
|
CAB
|
||||||
|
PUL 4
|
||||||
|
CMP 0 0
|
||||||
|
LIA 1
|
||||||
|
JS .endcompare3
|
||||||
|
LIA 0
|
||||||
|
endcompare3:
|
||||||
|
|
||||||
|
;if:
|
||||||
|
LIB 1
|
||||||
|
CMP 0 0
|
||||||
|
JNE .else4
|
||||||
|
;then code
|
||||||
|
|
||||||
|
;num: Loading num
|
||||||
|
LIA 1
|
||||||
|
|
||||||
|
JMP .afterif4
|
||||||
|
else4:
|
||||||
|
;else code
|
||||||
|
|
||||||
|
;*: next value
|
||||||
|
|
||||||
|
;var: load Variable
|
||||||
|
LDA 20 arg1
|
||||||
|
|
||||||
|
|
||||||
|
PSH 4
|
||||||
|
|
||||||
|
;*: next value
|
||||||
|
|
||||||
|
;1 Argument
|
||||||
|
|
||||||
|
;-: next value
|
||||||
|
|
||||||
|
;num: Loading num
|
||||||
|
LIA 1
|
||||||
|
|
||||||
|
|
||||||
|
PSH 4
|
||||||
|
|
||||||
|
;-: next value
|
||||||
|
|
||||||
|
;var: load Variable
|
||||||
|
LDA 20 arg1
|
||||||
|
|
||||||
|
|
||||||
|
;-: Pull/Add next
|
||||||
|
CAC
|
||||||
|
PUL 4
|
||||||
|
CAB
|
||||||
|
CCA
|
||||||
|
SUB 0 0 0
|
||||||
|
|
||||||
|
STA 4 arg0
|
||||||
|
|
||||||
|
;excute function
|
||||||
|
JSR .faculty
|
||||||
|
;loading return value
|
||||||
|
LDA 4 return2
|
||||||
|
|
||||||
|
|
||||||
|
;*: Pull/Add next
|
||||||
|
CAB
|
||||||
|
PUL 4
|
||||||
|
MUL 0 0 0
|
||||||
|
|
||||||
|
afterif4:
|
||||||
|
|
||||||
|
;return from subrutine
|
||||||
|
STA 4 return2
|
||||||
|
RSR
|
||||||
|
|
||||||
|
|
1
compiler/output/faculty.b16
Normal file
1
compiler/output/faculty.b16
Normal file
|
@ -0,0 +1 @@
|
||||||
|
fe00080f0000001b0f0000000a080400003b001b01040004fd00ff390401040000081400000114000039040f00000002133a043100000f000000013700430f0000000010000000013100003400560f000000013200820114000039040f00000001390401140000163a04131523000000080400003b001b01040004133a0424000000080400043d
|
25
compiler/package.json
Normal file
25
compiler/package.json
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"name": "compiler",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://gitlab.com/jusax23/raspberry-pi-pico-machine-code-emulator.git"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"raspberry",
|
||||||
|
"pi",
|
||||||
|
"pico"
|
||||||
|
],
|
||||||
|
"type":"module",
|
||||||
|
"author": "jusax23",
|
||||||
|
"license": "ISC",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://gitlab.com/jusax23/raspberry-pi-pico-machine-code-emulator/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://gitlab.com/jusax23/raspberry-pi-pico-machine-code-emulator#readme"
|
||||||
|
}
|
4
compiler/scripts/faculty.lisp
Normal file
4
compiler/scripts/faculty.lisp
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
(defun faculty:uint32 (input:uint32)
|
||||||
|
(if (< input 2) 1 (* input (faculty (- input 1))))
|
||||||
|
)
|
||||||
|
(print (faculty 10))
|
184
compiler/tools/asToBinary.js
Normal file
184
compiler/tools/asToBinary.js
Normal file
|
@ -0,0 +1,184 @@
|
||||||
|
import * as fs from "fs";
|
||||||
|
|
||||||
|
const shema = {
|
||||||
|
NOP:{c:0,l:[]},
|
||||||
|
LDA:{c:1,l:[1,2]},
|
||||||
|
LDB:{c:2,l:[1,2]},
|
||||||
|
LDC:{c:3,l:[1,2]},
|
||||||
|
LDX:{c:4,l:[1,2]},
|
||||||
|
|
||||||
|
LOA:{c:5,l:[1,2]},
|
||||||
|
LOB:{c:6,l:[1,2]},
|
||||||
|
LOC:{c:7,l:[1,2]},
|
||||||
|
|
||||||
|
STA:{c:8,l:[1,2]},
|
||||||
|
STB:{c:9,l:[1,2]},
|
||||||
|
STC:{c:10,l:[1,2]},
|
||||||
|
STX:{c:11,l:[1,2]},
|
||||||
|
|
||||||
|
SOA:{c:12,l:[1,2]},
|
||||||
|
SOB:{c:13,l:[1,2]},
|
||||||
|
SOC:{c:14,l:[1,2]},
|
||||||
|
|
||||||
|
LIA:{c:15,l:[4]},
|
||||||
|
LIB:{c:16,l:[4]},
|
||||||
|
LIC:{c:17,l:[4]},
|
||||||
|
LIX:{c:18,l:[4]},
|
||||||
|
|
||||||
|
CAB:{c:19,l:[]},
|
||||||
|
CBC:{c:20,l:[]},
|
||||||
|
CCA:{c:21,l:[]},
|
||||||
|
CAC:{c:22,l:[]},
|
||||||
|
CCB:{c:23,l:[]},
|
||||||
|
CBA:{c:24,l:[]},
|
||||||
|
|
||||||
|
CAX:{c:25,l:[]},
|
||||||
|
CBX:{c:26,l:[]},
|
||||||
|
CCX:{c:27,l:[]},
|
||||||
|
CXA:{c:28,l:[]},
|
||||||
|
CXB:{c:29,l:[]},
|
||||||
|
CXC:{c:30,l:[]},
|
||||||
|
|
||||||
|
CVA:{c:31,l:[1,1]},
|
||||||
|
CVB:{c:32,l:[1,1]},
|
||||||
|
CVC:{c:33,l:[1,1]},
|
||||||
|
|
||||||
|
ADD:{c:34,l:[1,1,1]},
|
||||||
|
SUB:{c:35,l:[1,1,1]},
|
||||||
|
MUL:{c:36,l:[1,1,1]},
|
||||||
|
DIV:{c:37,l:[1,1,1]},
|
||||||
|
MOD:{c:38,l:[1,1,1]},
|
||||||
|
|
||||||
|
POW:{c:39,l:[1,1,1]},
|
||||||
|
ROT:{c:40,l:[1,1,1]},
|
||||||
|
LOG:{c:41,l:[1,1]},
|
||||||
|
|
||||||
|
SR:{c:42,l:[]},
|
||||||
|
SL:{c:43,l:[]},
|
||||||
|
|
||||||
|
INC:{c:44,l:[1]},
|
||||||
|
DEC:{c:45,l:[1]},
|
||||||
|
|
||||||
|
BWO:{c:46,l:[]},
|
||||||
|
BWA:{c:47,l:[]},
|
||||||
|
BWX:{c:48,l:[]},
|
||||||
|
|
||||||
|
CMP:{c:49,l:[1,1]},
|
||||||
|
JMP:{c:50,l:[2]},
|
||||||
|
JE: {c:51,l:[2]},
|
||||||
|
JNE:{c:52,l:[2]},
|
||||||
|
JB: {c:53,l:[2]},
|
||||||
|
JNB:{c:54,l:[2]},
|
||||||
|
JS: {c:55,l:[2]},
|
||||||
|
JNS:{c:56,l:[2]},
|
||||||
|
|
||||||
|
PSH:{c:57,l:[1]},
|
||||||
|
PUL:{c:58,l:[1]},
|
||||||
|
JSR:{c:59,l:[2]},
|
||||||
|
JSA:{c:60,l:[]},
|
||||||
|
RSR:{c:61,l:[]},
|
||||||
|
|
||||||
|
IN :{c:252,l:[]},
|
||||||
|
OUT:{c:253,l:[1]},
|
||||||
|
SHS:{c:254,l:[2]},
|
||||||
|
HLT:{c:255,l:[]},
|
||||||
|
};
|
||||||
|
|
||||||
|
var path = process.argv[2];
|
||||||
|
var pathout = process.argv[3];
|
||||||
|
if(!path||!pathout){
|
||||||
|
console.log("PLease this Schema: node compile.js [path] [pathout]");
|
||||||
|
process.exit();
|
||||||
|
}
|
||||||
|
var file = fs.readFileSync(path).toString().split("\n");
|
||||||
|
|
||||||
|
var s1 = [];
|
||||||
|
var vars = {};
|
||||||
|
var label = false;
|
||||||
|
|
||||||
|
file.forEach((dd, i) => {
|
||||||
|
let d = dd.split(";")[0].trim();
|
||||||
|
if(d.length == 0) return;
|
||||||
|
if(d.endsWith(":")){
|
||||||
|
label = d.replace(":","");
|
||||||
|
}else if(d.includes("=")){
|
||||||
|
var line = d.split("=");
|
||||||
|
vars[line[0].trim()] = Number(line[1].trim());
|
||||||
|
}else{
|
||||||
|
var line = d.replace(/ +(?= )/g,'').split(" ");
|
||||||
|
var base = {d:line.splice(1)};
|
||||||
|
if(label){
|
||||||
|
base.label = label;
|
||||||
|
label = false;
|
||||||
|
}
|
||||||
|
var shem = shema[line[0]];
|
||||||
|
if(!shem){
|
||||||
|
console.log("Cout not parse command:",line[0]);
|
||||||
|
process.exit();
|
||||||
|
}
|
||||||
|
s1.push(Object.assign(base,shem));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function findLabel(l){
|
||||||
|
var count = 0;
|
||||||
|
for (var i = 0; i < s1.length; i++) {
|
||||||
|
if(s1[i].label==l)return count;
|
||||||
|
count += 1;
|
||||||
|
s1[i].l.forEach((item, i) => {
|
||||||
|
count += item;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
console.log("Cout not pase label:",l);
|
||||||
|
process.exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
s1.forEach((d, i) => {
|
||||||
|
|
||||||
|
if(d.d.length){
|
||||||
|
d.d = d.d.map(e=>{
|
||||||
|
if (e.startsWith(".")){
|
||||||
|
return findLabel(e.substr(1));
|
||||||
|
}else if(!isNaN(e)){
|
||||||
|
var n = Number(e);
|
||||||
|
if(Number.isInteger(n)){
|
||||||
|
if(n>=0){
|
||||||
|
return n;
|
||||||
|
}else{
|
||||||
|
var buf = new ArrayBuffer(4);
|
||||||
|
(new Int32Array(buf))[0] = n;
|
||||||
|
return (new Uint32Array(buf))[0];
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
var buf = new ArrayBuffer(4);
|
||||||
|
(new Float32Array(buf))[0] = n;
|
||||||
|
return (new Uint32Array(buf))[0];
|
||||||
|
}
|
||||||
|
}else if(e=="NaN"){
|
||||||
|
return 2143289344;
|
||||||
|
}else if(typeof vars[e] == "number"){
|
||||||
|
return vars[e];
|
||||||
|
}else{
|
||||||
|
console.log("Cout not parse:", e);
|
||||||
|
process.exit();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var s2 = [];
|
||||||
|
s1.forEach((d, i) => {
|
||||||
|
s2.push(d.c);
|
||||||
|
d.l.forEach((item, i) => {
|
||||||
|
for (var j = item-1; j >= 0; j--) {
|
||||||
|
s2.push(((d.d[i]??0)>>(8*j))&0xff);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
var finish = s2.map(d=>d.toString(16).padStart(2,"0")).join("");
|
||||||
|
fs.writeFileSync(pathout,finish);
|
||||||
|
console.log(`Finished converting in ${Math.round(performance.now())/1000}sec. The Size is: ${s2.length}byts. Binary in HEX saved to: ${pathout}`);
|
652
compiler/tools/lispToAs.js
Normal file
652
compiler/tools/lispToAs.js
Normal file
|
@ -0,0 +1,652 @@
|
||||||
|
import * as fs from "fs";
|
||||||
|
var path = process.argv[2];
|
||||||
|
var pathout = process.argv[3];
|
||||||
|
if(!path||!pathout){
|
||||||
|
console.log("PLease this Schema: node ToAs.js [path] [pathout]");
|
||||||
|
process.exit();
|
||||||
|
}
|
||||||
|
var file = fs.readFileSync(path).toString();
|
||||||
|
|
||||||
|
function error(msg,l=null,c=null){
|
||||||
|
var out = "Error"
|
||||||
|
if(l!=null&&c!=null)out+=` in line ${l} and character ${c}`;
|
||||||
|
out+=": "+msg;
|
||||||
|
console.log("\x1b[31m",out,"\x1b[0m");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
function cutCmd(code,line,chars){
|
||||||
|
if(!code.startsWith("("))return ["",error("Compiler Error",line,chars)];
|
||||||
|
|
||||||
|
if(!code.endsWith(")"))return ["",error("Compiler Error",line,chars)];
|
||||||
|
|
||||||
|
code = code.substring(1,code.length-1);
|
||||||
|
|
||||||
|
var countLinesBegin = line;
|
||||||
|
var countCharsBegin = chars;
|
||||||
|
|
||||||
|
var countLines = line;
|
||||||
|
var countChars = chars;
|
||||||
|
var inC = 0;
|
||||||
|
var wasinC = false;
|
||||||
|
var inStr = 0;
|
||||||
|
var buffer = "";
|
||||||
|
var i = 0;
|
||||||
|
var out = [];
|
||||||
|
|
||||||
|
function finishBuff(){
|
||||||
|
out.push(
|
||||||
|
wasinC?
|
||||||
|
new LISPcmd(buffer.trim(),countLinesBegin,countCharsBegin)
|
||||||
|
:
|
||||||
|
new LISPstring(buffer.trim(),countLinesBegin,countCharsBegin)
|
||||||
|
);
|
||||||
|
countLinesBegin = countLines;
|
||||||
|
countCharsBegin = countChars;
|
||||||
|
buffer = "";
|
||||||
|
wasinC = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < code.length; i++) {
|
||||||
|
|
||||||
|
countChars++;
|
||||||
|
//console.log(code,countLines,countChars);
|
||||||
|
let c = code[i];
|
||||||
|
if(!inC&&!inStr){
|
||||||
|
countLinesBegin = countLines;
|
||||||
|
countCharsBegin = countChars;
|
||||||
|
}
|
||||||
|
if(c=="\\"){
|
||||||
|
buffer+=code[++i];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(inStr){
|
||||||
|
if(c=="\n"){
|
||||||
|
countLines++;
|
||||||
|
countChars = 0;
|
||||||
|
}else if(c=='"'){
|
||||||
|
if(!inC)finishBuff();
|
||||||
|
inStr = false;
|
||||||
|
}else{
|
||||||
|
buffer+=c;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(c=='"'){
|
||||||
|
inStr = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(c==";"&&!inC){
|
||||||
|
while(code[++i]!="\n"){}
|
||||||
|
countLines++;
|
||||||
|
countChars = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(c=="\n"){
|
||||||
|
countLines++;
|
||||||
|
countChars = 0;
|
||||||
|
}
|
||||||
|
if((c == " "||c=="\n")&&!inC){
|
||||||
|
if(buffer.trim()!=""){
|
||||||
|
finishBuff();
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(c == "("){
|
||||||
|
if(!inC&&buffer.trim()!=""){
|
||||||
|
finishBuff();
|
||||||
|
}
|
||||||
|
inC++;
|
||||||
|
wasinC = true;
|
||||||
|
}
|
||||||
|
if(c == ")"){
|
||||||
|
inC--;
|
||||||
|
if(inC<0)error("Closing braket to much!",countLines,countChars);
|
||||||
|
if(!inC){
|
||||||
|
buffer+=c;
|
||||||
|
finishBuff();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buffer+=c;
|
||||||
|
|
||||||
|
}
|
||||||
|
if(inStr)error("Missing closing quotation mark!",countLines,countChars);
|
||||||
|
if(inC)error("Missing closing braket!",countLines,countChars);
|
||||||
|
|
||||||
|
if(buffer.trim()!="")finishBuff();
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
class LISPstring extends String {
|
||||||
|
#l;
|
||||||
|
#c;
|
||||||
|
constructor(string,line,char) {
|
||||||
|
super(string);
|
||||||
|
this.#l = line;
|
||||||
|
this.#c = char;
|
||||||
|
}
|
||||||
|
get lineCount(){
|
||||||
|
return this.#l;
|
||||||
|
}
|
||||||
|
get charCount(){
|
||||||
|
return this.#l;
|
||||||
|
}
|
||||||
|
get pos(){
|
||||||
|
return [this.#l,this.#c];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class LISPcmd extends Array {
|
||||||
|
#l;
|
||||||
|
#c;
|
||||||
|
|
||||||
|
constructor(code,line,char) {
|
||||||
|
var childs = cutCmd(code,line,char);
|
||||||
|
|
||||||
|
super(...childs);
|
||||||
|
this.#l = line;
|
||||||
|
this.#c = char;
|
||||||
|
}
|
||||||
|
get lineCount(){
|
||||||
|
return this.#l;
|
||||||
|
}
|
||||||
|
get charCount(){
|
||||||
|
return this.#l;
|
||||||
|
}
|
||||||
|
get pos(){
|
||||||
|
return [this.#l,this.#c];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var data = new LISPcmd("(\n"+file+"\n)",0,0);
|
||||||
|
|
||||||
|
//console.log(JSON.stringify(data));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function getType(data){
|
||||||
|
/*if(data=="empty"){
|
||||||
|
return ["emp", ""];
|
||||||
|
}*/
|
||||||
|
if(data=="true"){
|
||||||
|
return ["bool", 1];
|
||||||
|
}
|
||||||
|
if(data=="false"){
|
||||||
|
return ["bool", 0];
|
||||||
|
}
|
||||||
|
if(data=="NaN"){
|
||||||
|
return ["num", NaN];
|
||||||
|
}
|
||||||
|
/*if(typeof data == "string"&&data.startsWith('"') && data.endsWith('"')){
|
||||||
|
return ["str", data.slice(1,-1)];
|
||||||
|
}*/
|
||||||
|
if((data instanceof LISPstring)&&!isNaN(data)/*!data.match(new RegExp("[^0-9.-e+]","g"))*/){
|
||||||
|
return ["num", Number(data)];
|
||||||
|
}
|
||||||
|
if(data instanceof LISPcmd/*Array.isArray(data)*/){
|
||||||
|
return ["code", data];
|
||||||
|
}
|
||||||
|
return ["var",data];
|
||||||
|
}
|
||||||
|
|
||||||
|
var nid = 0;
|
||||||
|
|
||||||
|
var dataTypes = {
|
||||||
|
uint32: {ptype:0, length:4, mask:null },
|
||||||
|
uint16: {ptype:0, length:2, mask:0xffff },
|
||||||
|
uint8: {ptype:0, length:1, mask:0xff },
|
||||||
|
int32: {ptype:1, length:4, mask:null },
|
||||||
|
int16: {ptype:1, length:2, mask:0xffff },
|
||||||
|
int8: {ptype:1, length:1, mask:0xff },
|
||||||
|
float: {ptype:2, length:4, mask:null },
|
||||||
|
bool: {ptype:0, length:1, mask:1 },
|
||||||
|
};
|
||||||
|
var dataTypesReversed = {
|
||||||
|
0:"uint/bool",
|
||||||
|
1:"int",
|
||||||
|
2:"float"
|
||||||
|
}
|
||||||
|
|
||||||
|
/*var numTypes = ["uint32", "uint16","uint8","int32","int16","int8","float","bool"];*/
|
||||||
|
|
||||||
|
|
||||||
|
function last(d){
|
||||||
|
return d[d.length-1];
|
||||||
|
}
|
||||||
|
function find(d,n){
|
||||||
|
for (var i = d.length-1; i >= 0 ; i--) {
|
||||||
|
if(typeof d[i][n] == "object")return d[i][n];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
function createVars(c){
|
||||||
|
var l = 0;
|
||||||
|
return [Object.entries(c).map(d=>{
|
||||||
|
var out = `${d[1].id} = ${l};${dataTypes[d[1].type].length}`;
|
||||||
|
if(d[1].used==0) return ";"+out;
|
||||||
|
l+=dataTypes[d[1].type].length;
|
||||||
|
return out;
|
||||||
|
}).join("\n"),l];
|
||||||
|
}
|
||||||
|
|
||||||
|
var extrafuns = {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
function execute(data,expect,context,local){
|
||||||
|
var code = "";
|
||||||
|
var ptype = 0;
|
||||||
|
var doconv = true;
|
||||||
|
let [type,d] = getType(data);
|
||||||
|
|
||||||
|
if(type == "code"){
|
||||||
|
if(data[0]=="defvar"){
|
||||||
|
var ctx = last(context);
|
||||||
|
var [vname,vtype] = data[1].split(":");
|
||||||
|
if(ctx[vname])error(`Can not redefine: ${cname}! It is already defined!`,...data.pos);
|
||||||
|
if(!dataTypes[vtype])error(`Unknown Datatype: ${vtype}`,...data.pos);
|
||||||
|
|
||||||
|
let mvar = {type:vtype,used:0,id:"v"+nid++,local:local};
|
||||||
|
ctx["v"+vname] = mvar;
|
||||||
|
let [c,etype] = execute(data[2],mvar.type,context,local);
|
||||||
|
code+= `
|
||||||
|
;defvar: executing value:
|
||||||
|
${c}
|
||||||
|
;defvar: Store Value
|
||||||
|
STA ${dataTypes[mvar.type].length|(mvar.local?0x10:0)} ${mvar.id}
|
||||||
|
`;
|
||||||
|
ptype = dataTypes[mvar.type].ptype;
|
||||||
|
}else if(data[0]=="defun"){
|
||||||
|
var [fname,ftype] = (data[1]??"").split(":");
|
||||||
|
if(local)error(`Nested functions are currently not supported: ${fname}`,...data.pos);
|
||||||
|
if(extrafuns[fname])error(`You can not declare functions double: ${fname}`,...data.pos);
|
||||||
|
if(!dataTypes[ftype])error(`Unknown Datatype: ${ftype}`,...data.pos);
|
||||||
|
var ctx = last(context);
|
||||||
|
var funsCtx = {};
|
||||||
|
var args = [];
|
||||||
|
var lcode = "";
|
||||||
|
data[2].forEach(v=>{
|
||||||
|
var [vname,vtype] = v.split(":");
|
||||||
|
if(funsCtx[vname])error(`You declared the Argument ${vname} in function",fname,"twice!`,...data.pos);
|
||||||
|
if(!dataTypes[vtype])error(`Unknown Datatype: ${vtype}`,...data.pos);
|
||||||
|
var mvarg = {type:vtype,used:1,id:"arg"+nid++,local:false};
|
||||||
|
var mvarl = {type:vtype,used:1,id:"arg"+nid++,local:true};
|
||||||
|
|
||||||
|
funsCtx["v"+vname] = mvarl;
|
||||||
|
args.push(mvarg);
|
||||||
|
ctx["arg_"+vname] = mvarg;
|
||||||
|
lcode+=`
|
||||||
|
;function copy args
|
||||||
|
LDA ${dataTypes[mvarg.type].length} ${mvarg.id}
|
||||||
|
STA ${dataTypes[mvarl.type].length|0x10} ${mvarl.id}
|
||||||
|
`
|
||||||
|
});
|
||||||
|
var mvar = {type:ftype,used:1,id:"return"+nid++,local:false};
|
||||||
|
var fun = {
|
||||||
|
type:ftype,
|
||||||
|
code:"",
|
||||||
|
args,
|
||||||
|
return:mvar
|
||||||
|
};
|
||||||
|
extrafuns[fname] = fun;
|
||||||
|
//execute lcode
|
||||||
|
lcode+="\n;function code:\n";
|
||||||
|
for (var i = 3; i < data.length; i++) {
|
||||||
|
let [c,t] = execute(data[i],data.length-1==i?ftype:"any",[...context,funsCtx],true);
|
||||||
|
lcode+=c;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx["return_"+fname] = mvar;
|
||||||
|
lcode+= `
|
||||||
|
;return from subrutine
|
||||||
|
STA ${dataTypes[mvar.type].length} ${mvar.id}
|
||||||
|
RSR
|
||||||
|
`;
|
||||||
|
let [localvars,localL] = createVars(funsCtx);
|
||||||
|
lcode = `
|
||||||
|
;function reserve Stackspace
|
||||||
|
${(new Array(Math.floor(localL/255))).fill("PSH 255").join("\n ")}
|
||||||
|
${(localL%255>0?`PSH ${localL%255}`:'')}
|
||||||
|
;function place variable pointers
|
||||||
|
${localvars}
|
||||||
|
|
||||||
|
${lcode}
|
||||||
|
`;
|
||||||
|
|
||||||
|
fun.code = lcode;
|
||||||
|
|
||||||
|
code=`
|
||||||
|
LIA .${fname}
|
||||||
|
`;
|
||||||
|
ptype=0;
|
||||||
|
|
||||||
|
}else if(data[0]=="let"){
|
||||||
|
var mvar = find(context,"v"+data[1]);
|
||||||
|
if(mvar == null)error(`Unknown Variable: ${data[1]}`,...data.pos);
|
||||||
|
mvar.used++;
|
||||||
|
let [c,etype] = execute(data[2],mvar.type,context,local);
|
||||||
|
code+= `
|
||||||
|
;let: executing value:
|
||||||
|
${c}
|
||||||
|
;let: Store Value
|
||||||
|
STA ${dataTypes[mvar.type].length|(mvar.local?0x10:0)} ${mvar.id}
|
||||||
|
`;
|
||||||
|
ptype = dataTypes[mvar.type].ptype;
|
||||||
|
}else if(data[0]=="+"){
|
||||||
|
var etypes = [];
|
||||||
|
var etypeMax = 0;
|
||||||
|
for (var i = 1; i < data.length; i++) {
|
||||||
|
let [c,etype] = execute(data[i],"num",context,local);
|
||||||
|
code+=`
|
||||||
|
;+: next value
|
||||||
|
${c}
|
||||||
|
`;
|
||||||
|
if(i<data.length-1){
|
||||||
|
code+=`
|
||||||
|
PSH 4
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
etypes.push(etype);
|
||||||
|
if(etype>etypeMax)etypeMax=etype;
|
||||||
|
}
|
||||||
|
if(etypes[0]!=etypeMax){
|
||||||
|
code+=`
|
||||||
|
;+: converting not matching types
|
||||||
|
CVA ${etypes[0]} ${etypeMax}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
for (var i = 1; i < etypes.length; i++) {
|
||||||
|
code+=`
|
||||||
|
;+: Pull/Add next
|
||||||
|
CAB
|
||||||
|
PUL 4
|
||||||
|
ADD ${etypeMax} ${etypes[i]} ${etypeMax}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
ptype = etypeMax;
|
||||||
|
}else if(data[0]=="-"){
|
||||||
|
var etypes = [];
|
||||||
|
var etypeMax = 0;
|
||||||
|
for (var i = data.length-1; i >=1 ; i--) {
|
||||||
|
let [c,etype] = execute(data[i],"num",context,local);
|
||||||
|
code+=`
|
||||||
|
;-: next value
|
||||||
|
${c}
|
||||||
|
`;
|
||||||
|
if(i>1){
|
||||||
|
code+=`
|
||||||
|
PSH 4
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
etypes.push(etype);
|
||||||
|
if(etype>etypeMax)etypeMax=etype;
|
||||||
|
}
|
||||||
|
if(etypes[0]!=etypeMax){
|
||||||
|
code+=`
|
||||||
|
;-: converting not matching types
|
||||||
|
CVA ${etypes[0]} ${etypeMax}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
for (var i = 1; i < etypes.length; i++) {
|
||||||
|
code+=`
|
||||||
|
;-: Pull/Add next
|
||||||
|
CAC
|
||||||
|
PUL 4
|
||||||
|
CAB
|
||||||
|
CCA
|
||||||
|
SUB ${etypeMax} ${etypes[i]} ${etypeMax}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
ptype = etypeMax;
|
||||||
|
}else if(data[0]=="*"){
|
||||||
|
var etypes = [];
|
||||||
|
var etypeMax = 0;
|
||||||
|
for (var i = 1; i < data.length; i++) {
|
||||||
|
let [c,etype] = execute(data[i],"num",context,local);
|
||||||
|
code+=`
|
||||||
|
;*: next value
|
||||||
|
${c}
|
||||||
|
`;
|
||||||
|
if(i<data.length-1){
|
||||||
|
code+=`
|
||||||
|
PSH 4
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
etypes.push(etype);
|
||||||
|
if(etype>etypeMax)etypeMax=etype;
|
||||||
|
}
|
||||||
|
if(etypes[0]!=etypeMax){
|
||||||
|
code+=`
|
||||||
|
;*: converting not matching types
|
||||||
|
CVA ${etypes[0]} ${etypeMax}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
for (var i = 1; i < etypes.length; i++) {
|
||||||
|
code+=`
|
||||||
|
;*: Pull/Add next
|
||||||
|
CAB
|
||||||
|
PUL 4
|
||||||
|
MUL ${etypeMax} ${etypes[i]} ${etypeMax}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
ptype = etypeMax;
|
||||||
|
}else if(data[0]=="/"){
|
||||||
|
var etypes = [];
|
||||||
|
var etypeMax = 0;
|
||||||
|
for (var i = data.length-1; i >=1 ; i--) {
|
||||||
|
let [c,etype] = execute(data[i],"num",context,local);
|
||||||
|
code+=`
|
||||||
|
;/: next value
|
||||||
|
${c}
|
||||||
|
`;
|
||||||
|
if(i>1){
|
||||||
|
code+=`
|
||||||
|
PSH 4
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
etypes.push(etype);
|
||||||
|
if(etype>etypeMax)etypeMax=etype;
|
||||||
|
}
|
||||||
|
if(etypes[0]!=etypeMax){
|
||||||
|
code+=`
|
||||||
|
;/: converting not matching types
|
||||||
|
CVA ${etypes[0]} ${etypeMax}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
for (var i = 1; i < etypes.length; i++) {
|
||||||
|
code+=`
|
||||||
|
;/: Pull/Add next
|
||||||
|
CAC
|
||||||
|
PUL 4
|
||||||
|
CAB
|
||||||
|
CCA
|
||||||
|
DIV ${etypeMax} ${etypes[i]} ${etypeMax}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
ptype = etypeMax;
|
||||||
|
}else if(data[0]=="print"){
|
||||||
|
let [c,etype] = execute(data[1],"any",context,local);
|
||||||
|
code+=`
|
||||||
|
;print: executing value:
|
||||||
|
${c}
|
||||||
|
;print Value
|
||||||
|
OUT ${etype}
|
||||||
|
`;
|
||||||
|
ptype = etype;
|
||||||
|
}else if(data[0]=="if"){
|
||||||
|
let [c,etype] = execute(data[1],"bool",context,local);
|
||||||
|
let [c1,etype1] = execute(data[2],expect,context,local);
|
||||||
|
let c2,etype2;
|
||||||
|
if(typeof data[3]!="undefined"){
|
||||||
|
[c2,etype2] = execute(data[3],expect,context,local);
|
||||||
|
}else{
|
||||||
|
[c2,etype2] = ["LIA 0",0];
|
||||||
|
}
|
||||||
|
|
||||||
|
var id = nid++;
|
||||||
|
code+=`
|
||||||
|
;if: executing value:
|
||||||
|
${c}
|
||||||
|
;if:
|
||||||
|
LIB 1
|
||||||
|
CMP 0 0
|
||||||
|
JNE .else${id}
|
||||||
|
;then code
|
||||||
|
${c1}
|
||||||
|
JMP .afterif${id}
|
||||||
|
else${id}:
|
||||||
|
;else code
|
||||||
|
${c2}
|
||||||
|
afterif${id}:
|
||||||
|
`;
|
||||||
|
ptype = etype1;
|
||||||
|
}else if(data[0]==">"){
|
||||||
|
let [c1,etype1] = execute(data[1],"num",context,local);
|
||||||
|
let [c2,etype2] = execute(data[2],"num",context,local);
|
||||||
|
doconv = false;
|
||||||
|
var id = nid++;
|
||||||
|
code+=`
|
||||||
|
;>: execute first
|
||||||
|
${c1}
|
||||||
|
PSH 4
|
||||||
|
;>: execute secound
|
||||||
|
${c2}
|
||||||
|
CAB
|
||||||
|
PUL 4
|
||||||
|
CMP ${etype1} ${etype2}
|
||||||
|
LIA 1
|
||||||
|
JB .endcompare${id}
|
||||||
|
LIA 0
|
||||||
|
endcompare${id}:
|
||||||
|
`;
|
||||||
|
}else if(data[0]=="<"){
|
||||||
|
let [c1,etype1] = execute(data[1],"num",context,local);
|
||||||
|
let [c2,etype2] = execute(data[2],"num",context,local);
|
||||||
|
doconv = false;
|
||||||
|
var id = nid++;
|
||||||
|
code+=`
|
||||||
|
;<: execute first
|
||||||
|
${c1}
|
||||||
|
PSH 4
|
||||||
|
;<: execute secound
|
||||||
|
${c2}
|
||||||
|
CAB
|
||||||
|
PUL 4
|
||||||
|
CMP ${etype1} ${etype2}
|
||||||
|
LIA 1
|
||||||
|
JS .endcompare${id}
|
||||||
|
LIA 0
|
||||||
|
endcompare${id}:
|
||||||
|
`;
|
||||||
|
}else if(data[0]=="="){
|
||||||
|
let [c1,etype1] = execute(data[1],"num",context,local);
|
||||||
|
let [c2,etype2] = execute(data[2],"num",context,local);
|
||||||
|
doconv = false;
|
||||||
|
var id = nid++;
|
||||||
|
code+=`
|
||||||
|
;>: execute first
|
||||||
|
${c1}
|
||||||
|
PSH 4
|
||||||
|
;>: execute secound
|
||||||
|
${c2}
|
||||||
|
CAB
|
||||||
|
PUL 4
|
||||||
|
CMP ${etype1} ${etype2}
|
||||||
|
LIA 1
|
||||||
|
JE .endcompare${id}
|
||||||
|
LIA 0
|
||||||
|
endcompare${id}:
|
||||||
|
`;
|
||||||
|
}else{
|
||||||
|
if(extrafuns[data[0]]){
|
||||||
|
var fun = extrafuns[data[0]];
|
||||||
|
for (var i = 0; i < fun.args.length; i++) {
|
||||||
|
if(typeof data[i+1] == "undefined")error(`Argument missing for function ${data[0]}`,...data.pos);
|
||||||
|
var [ecode,etype] = execute(data[i+1],fun.args[i].type,context,local);
|
||||||
|
code+=`
|
||||||
|
;${i+1} Argument
|
||||||
|
${ecode}
|
||||||
|
STA ${dataTypes[fun.args[i].type].length} ${fun.args[i].id}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
code+=`
|
||||||
|
;excute function
|
||||||
|
JSR .${data[0]}
|
||||||
|
;loading return value
|
||||||
|
LDA ${dataTypes[fun.return.type].length} ${fun.return.id}
|
||||||
|
`;
|
||||||
|
ptype = dataTypes[fun.return.type].ptype;
|
||||||
|
}else{
|
||||||
|
error(`Unknown command: ${data[0]}`,...data.pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else if(type == "var"){
|
||||||
|
let mvar = find(context,"v"+d);
|
||||||
|
if(mvar == null)error(`Unknown Variable/Expression: ${d}`,...data.pos);
|
||||||
|
mvar.used++;
|
||||||
|
code += `
|
||||||
|
;var: load Variable
|
||||||
|
LDA ${dataTypes[mvar.type].length|(mvar.local?0x10:0)} ${mvar.id}
|
||||||
|
`;
|
||||||
|
ptype = dataTypes[mvar.type].ptype;
|
||||||
|
}else if(type == "num"||type=="bool"){
|
||||||
|
ptype = Number.isInteger(d)?(d>=0?0:1):2;
|
||||||
|
if(dataTypes[expect]?.ptype == ptype){
|
||||||
|
code += `
|
||||||
|
;num: Loading num
|
||||||
|
LIA ${dataTypes[expect].mask==null?d:dataTypes[expect].ptype&d}
|
||||||
|
`;
|
||||||
|
doconv = false;
|
||||||
|
}else{
|
||||||
|
code += `
|
||||||
|
;num: Loading num
|
||||||
|
LIA ${d}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
}else{
|
||||||
|
error(`Not Supported execution type: ${type} of ${d}`,...data.pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(expect=="any")return [code,ptype];
|
||||||
|
if(expect=="num"){
|
||||||
|
if(ptype==0||ptype==1||ptype==2){
|
||||||
|
return [code,ptype];
|
||||||
|
}else{
|
||||||
|
error(`Can not convert ${dataTypesReversed[ptype]} to Number`,...data.pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(ptype!=dataTypes[expect].ptype){
|
||||||
|
code+=`
|
||||||
|
CVA ${ptype} ${dataTypes[expect].ptype}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
if(doconv&&dataTypes[expect].mask != null){
|
||||||
|
code+=`
|
||||||
|
LIB ${dataTypes[expect].mask}
|
||||||
|
BWA
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
return [code,dataTypes[expect].ptype];
|
||||||
|
|
||||||
|
}
|
||||||
|
var code = "";
|
||||||
|
var context = [{}];
|
||||||
|
for (var i = 0; i < data.length; i++) {
|
||||||
|
let [c,t] = execute(data[i],"any",context);
|
||||||
|
code += c;
|
||||||
|
//console.log(c);
|
||||||
|
}
|
||||||
|
var [globvars,globL] = createVars(context[0]);
|
||||||
|
var finish = `
|
||||||
|
${globvars}
|
||||||
|
SHS ${globL}
|
||||||
|
;code
|
||||||
|
${code}
|
||||||
|
HLT
|
||||||
|
;functions
|
||||||
|
${Object.entries(extrafuns).map(d=>d[0]+":\n"+d[1].code).join("\n\n")}
|
||||||
|
`;
|
||||||
|
fs.writeFileSync(pathout,finish);
|
||||||
|
console.log(`Finished compiling in ${Math.round(performance.now())/1000}sec. Assembly saved to: ${pathout}`);
|
844
pico/pico.ino
Normal file
844
pico/pico.ino
Normal file
|
@ -0,0 +1,844 @@
|
||||||
|
#define pram_length 65536
|
||||||
|
#define program_length 65536
|
||||||
|
|
||||||
|
//#define s_debug
|
||||||
|
|
||||||
|
byte pram[pram_length];
|
||||||
|
byte prog[program_length];
|
||||||
|
|
||||||
|
uint16_t pcounter = 0;
|
||||||
|
uint16_t pstackpointer = pram_length-1;
|
||||||
|
uint16_t pframepointer = pram_length-1;
|
||||||
|
uint16_t pstackmax = pram_length*0.5;
|
||||||
|
|
||||||
|
uint32_t AReg;
|
||||||
|
uint32_t BReg;
|
||||||
|
uint32_t CReg;
|
||||||
|
|
||||||
|
uint32_t XReg;
|
||||||
|
|
||||||
|
bool equalFlag;
|
||||||
|
bool biggerFlag;
|
||||||
|
bool smalerFlag;
|
||||||
|
|
||||||
|
bool doExecute = false;
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
pinMode(25, OUTPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
String b16 = "0123456789abcdef";
|
||||||
|
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
while (true){
|
||||||
|
while(Serial.available()){
|
||||||
|
String c = Serial.readStringUntil('\n');
|
||||||
|
if (c == "start")doExecute = true;
|
||||||
|
else if (c == "stop")doExecute = false;
|
||||||
|
else if (c == "test"){
|
||||||
|
for(int i = 0; i < 115; i++) {
|
||||||
|
Serial.println(prog[i]);
|
||||||
|
}
|
||||||
|
Serial.println(pcounter);
|
||||||
|
}
|
||||||
|
else if (c == "clear"){
|
||||||
|
pcounter = 0;
|
||||||
|
pstackpointer = pram_length-1;
|
||||||
|
pstackmax = pram_length*0.5;
|
||||||
|
AReg = 0;
|
||||||
|
BReg = 0;
|
||||||
|
CReg = 0;
|
||||||
|
XReg = 0;
|
||||||
|
equalFlag = false;
|
||||||
|
biggerFlag = false;
|
||||||
|
smalerFlag = false;
|
||||||
|
for (int i = 0; i < pram_length; i++) {
|
||||||
|
pram[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
for (int i = 0; i < c.length()-1; i=i+2) {
|
||||||
|
prog[i/2] = b16.indexOf(c[i])*16+b16.indexOf(c[i+1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(doExecute){
|
||||||
|
digitalWrite(25, true);
|
||||||
|
#ifdef s_debug
|
||||||
|
Serial.print("Line: ");
|
||||||
|
Serial.print(pcounter);
|
||||||
|
Serial.print(" > ");
|
||||||
|
Serial.print(prog[pcounter]);
|
||||||
|
Serial.print(" > ");
|
||||||
|
Serial.print(pram[65528]);
|
||||||
|
Serial.print(" > ");
|
||||||
|
Serial.print(pstackpointer);
|
||||||
|
Serial.println(" ... ");
|
||||||
|
#endif
|
||||||
|
execute();
|
||||||
|
#ifdef s_debug
|
||||||
|
Serial.print(" ... ");
|
||||||
|
Serial.print(pram[65528]);
|
||||||
|
Serial.print(" > ");
|
||||||
|
Serial.println("done");
|
||||||
|
#endif
|
||||||
|
}else{
|
||||||
|
digitalWrite(25, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//delay(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void execute(){
|
||||||
|
byte cmd = prog[pcounter++];
|
||||||
|
switch ((int)cmd){
|
||||||
|
case 0:{
|
||||||
|
__asm__("nop");
|
||||||
|
}break;
|
||||||
|
case 1:{ // LDA
|
||||||
|
byte s = prog[pcounter++];
|
||||||
|
byte n = min(s&0xf,4);
|
||||||
|
unsigned short data = prog[pcounter++]<<8;
|
||||||
|
data += prog[pcounter++];
|
||||||
|
unsigned short addr = ((s&0xf0)!=0)?max(pframepointer+1-data-n,pstackpointer):data;
|
||||||
|
/*Serial.print("LDA");
|
||||||
|
Serial.print(s);
|
||||||
|
Serial.print(">");
|
||||||
|
Serial.print(s&0xf0);
|
||||||
|
Serial.print(">");
|
||||||
|
Serial.print((s&0xf0)!=0);
|
||||||
|
Serial.print(">");
|
||||||
|
Serial.print(max(pframepointer+1-data-n,pstackpointer));
|
||||||
|
Serial.print(">");
|
||||||
|
Serial.print(pframepointer-data-n);
|
||||||
|
Serial.print(">");
|
||||||
|
Serial.println(addr);*/
|
||||||
|
AReg = 0;
|
||||||
|
for (byte i = 0; i < n; i++) {
|
||||||
|
AReg += pram[addr+i]<<(i*8);
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
case 2:{ // LDB
|
||||||
|
byte n = min(prog[pcounter++],4);
|
||||||
|
unsigned short data = prog[pcounter++]<<8;
|
||||||
|
data += prog[pcounter++];
|
||||||
|
BReg = 0;
|
||||||
|
for (byte i = 0; i < n; i++) {
|
||||||
|
BReg += pram[data+i]<<(i*8);
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
case 3:{ // LDC
|
||||||
|
byte n = min(prog[pcounter++],4);
|
||||||
|
unsigned short data = prog[pcounter++]<<8;
|
||||||
|
data += prog[pcounter++];
|
||||||
|
CReg = 0;
|
||||||
|
for (byte i = 0; i < n; i++) {
|
||||||
|
CReg += pram[data+i]<<(i*8);
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
case 4:{ // LDX
|
||||||
|
byte n = min(prog[pcounter++],4);
|
||||||
|
unsigned short data = prog[pcounter++]<<8;
|
||||||
|
data += prog[pcounter++];
|
||||||
|
XReg = 0;
|
||||||
|
for (byte i = 0; i < n; i++) {
|
||||||
|
XReg += pram[data+i]<<(i*8);
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case 5:{ // LOA
|
||||||
|
byte n = min(prog[pcounter++],4);
|
||||||
|
unsigned short data = prog[pcounter++]<<8;
|
||||||
|
data += prog[pcounter++];
|
||||||
|
data += XReg*n;
|
||||||
|
AReg = 0;
|
||||||
|
for (byte i = 0; i < n; i++) {
|
||||||
|
AReg += pram[data+i]<<(i*8);
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
case 6:{ // LOB
|
||||||
|
byte n = min(prog[pcounter++],4);
|
||||||
|
unsigned short data = prog[pcounter++]<<8;
|
||||||
|
data += prog[pcounter++];
|
||||||
|
data += XReg*n;
|
||||||
|
BReg = 0;
|
||||||
|
for (byte i = 0; i < n; i++) {
|
||||||
|
BReg += pram[data+i]<<(i*8);
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
case 7:{ // LOC
|
||||||
|
byte n = min(prog[pcounter++],4);
|
||||||
|
unsigned short data = prog[pcounter++]<<8;
|
||||||
|
data += prog[pcounter++];
|
||||||
|
data += XReg*n;
|
||||||
|
CReg = 0;
|
||||||
|
for (byte i = 0; i < n; i++) {
|
||||||
|
CReg += pram[data+i]<<(i*8);
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case 8:{ // STA
|
||||||
|
byte s = prog[pcounter++];
|
||||||
|
byte n = min(s&0xf,4);
|
||||||
|
unsigned short data = prog[pcounter++]<<8;
|
||||||
|
data += prog[pcounter++];
|
||||||
|
unsigned short addr = ((s&0xf0)!=0)?max(pframepointer+1-data-n,pstackpointer):data;
|
||||||
|
/*Serial.print("STA");
|
||||||
|
Serial.print(s);
|
||||||
|
Serial.print(">");
|
||||||
|
Serial.print(s&0xf0);
|
||||||
|
Serial.print(">");
|
||||||
|
Serial.print((s&0xf0)!=0);
|
||||||
|
Serial.print(">");
|
||||||
|
Serial.print(max(pframepointer+1-data-n,pstackpointer));
|
||||||
|
Serial.print(">");
|
||||||
|
Serial.println(addr);*/
|
||||||
|
for (byte i = 0; i < n; i++) {
|
||||||
|
pram[addr+i] = (AReg>>(i*8))&0xff;
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
case 9:{ // STB
|
||||||
|
byte n = min(prog[pcounter++],4);
|
||||||
|
unsigned short data = prog[pcounter++]<<8;
|
||||||
|
data += prog[pcounter++];
|
||||||
|
for (byte i = 0; i < n; i++) {
|
||||||
|
pram[data+i] = (BReg>>(i*8))&0xff;
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
case 10:{ // STC
|
||||||
|
byte n = min(prog[pcounter++],4);
|
||||||
|
unsigned short data = prog[pcounter++]<<8;
|
||||||
|
data += prog[pcounter++];
|
||||||
|
for (byte i = 0; i < n; i++) {
|
||||||
|
pram[data+i] = (CReg>>(i*8))&0xff;
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
case 11:{ // STX
|
||||||
|
byte n = min(prog[pcounter++],4);
|
||||||
|
unsigned short data = prog[pcounter++]<<8;
|
||||||
|
data += prog[pcounter++];
|
||||||
|
for (byte i = 0; i < n; i++) {
|
||||||
|
pram[data+i] = (XReg>>(i*8))&0xff;
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case 12:{ // SOA
|
||||||
|
byte n = min(prog[pcounter++],4);
|
||||||
|
unsigned short data = prog[pcounter++]<<8;
|
||||||
|
data += prog[pcounter++];
|
||||||
|
data += XReg*n;
|
||||||
|
for (byte i = 0; i < n; i++) {
|
||||||
|
pram[data+i] = (AReg>>(i*8))&0xff;
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
case 13:{ // SOB
|
||||||
|
byte n = min(prog[pcounter++],4);
|
||||||
|
unsigned short data = prog[pcounter++]<<8;
|
||||||
|
data += prog[pcounter++];
|
||||||
|
data += XReg*n;
|
||||||
|
for (byte i = 0; i < n; i++) {
|
||||||
|
pram[data+i] = (BReg>>(i*8))&0xff;
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
case 14:{ // SOC
|
||||||
|
byte n = min(prog[pcounter++],4);
|
||||||
|
unsigned short data = prog[pcounter++]<<8;
|
||||||
|
data += prog[pcounter++];
|
||||||
|
data += XReg*n;
|
||||||
|
for (byte i = 0; i < n; i++) {
|
||||||
|
pram[data+i] = (CReg>>(i*8))&0xff;
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case 15:{ // LIA
|
||||||
|
uint32_t data = prog[pcounter++]<<24;
|
||||||
|
data += prog[pcounter++]<<16;
|
||||||
|
data += prog[pcounter++]<<8;
|
||||||
|
data += prog[pcounter++];
|
||||||
|
AReg = data;
|
||||||
|
}break;
|
||||||
|
case 16:{ // LIB
|
||||||
|
uint32_t data = prog[pcounter++]<<24;
|
||||||
|
data += prog[pcounter++]<<16;
|
||||||
|
data += prog[pcounter++]<<8;
|
||||||
|
data += prog[pcounter++];
|
||||||
|
BReg = data;
|
||||||
|
}break;
|
||||||
|
case 17:{ // LIC
|
||||||
|
uint32_t data = prog[pcounter++]<<24;
|
||||||
|
data += prog[pcounter++]<<16;
|
||||||
|
data += prog[pcounter++]<<8;
|
||||||
|
data += prog[pcounter++];
|
||||||
|
CReg = data;
|
||||||
|
}break;
|
||||||
|
case 18:{ // LIX
|
||||||
|
uint32_t data = prog[pcounter++]<<24;
|
||||||
|
data += prog[pcounter++]<<16;
|
||||||
|
data += prog[pcounter++]<<8;
|
||||||
|
data += prog[pcounter++];
|
||||||
|
XReg = data;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case 19:{ // CAB
|
||||||
|
BReg = AReg;
|
||||||
|
}break;
|
||||||
|
case 20:{ // CBC
|
||||||
|
CReg = BReg;
|
||||||
|
}break;
|
||||||
|
case 21:{ // CCA
|
||||||
|
AReg = CReg;
|
||||||
|
}break;
|
||||||
|
case 22:{ // CAC
|
||||||
|
CReg = AReg;
|
||||||
|
}break;
|
||||||
|
case 23:{ // CCB
|
||||||
|
BReg = CReg;
|
||||||
|
}break;
|
||||||
|
case 24:{ // CBA
|
||||||
|
AReg = BReg;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case 25:{ // CAX
|
||||||
|
XReg = AReg;
|
||||||
|
}break;
|
||||||
|
case 26:{ // CBX
|
||||||
|
XReg = BReg;
|
||||||
|
}break;
|
||||||
|
case 27:{ // CCX
|
||||||
|
XReg = CReg;
|
||||||
|
}break;
|
||||||
|
case 28:{ // CXA
|
||||||
|
AReg = XReg;
|
||||||
|
}break;
|
||||||
|
case 29:{ // CXB
|
||||||
|
BReg = XReg;
|
||||||
|
}break;
|
||||||
|
case 30:{ // CXC
|
||||||
|
CReg = XReg;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
//Types unsigned 0: uint;
|
||||||
|
// signed 1: int; 2: float
|
||||||
|
|
||||||
|
case 31: { //CVA
|
||||||
|
byte data1 = prog[pcounter++];
|
||||||
|
byte data2 = prog[pcounter++];
|
||||||
|
if(data2 == 2){
|
||||||
|
float o = 0;
|
||||||
|
if(data1 == 1){o= * ( int32_t * ) &AReg;}
|
||||||
|
else if(data1 == 2){o=AReg;}
|
||||||
|
else if(data1 == 2){o= * ( float * ) &AReg;}
|
||||||
|
AReg = * (uint32_t * ) &o;
|
||||||
|
}else if(data2 == 1){
|
||||||
|
int32_t o = 0;
|
||||||
|
if(data1 == 1){o= * ( int32_t * ) &AReg;}
|
||||||
|
else if(data1 == 0){o=AReg;}
|
||||||
|
else if(data1 == 2){o= * ( float * ) &AReg;}
|
||||||
|
AReg = * (uint32_t * ) &o;
|
||||||
|
}else {
|
||||||
|
uint32_t o = 0;
|
||||||
|
if(data1 == 1){o= * ( int32_t * ) &AReg;}
|
||||||
|
else if(data1 == 0){o=AReg;}
|
||||||
|
else if(data1 == 2){o= * ( float * ) &AReg;}
|
||||||
|
AReg = * (uint32_t * ) &o;
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
case 32:{ //CVB
|
||||||
|
byte data1 = prog[pcounter++];
|
||||||
|
byte data2 = prog[pcounter++];
|
||||||
|
if(data2 == 2){
|
||||||
|
float o = 0;
|
||||||
|
if(data1 == 1){o= * ( int32_t * ) &BReg;}
|
||||||
|
else if(data1 == 0){o=BReg;}
|
||||||
|
else if(data1 == 2){o= * ( float * ) &BReg;}
|
||||||
|
BReg = * (uint32_t * ) &o;
|
||||||
|
}else if(data2 == 1){
|
||||||
|
int32_t o = 0;
|
||||||
|
if(data1 == 1){o= * ( int32_t * ) &BReg;}
|
||||||
|
else if(data1 == 0){o=BReg;}
|
||||||
|
else if(data1 == 2){o= * ( float * ) &BReg;}
|
||||||
|
BReg = * (uint32_t * ) &o;
|
||||||
|
}else {
|
||||||
|
uint32_t o = 0;
|
||||||
|
if(data1 == 1){o= * ( int32_t * ) &BReg;}
|
||||||
|
else if(data1 == 0){o=BReg;}
|
||||||
|
else if(data1 == 2){o= * ( float * ) &BReg;}
|
||||||
|
BReg = * (uint32_t * ) &o;
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
case 33:{ //CVC
|
||||||
|
byte data1 = prog[pcounter++];
|
||||||
|
byte data2 = prog[pcounter++];
|
||||||
|
if(data2 == 2){
|
||||||
|
float o = 0;
|
||||||
|
if(data1 == 1){o= * ( int32_t * ) &CReg;}
|
||||||
|
else if(data1 == 0){o=CReg;}
|
||||||
|
else if(data1 == 2){o= * ( float * ) &CReg;}
|
||||||
|
CReg = * (uint32_t * ) &o;
|
||||||
|
}else if(data2 == 1){
|
||||||
|
int32_t o = 0;
|
||||||
|
if(data1 == 1){o= * ( int32_t * ) &CReg;}
|
||||||
|
else if(data1 == 0){o=CReg;}
|
||||||
|
else if(data1 == 2){o= * ( float * ) &CReg;}
|
||||||
|
CReg = * (uint32_t * ) &o;
|
||||||
|
}else {
|
||||||
|
uint32_t o = 0;
|
||||||
|
if(data1 == 1){o= * ( int32_t * ) &CReg;}
|
||||||
|
else if(data1 == 0){o=CReg;}
|
||||||
|
else if(data1 == 2){o= * ( float * ) &CReg;}
|
||||||
|
CReg = * (uint32_t * ) &o;
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
|
|
||||||
|
case 34:{ // ADD
|
||||||
|
byte data = prog[pcounter++];
|
||||||
|
byte data1 = prog[pcounter++];
|
||||||
|
byte data2 = prog[pcounter++];
|
||||||
|
|
||||||
|
if(data == 2){
|
||||||
|
float o = 0;
|
||||||
|
if(data1 == 1){o= * ( int32_t * ) &AReg;}
|
||||||
|
else if(data1 == 0){o=AReg;}
|
||||||
|
else if(data1 == 2){o= * ( float * ) &AReg;}
|
||||||
|
if(data2 == 1){o+= * ( int32_t * ) &BReg;}
|
||||||
|
else if(data2 == 0){o+=BReg;}
|
||||||
|
else if(data2 == 2){o+= * ( float * ) &BReg;}
|
||||||
|
AReg = * (uint32_t * ) &o;
|
||||||
|
}else if(data == 1){
|
||||||
|
int32_t o = 0;
|
||||||
|
if(data1 == 1){o= * ( int32_t * ) &AReg;}
|
||||||
|
else if(data1 == 0){o=AReg;}
|
||||||
|
else if(data1 == 2){o= * ( float * ) &AReg;}
|
||||||
|
if(data2 == 1){o+= * ( int32_t * ) &BReg;}
|
||||||
|
else if(data2 == 0){o+=BReg;}
|
||||||
|
else if(data2 == 2){o+= * ( float * ) &BReg;}
|
||||||
|
AReg = * (uint32_t * ) &o;
|
||||||
|
}else {
|
||||||
|
uint32_t o = 0;
|
||||||
|
if(data1 == 1){o= * ( int32_t * ) &AReg;}
|
||||||
|
else if(data1 == 0){o=AReg;}
|
||||||
|
else if(data1 == 2){o= * ( float * ) &AReg;}
|
||||||
|
if(data2 == 1){o+= * ( int32_t * ) &BReg;}
|
||||||
|
else if(data2 == 0){o+=BReg;}
|
||||||
|
else if(data2 == 2){o+= * ( float * ) &BReg;}
|
||||||
|
AReg = * (uint32_t * ) &o;
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
case 35:{ // SUB
|
||||||
|
byte data = prog[pcounter++];
|
||||||
|
byte data1 = prog[pcounter++];
|
||||||
|
byte data2 = prog[pcounter++];
|
||||||
|
|
||||||
|
if(data == 2){
|
||||||
|
float o = 0;
|
||||||
|
if(data1 == 1){o= * ( int32_t * ) &AReg;}
|
||||||
|
else if(data1 == 0){o=AReg;}
|
||||||
|
else if(data1 == 2){o= * ( float * ) &AReg;}
|
||||||
|
if(data2 == 1){o-= * ( int32_t * ) &BReg;}
|
||||||
|
else if(data2 == 0){o-=BReg;}
|
||||||
|
else if(data2 == 2){o-= * ( float * ) &BReg;}
|
||||||
|
AReg = * (uint32_t * ) &o;
|
||||||
|
}else if(data == 1){
|
||||||
|
int32_t o = 0;
|
||||||
|
if(data1 == 1){o= * ( int32_t * ) &AReg;}
|
||||||
|
else if(data1 == 0){o=AReg;}
|
||||||
|
else if(data1 == 2){o= * ( float * ) &AReg;}
|
||||||
|
if(data2 == 1){o-= * ( int32_t * ) &BReg;}
|
||||||
|
else if(data2 == 0){o-=BReg;}
|
||||||
|
else if(data2 == 2){o-= * ( float * ) &BReg;}
|
||||||
|
AReg = * (uint32_t * ) &o;
|
||||||
|
}else {
|
||||||
|
uint32_t o = 0;
|
||||||
|
if(data1 == 1){o= * ( int32_t * ) &AReg;}
|
||||||
|
else if(data1 == 0){o=AReg;}
|
||||||
|
else if(data1 == 2){o= * ( float * ) &AReg;}
|
||||||
|
if(data2 == 1){o-= * ( int32_t * ) &BReg;}
|
||||||
|
else if(data2 == 0){o-=BReg;}
|
||||||
|
else if(data2 == 2){o-= * ( float * ) &BReg;}
|
||||||
|
AReg = * (uint32_t * ) &o;
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
case 36:{ //MUL
|
||||||
|
byte data = prog[pcounter++];
|
||||||
|
byte data1 = prog[pcounter++];
|
||||||
|
byte data2 = prog[pcounter++];
|
||||||
|
|
||||||
|
if(data == 2){
|
||||||
|
float o = 1;
|
||||||
|
if(data1 == 1){o= * ( int32_t * ) &AReg;}
|
||||||
|
else if(data1 == 0){o=AReg;}
|
||||||
|
else if(data1 == 2){o= * ( float * ) &AReg;}
|
||||||
|
if(data2 == 1){o*= * ( int32_t * ) &BReg;}
|
||||||
|
else if(data2 == 0){o*=BReg;}
|
||||||
|
else if(data2 == 2){o*= * ( float * ) &BReg;}
|
||||||
|
AReg = * (uint32_t * ) &o;
|
||||||
|
}else if(data == 1){
|
||||||
|
int32_t o = 1;
|
||||||
|
if(data1 == 1){o= * ( int32_t * ) &AReg;}
|
||||||
|
else if(data1 == 0){o=AReg;}
|
||||||
|
else if(data1 == 2){o= * ( float * ) &AReg;}
|
||||||
|
if(data2 == 1){o*= * ( int32_t * ) &BReg;}
|
||||||
|
else if(data2 == 0){o*=BReg;}
|
||||||
|
else if(data2 == 2){o*= * ( float * ) &BReg;}
|
||||||
|
AReg = * (uint32_t * ) &o;
|
||||||
|
}else {
|
||||||
|
uint32_t o = 1;
|
||||||
|
if(data1 == 1){o= * ( int32_t * ) &AReg;}
|
||||||
|
else if(data1 == 0){o=AReg;}
|
||||||
|
else if(data1 == 2){o= * ( float * ) &AReg;}
|
||||||
|
if(data2 == 1){o*= * ( int32_t * ) &BReg;}
|
||||||
|
else if(data2 == 0){o*=BReg;}
|
||||||
|
else if(data2 == 2){o*= * ( float * ) &BReg;}
|
||||||
|
AReg = * (uint32_t * ) &o;
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
case 37:{ //DIV
|
||||||
|
byte data = prog[pcounter++];
|
||||||
|
byte data1 = prog[pcounter++];
|
||||||
|
byte data2 = prog[pcounter++];
|
||||||
|
|
||||||
|
if(data == 2){
|
||||||
|
float o = 1;
|
||||||
|
if(data1 == 1){o= * ( int32_t * ) &AReg;}
|
||||||
|
else if(data1 == 0){o=AReg;}
|
||||||
|
else if(data1 == 2){o= * ( float * ) &AReg;}
|
||||||
|
if(data2 == 1){o/= * ( int32_t * ) &BReg;}
|
||||||
|
else if(data2 == 0){o/=BReg;}
|
||||||
|
else if(data2 == 2){o/= * ( float * ) &BReg;}
|
||||||
|
AReg = * (uint32_t * ) &o;
|
||||||
|
}else if(data == 1){
|
||||||
|
int32_t o = 1;
|
||||||
|
if(data1 == 1){o= * ( int32_t * ) &AReg;}
|
||||||
|
else if(data1 == 0){o=AReg;}
|
||||||
|
else if(data1 == 2){o= * ( float * ) &AReg;}
|
||||||
|
if(data2 == 1){o/= * ( int32_t * ) &BReg;}
|
||||||
|
else if(data2 == 0){o/=BReg;}
|
||||||
|
else if(data2 == 2){o/= * ( float * ) &BReg;}
|
||||||
|
AReg = * (uint32_t * ) &o;
|
||||||
|
}else{
|
||||||
|
uint32_t o = 1;
|
||||||
|
if(data1 == 1){o= * ( int32_t * ) &AReg;}
|
||||||
|
else if(data1 == 0){o=AReg;}
|
||||||
|
else if(data1 == 2){o= * ( float * ) &AReg;}
|
||||||
|
if(data2 == 1){o/= * ( int32_t * ) &BReg;}
|
||||||
|
else if(data2 == 0){o/=BReg;}
|
||||||
|
else if(data2 == 2){o/= * ( float * ) &BReg;}
|
||||||
|
AReg = * (uint32_t * ) &o;
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
case 38:{ //MOD
|
||||||
|
byte data = prog[pcounter++];
|
||||||
|
byte data1 = prog[pcounter++];
|
||||||
|
byte data2 = prog[pcounter++];
|
||||||
|
|
||||||
|
if(data == 2){
|
||||||
|
uint32_t o = 1;
|
||||||
|
if(data1 == 1){o= * ( int32_t * ) &AReg;}
|
||||||
|
else if(data1 == 0){o=AReg;}
|
||||||
|
if(data2 == 1){o = o % (* ( int32_t * ) &BReg);}
|
||||||
|
else if(data2 == 0){o=o%BReg;}
|
||||||
|
AReg = * (uint32_t * ) &o;
|
||||||
|
}else{
|
||||||
|
int32_t o = 1;
|
||||||
|
if(data1 == 1){o= * ( int32_t * ) &AReg;}
|
||||||
|
else if(data1 == 0){o=AReg;}
|
||||||
|
if(data2 == 1){o = o % (* ( int32_t * ) &BReg);}
|
||||||
|
else if(data2 == 0){o=o%BReg;}
|
||||||
|
AReg = * (uint32_t * ) &o;
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case 39:{ // POW
|
||||||
|
byte data = prog[pcounter++];
|
||||||
|
byte data1 = prog[pcounter++];
|
||||||
|
byte data2 = prog[pcounter++];
|
||||||
|
|
||||||
|
if(data == 2){
|
||||||
|
float o = 0;
|
||||||
|
if(data1 == 1){o= * ( int32_t * ) &AReg;}
|
||||||
|
else if(data1 == 0){o=AReg;}
|
||||||
|
else if(data1 == 2){o= * ( float * ) &AReg;}
|
||||||
|
if(data2 == 1){o=pow(o, * ( int32_t * ) &BReg);}
|
||||||
|
else if(data2 == 0){o=pow(o, BReg);}
|
||||||
|
else if(data2 == 2){o=pow(o, * ( float * ) &BReg);}
|
||||||
|
AReg = * (uint32_t * ) &o;
|
||||||
|
}else if(data == 1){
|
||||||
|
int32_t o = 0;
|
||||||
|
if(data1 == 1){o= * ( int32_t * ) &AReg;}
|
||||||
|
else if(data1 == 0){o=AReg;}
|
||||||
|
else if(data1 == 2){o= * ( float * ) &AReg;}
|
||||||
|
if(data2 == 1){o=pow(o, * ( int32_t * ) &BReg);}
|
||||||
|
else if(data2 == 0){o=pow(o, BReg);}
|
||||||
|
else if(data2 == 2){o=pow(o, * ( float * ) &BReg);}
|
||||||
|
AReg = * (uint32_t * ) &o;
|
||||||
|
}else {
|
||||||
|
uint32_t o = 0;
|
||||||
|
if(data1 == 1){o= * ( int32_t * ) &AReg;}
|
||||||
|
else if(data1 == 0){o=AReg;}
|
||||||
|
else if(data1 == 2){o= * ( float * ) &AReg;}
|
||||||
|
if(data2 == 1){o=pow(o, * ( int32_t * ) &BReg);}
|
||||||
|
else if(data2 == 0){o=pow(o, BReg);}
|
||||||
|
else if(data2 == 2){o=pow(o, * ( float * ) &BReg);}
|
||||||
|
AReg = * (uint32_t * ) &o;
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
case 40:{ // ROT
|
||||||
|
byte data = prog[pcounter++];
|
||||||
|
byte data1 = prog[pcounter++];
|
||||||
|
byte data2 = prog[pcounter++];
|
||||||
|
|
||||||
|
if(data == 2){
|
||||||
|
float o = 0;
|
||||||
|
if(data1 == 1){o= * ( int32_t * ) &AReg;}
|
||||||
|
else if(data1 == 0){o=AReg;}
|
||||||
|
else if(data1 == 2){o= * ( float * ) &AReg;}
|
||||||
|
if(data2 == 1){o=pow(o,1.0/ (* ( int32_t * ) &BReg));}
|
||||||
|
else if(data2 == 0){o=pow(o, 1.0/BReg);}
|
||||||
|
else if(data2 == 2){o=pow(o,1.0/( * ( float * ) &BReg));}
|
||||||
|
AReg = * (uint32_t * ) &o;
|
||||||
|
}else if(data == 1){
|
||||||
|
int32_t o = 0;
|
||||||
|
if(data1 == 1){o= * ( int32_t * ) &AReg;}
|
||||||
|
else if(data1 == 0){o=AReg;}
|
||||||
|
else if(data1 == 2){o= * ( float * ) &AReg;}
|
||||||
|
if(data2 == 1){o=pow(o,1.0/ (* ( int32_t * ) &BReg));}
|
||||||
|
else if(data2 == 0){o=pow(o, 1.0/BReg);}
|
||||||
|
else if(data2 == 2){o=pow(o,1.0/( * ( float * ) &BReg));}
|
||||||
|
AReg = * (uint32_t * ) &o;
|
||||||
|
}else {
|
||||||
|
uint32_t o = 0;
|
||||||
|
if(data1 == 1){o= * ( int32_t * ) &AReg;}
|
||||||
|
else if(data1 == 0){o=AReg;}
|
||||||
|
else if(data1 == 2){o= * ( float * ) &AReg;}
|
||||||
|
if(data2 == 1){o=pow(o, * ( int32_t * ) &BReg);}
|
||||||
|
else if(data2 == 0){o=pow(o, BReg);}
|
||||||
|
else if(data2 == 2){o=pow(o, * ( float * ) &BReg);}
|
||||||
|
AReg = * (uint32_t * ) &o;
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
case 41:{ // LOG
|
||||||
|
byte data = prog[pcounter++];
|
||||||
|
byte data1 = prog[pcounter++];
|
||||||
|
|
||||||
|
if(data == 2){
|
||||||
|
float o = 0;
|
||||||
|
if(data1 == 1){o=log( * ( int32_t * ) &AReg);}
|
||||||
|
else if(data1 == 0){o=log(AReg);}
|
||||||
|
else if(data1 == 2){o= log(* ( float * ) &AReg);}
|
||||||
|
AReg = * (uint32_t * ) &o;
|
||||||
|
}else if(data == 1){
|
||||||
|
int32_t o = 0;
|
||||||
|
if(data1 == 1){o=log( * ( int32_t * ) &AReg);}
|
||||||
|
else if(data1 == 0){o=log(AReg);}
|
||||||
|
else if(data1 == 2){o= log(* ( float * ) &AReg);}
|
||||||
|
AReg = * (uint32_t * ) &o;
|
||||||
|
}else {
|
||||||
|
uint32_t o = 0;
|
||||||
|
if(data1 == 1){o=log( * ( int32_t * ) &AReg);}
|
||||||
|
else if(data1 == 0){o=log(AReg);}
|
||||||
|
else if(data1 == 2){o= log(* ( float * ) &AReg);}
|
||||||
|
AReg = * (uint32_t * ) &o;
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case 42:{ // SR
|
||||||
|
AReg = AReg >> BReg;
|
||||||
|
}break;
|
||||||
|
case 43:{ // SL
|
||||||
|
AReg = AReg << BReg;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case 44:{ // INC
|
||||||
|
byte data1 = prog[pcounter++];
|
||||||
|
if(data1==0||data1==1){
|
||||||
|
AReg++;
|
||||||
|
}else if(data1==2){
|
||||||
|
float o = * (float *) &AReg;
|
||||||
|
o++;
|
||||||
|
AReg = * (uint32_t * ) &o;
|
||||||
|
}
|
||||||
|
|
||||||
|
}break;
|
||||||
|
case 45:{ // DEC
|
||||||
|
byte data1 = prog[pcounter++];
|
||||||
|
if(data1==0||data1==1){
|
||||||
|
AReg--;
|
||||||
|
}else if(data1==2){
|
||||||
|
float o = * (float *) &AReg;
|
||||||
|
o--;
|
||||||
|
AReg = * (uint32_t * ) &o;
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case 46:{ // BWO
|
||||||
|
AReg = AReg | BReg;
|
||||||
|
}break;
|
||||||
|
case 47:{ // BWA
|
||||||
|
AReg = AReg & BReg;
|
||||||
|
}break;
|
||||||
|
case 48:{ // BWX
|
||||||
|
AReg = AReg ^ BReg;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case 49:{ //CMP
|
||||||
|
byte data1 = prog[pcounter++];
|
||||||
|
byte data2 = prog[pcounter++];
|
||||||
|
|
||||||
|
double o = 0;
|
||||||
|
if(data1 == 1){o= * ( int32_t * ) &AReg;}
|
||||||
|
else if(data1 == 0){o=AReg;}
|
||||||
|
else if(data1 == 2){o= * ( float * ) &AReg;}
|
||||||
|
if(data2 == 1){o-= * ( int32_t * ) &BReg;}
|
||||||
|
else if(data2 == 0){o-=BReg;}
|
||||||
|
else if(data2 == 2){o-= * ( float * ) &BReg;}
|
||||||
|
equalFlag = (fabs(o) < 0.00005f);
|
||||||
|
biggerFlag = (o >= 0.00005f);
|
||||||
|
smalerFlag = (o <= -0.00005f);
|
||||||
|
}break;
|
||||||
|
case 50:{ //JMP
|
||||||
|
uint16_t data = prog[pcounter++]<<8;
|
||||||
|
data += prog[pcounter++];
|
||||||
|
pcounter = data;
|
||||||
|
}break;
|
||||||
|
case 51:{ //JE
|
||||||
|
uint16_t data = prog[pcounter++]<<8;
|
||||||
|
data += prog[pcounter++];
|
||||||
|
if(equalFlag){
|
||||||
|
pcounter = data;
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
case 52:{ //JNE
|
||||||
|
uint16_t data = prog[pcounter++]<<8;
|
||||||
|
data += prog[pcounter++];
|
||||||
|
if(!equalFlag){
|
||||||
|
pcounter = data;
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
case 53:{ //JB
|
||||||
|
uint16_t data = prog[pcounter++]<<8;
|
||||||
|
data += prog[pcounter++];
|
||||||
|
if(biggerFlag){
|
||||||
|
pcounter = data;
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
case 54:{ //JNB
|
||||||
|
uint16_t data = prog[pcounter++]<<8;
|
||||||
|
data += prog[pcounter++];
|
||||||
|
if(!biggerFlag){
|
||||||
|
pcounter = data;
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
case 55:{ //JS
|
||||||
|
uint16_t data = prog[pcounter++]<<8;
|
||||||
|
data += prog[pcounter++];
|
||||||
|
if(smalerFlag){
|
||||||
|
pcounter = data;
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
case 56:{ //JNS
|
||||||
|
uint16_t data = prog[pcounter++]<<8;
|
||||||
|
data += prog[pcounter++];
|
||||||
|
if(!smalerFlag){
|
||||||
|
pcounter = data;
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case 57:{ //PSH
|
||||||
|
int data = max(min(prog[pcounter++],255),1);
|
||||||
|
for (int i = data-1; i >= 0; i--) {
|
||||||
|
if(i<=4){
|
||||||
|
pram[pstackpointer--] = (AReg >> (i*8))&0xff;
|
||||||
|
}else{
|
||||||
|
pram[pstackpointer--] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(pram_length-pstackpointer>pstackmax){
|
||||||
|
doExecute = false;
|
||||||
|
Serial.println("Stackoverflow: PSH");
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
case 58:{ //PUL
|
||||||
|
int data = max(min(prog[pcounter++]+0,255),1);
|
||||||
|
AReg = 0;
|
||||||
|
for (int i = 0; i < data; i++) {
|
||||||
|
if(i<=4){
|
||||||
|
AReg+=pram[++pstackpointer]<<(i*8);
|
||||||
|
}else{
|
||||||
|
pstackpointer++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(pram_length-pstackpointer>pstackmax){
|
||||||
|
doExecute = false;
|
||||||
|
Serial.println("Stackunderflow: PUL");
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
case 59:{ //JSR
|
||||||
|
uint16_t data = prog[pcounter++]<<8;
|
||||||
|
data += prog[pcounter++];
|
||||||
|
pram[pstackpointer--] = (pframepointer)&0xff;
|
||||||
|
pram[pstackpointer--] = (pframepointer>>8)&0xff;
|
||||||
|
pram[pstackpointer--] = (pcounter)&0xff;
|
||||||
|
pram[pstackpointer--] = (pcounter>>8)&0xff;
|
||||||
|
pframepointer = pstackpointer;
|
||||||
|
if(pram_length-pstackpointer>pstackmax){
|
||||||
|
doExecute = false;
|
||||||
|
Serial.println("Stackoverflow: JSR");
|
||||||
|
}
|
||||||
|
pcounter = data;
|
||||||
|
}break;
|
||||||
|
case 60:{ //JSA
|
||||||
|
uint16_t data = AReg;
|
||||||
|
pram[pstackpointer--] = (pframepointer)&0xff;
|
||||||
|
pram[pstackpointer--] = (pframepointer>>8)&0xff;
|
||||||
|
pram[pstackpointer--] = (pcounter)&0xff;
|
||||||
|
pram[pstackpointer--] = (pcounter>>8)&0xff;
|
||||||
|
pframepointer = pstackpointer;
|
||||||
|
if(pram_length-pstackpointer>pstackmax){
|
||||||
|
doExecute = false;
|
||||||
|
Serial.println("Stackoverflow: JSA");
|
||||||
|
}
|
||||||
|
pcounter = data;
|
||||||
|
}break;
|
||||||
|
case 61:{ //RSR
|
||||||
|
pcounter = 0;
|
||||||
|
pstackpointer = pframepointer;
|
||||||
|
pcounter = pram[++pstackpointer]<<8;
|
||||||
|
pcounter += pram[++pstackpointer];
|
||||||
|
pframepointer = pram[++pstackpointer]<<8;
|
||||||
|
pframepointer += pram[++pstackpointer];
|
||||||
|
if(pram_length-pstackpointer>pstackmax){
|
||||||
|
doExecute = false;
|
||||||
|
Serial.println("Stackunderflow: RSR");
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
|
|
||||||
|
case 252:{ //IN
|
||||||
|
|
||||||
|
}break;
|
||||||
|
case 253:{ //OUT
|
||||||
|
byte data = prog[pcounter++];
|
||||||
|
if(data==1) Serial.println(* (int *) &AReg);
|
||||||
|
if(data==0) Serial.println(AReg);
|
||||||
|
if(data==2) Serial.println(* (float *) &AReg);
|
||||||
|
}break;
|
||||||
|
case 254:{ //SHS Set Heap Size
|
||||||
|
unsigned short data = prog[pcounter++]<<8;
|
||||||
|
data += prog[pcounter++];
|
||||||
|
pstackmax = pram_length-data;
|
||||||
|
if(pram_length-pstackpointer>pstackmax){
|
||||||
|
doExecute = false;
|
||||||
|
Serial.println("Stackoverflow: SHS");
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
case 255:{ //HLT bzw. exit
|
||||||
|
pcounter = 0;
|
||||||
|
doExecute = false;
|
||||||
|
}break;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue