Initial Commit

This commit is contained in:
jusax23 2022-05-15 22:32:35 +02:00
parent 323dff45f4
commit 981b014f37
10 changed files with 1912 additions and 75 deletions

0
.gitignore vendored Normal file
View file

137
README.md
View file

@ -1,92 +1,79 @@
# 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
- [ ] [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:
### Calculation
```lisp
(+ a b)
(+ a b c) ;...
(- a b)
(- a b c) ;...
(* a b)
(* a b c) ;...
(/ a b)
(/ a b c) ;...
```
cd existing_repo
git remote add origin https://gitlab.com/jusax23/raspberry-pi-pico-machine-code-emulator.git
git branch -M main
git push -uf origin main
###print
```lisp
(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/)
- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html)
- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically)
- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/)
- [ ] [Automatically merge when pipeline succeeds](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html)
### Variables
Define Variables:
```lisp
(defvar myvar1:uint32 4)
(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.
- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html)
- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing(SAST)](https://docs.gitlab.com/ee/user/application_security/sast/)
- [ ] [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/)
- [ ] [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.
```lisp
(defun faculty:uint32 (input:uint32)
(print input)
(if (< in 2) 1 (* input (faculty (- input 1))))
)
(print (faculty 10))
```

11
compiler/build.sh Normal file
View 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
View 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

View file

@ -0,0 +1 @@
fe00080f0000001b0f0000000a080400003b001b01040004fd00ff390401040000081400000114000039040f00000002133a043100000f000000013700430f0000000010000000013100003400560f000000013200820114000039040f00000001390401140000163a04131523000000080400003b001b01040004133a0424000000080400043d

25
compiler/package.json Normal file
View 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"
}

View file

@ -0,0 +1,4 @@
(defun faculty:uint32 (input:uint32)
(if (< input 2) 1 (* input (faculty (- input 1))))
)
(print (faculty 10))

View 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
View 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
View 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;
}
}