ctx steps, better errors, vars, chars, comp, if, math,
This commit is contained in:
parent
77e6b3da48
commit
675a3d552a
13 changed files with 430 additions and 106 deletions
76
js/ctx.js
76
js/ctx.js
|
@ -1,6 +1,8 @@
|
||||||
import { link } from "fs";
|
import { link } from "fs";
|
||||||
import { error } from "./lexer.js";
|
import { error } from "./lexer.js";
|
||||||
|
|
||||||
|
let count = 0;
|
||||||
|
|
||||||
export class context{
|
export class context{
|
||||||
#list = {};
|
#list = {};
|
||||||
#types = {
|
#types = {
|
||||||
|
@ -18,30 +20,55 @@ export class context{
|
||||||
bool: {link:"u8"},
|
bool: {link:"u8"},
|
||||||
b: {link:"bool"},
|
b: {link:"bool"},
|
||||||
};
|
};
|
||||||
constructor(){
|
#upper = [];
|
||||||
console.log("create");
|
constructor(upper =[]){
|
||||||
|
this.#upper = upper;
|
||||||
}
|
}
|
||||||
|
nextLevel(){
|
||||||
add({name,size,amount=1,type = 0, content = 0}){
|
return new context(this);
|
||||||
console.log("add",name+"");
|
|
||||||
|
|
||||||
this.#list[name+""] = {size,amount,type,content};
|
|
||||||
console.log(this.#list);
|
|
||||||
}
|
}
|
||||||
find(name,pos){
|
add({name,vType,size,amount=1,type = 0, content = 0,config = [1]}){
|
||||||
let elem = this.#list[name+""];
|
if (!this.#list[vType]) this.#list[vType] = {};
|
||||||
console.log(this.#list);
|
this.#list[vType][name+""] = {name: vType+(count++),size,amount,type,content,config};
|
||||||
if(!elem) error("Can not find '"+name+"' in context!");
|
}
|
||||||
|
find(name, vType,pos=name.pos,quit=true){
|
||||||
|
let elem = (this.#list[vType]??{})[name+""]??null;
|
||||||
|
|
||||||
|
if(!elem){
|
||||||
|
elem = this.#upper.find(name,vType,pos,false);
|
||||||
|
}
|
||||||
|
if(!elem&&quit) error("Can not find '"+name+"' in context!",...pos);
|
||||||
return elem;
|
return elem;
|
||||||
}
|
}
|
||||||
|
|
||||||
getType(name){
|
getType(name,pos=name.pos, quit = true){
|
||||||
let type;
|
let lastName = name;
|
||||||
do{
|
let type = this.#types[name];
|
||||||
|
|
||||||
|
if(!type){
|
||||||
|
type = this.#upper.getType(name, pos, false);
|
||||||
|
if (!type) error("Can not find '" + name + "' in context", ...pos);
|
||||||
|
return type;
|
||||||
|
}else{
|
||||||
|
if(type.link){
|
||||||
|
type = this.getType(type.link,pos,false);
|
||||||
|
if (!type) error("Can not find '" + name + "' in context", ...pos);
|
||||||
|
return type;
|
||||||
|
}else{
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*do{
|
||||||
|
|
||||||
if (type) type = this.#types[type.link]
|
if (type) type = this.#types[type.link]
|
||||||
else type = this.#types[name];
|
else type = this.#types[name];
|
||||||
}while(type.link);
|
}while(type&&type.link);*/
|
||||||
return type;
|
|
||||||
|
|
||||||
|
}
|
||||||
|
addLinkType(name,link){
|
||||||
|
this.#types[name] = {link};
|
||||||
}
|
}
|
||||||
|
|
||||||
build(){
|
build(){
|
||||||
|
@ -50,17 +77,22 @@ export class context{
|
||||||
GREG @
|
GREG @
|
||||||
|
|
||||||
`;
|
`;
|
||||||
for(let Name in this.#list){
|
|
||||||
let { size, amount, type, content } = this.#list[Name];
|
for(let vType in this.#list){
|
||||||
|
for(let UName in this.#list[vType]){
|
||||||
|
let { size, amount, type, content, name } = this.#list[vType][UName];
|
||||||
|
if (!isNaN(content)) content = Number(content);
|
||||||
if (size <= 8 && amount == 1) {
|
if (size <= 8 && amount == 1) {
|
||||||
out += `${Name} ${(["BYTE", "WYDE", "TETRA", "TETRA", "OCTA", "OCTA", "OCTA", "OCTA"])[size-1]} ${content}\n`;
|
out += `${name} ${(["BYTE", "WYDE", "TETRA", "TETRA", "OCTA", "OCTA", "OCTA", "OCTA"])[size - 1]} ${content}\n`;
|
||||||
} else {
|
} else {
|
||||||
out += `
|
out += `
|
||||||
${name} BYTE ${content}
|
${name} BYTE ${content}
|
||||||
LOC ${name}+${size+amount+1}\n`;
|
LOC ${name}+${size * amount + 1}\n`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out+=" LOC #100\nMain";
|
|
||||||
|
}
|
||||||
|
out +=" LOC #100\nMain SWYM\n";
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
}
|
}
|
9
js/errors.js
Normal file
9
js/errors.js
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
import { error } from "./lexer.js"
|
||||||
|
|
||||||
|
|
||||||
|
export const argsCount = (name,num,pos)=>{
|
||||||
|
error(`The native function '${name}' needs at least ${num} Arguments!`, ...pos);
|
||||||
|
}
|
||||||
|
export const argCount = (name,num,pos)=>{
|
||||||
|
error(`The native function '${name}' needs ${num} Arguments!`, ...pos);
|
||||||
|
}
|
|
@ -7,33 +7,40 @@ let nid = 0;
|
||||||
|
|
||||||
|
|
||||||
export function execute({ data, target = 0, ctx = new context()}){
|
export function execute({ data, target = 0, ctx = new context()}){
|
||||||
|
if(target > 255) error("To much registers are required to run this. Support for this case will be build in later!",...data.pos);
|
||||||
let [type, d] = createType(data);
|
let [type, d] = createType(data);
|
||||||
if(type == "code"){
|
if(type == "code"){
|
||||||
try {
|
try {
|
||||||
let { type, code } = nativefunc[data[0]]({ execute: ({data, target=0}) => execute({data, target,ctx}),data,target,nid:()=>nid++,ctx});
|
let { type, code } = nativefunc[data[0]]({
|
||||||
|
execute: ({ data, target = 0, ctx:contx = ctx }) => execute({ data, target, ctx:contx }),
|
||||||
|
data,
|
||||||
|
target,
|
||||||
|
nid: () => nid++,
|
||||||
|
ctx
|
||||||
|
});
|
||||||
return {code,type};
|
return {code,type};
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
error(`'${data[0]}' is not a function`,...data.pos);
|
error(`'${data[0]}' is not a function`,...data.pos);
|
||||||
}
|
}
|
||||||
}else if (type == "var"){
|
}else if (type == "var"){
|
||||||
let { size, amount, type } = ctx.find(d+"V");
|
let { size, amount, type, name } = ctx.find(d,"V",data.pos);
|
||||||
if (size <= 8 && amount == 1){
|
if (size <= 8 && amount == 1){
|
||||||
if(type == COMPUTE_TYPES.FLOAT){
|
if(type == COMPUTE_TYPES.FLOAT){
|
||||||
return {
|
return {
|
||||||
type: 2,
|
type: 2,
|
||||||
code: ` ${size > 4 ? "LDOU" :"SFLOT"} $${target},${d}V`
|
code: ` ${size > 4 ? "LDOU" :"LDSF"} $${target},${name}`
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
return {
|
return {
|
||||||
type: type,
|
type: type,
|
||||||
code: ` LD${(["B", "W", "T", "T", "O", "O", "O", "O"])[size-1]}${type==0?"U":""} $${target},${d}V`
|
code: ` LD${(["B", "W", "T", "T", "O", "O", "O", "O"])[size-1]}${type==0?"U":""} $${target},${name}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
return {
|
return {
|
||||||
type: 0,
|
type: 0,
|
||||||
code: ` LDA $${target},${elem.name}`
|
code: ` LDA $${target},${name}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,11 +50,16 @@ export function execute({ data, target = 0, ctx = new context()}){
|
||||||
type: COMPUTE_TYPES.UINT
|
type: COMPUTE_TYPES.UINT
|
||||||
}
|
}
|
||||||
}else if (type == "num"){
|
}else if (type == "num"){
|
||||||
|
|
||||||
return {
|
return {
|
||||||
code: ` SET $${target},${d}`,
|
code: ` SET $${target},${d}`,
|
||||||
type: COMPUTE_TYPES.UINT
|
type: COMPUTE_TYPES.UINT
|
||||||
}
|
}
|
||||||
|
}else if (type == "str"){
|
||||||
|
|
||||||
|
return {
|
||||||
|
code: ` SET $${target},"${d}"`,
|
||||||
|
type: COMPUTE_TYPES.UINT
|
||||||
|
}
|
||||||
}
|
}
|
||||||
throw new Error("nothing found");
|
throw new Error("nothing found");
|
||||||
}
|
}
|
|
@ -102,6 +102,7 @@ function cutCmd(code, line, chars) {
|
||||||
countLines++;
|
countLines++;
|
||||||
countChars = 0;
|
countChars = 0;
|
||||||
} else if (c == '"') {
|
} else if (c == '"') {
|
||||||
|
buffer += c;
|
||||||
if (!inC) finishBuff();
|
if (!inC) finishBuff();
|
||||||
inStr = false;
|
inStr = false;
|
||||||
} else {
|
} else {
|
||||||
|
@ -111,6 +112,7 @@ function cutCmd(code, line, chars) {
|
||||||
}
|
}
|
||||||
if (c == '"') {
|
if (c == '"') {
|
||||||
inStr = true;
|
inStr = true;
|
||||||
|
buffer += c;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (c == ";" && !inC) {
|
if (c == ";" && !inC) {
|
||||||
|
@ -167,9 +169,9 @@ export function createType(data) {
|
||||||
/*if (data == "NaN") {
|
/*if (data == "NaN") {
|
||||||
return ["num", NaN];
|
return ["num", NaN];
|
||||||
}*/
|
}*/
|
||||||
/*if(typeof data == "string"&&data.startsWith('"') && data.endsWith('"')){
|
if ((data instanceof LISPstring)&&data.startsWith('"') && data.endsWith('"')){
|
||||||
return ["str", data.slice(1,-1)];
|
return ["str", data.slice(1,-1)];
|
||||||
}*/
|
}
|
||||||
if ((data instanceof LISPstring) && !isNaN(data)) {
|
if ((data instanceof LISPstring) && !isNaN(data)) {
|
||||||
return ["num", Number(data)];
|
return ["num", Number(data)];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,70 +1,13 @@
|
||||||
import { createType, error, LISPcmd } from "./lexer.js";
|
import bool from "./nativefuncs/bool.js";
|
||||||
import { convertType, getOutType } from "./types.js"
|
import lanes from "./nativefuncs/lanes.js";
|
||||||
|
import math from "./nativefuncs/math.js";
|
||||||
|
import sys from "./nativefuncs/sys.js";
|
||||||
|
import vars from "./nativefuncs/vars.js";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
"+": ({ execute, data, target, nid, ctx }) => {
|
...math,
|
||||||
let params = data.array.slice(1).map((d, i) => execute({ data: d, target: target + (i ? 0 : 1) }));
|
...vars,
|
||||||
let outType = getOutType(...params.map(d => d.type));
|
...lanes,
|
||||||
return {
|
...sys,
|
||||||
type: outType,
|
...bool,
|
||||||
code: params.map((d, i) => {
|
|
||||||
if (i == 0) return [
|
|
||||||
d.code,
|
|
||||||
convertType(d.type, outType, target)
|
|
||||||
];
|
|
||||||
return [
|
|
||||||
d.code,
|
|
||||||
convertType(d.type, outType, target + 1),
|
|
||||||
` ${(["ADDU", "ADD", "FADD"])[outType]} $${target},$${target},$${target + 1}`
|
|
||||||
];
|
|
||||||
}).flat(Infinity).join("\n")
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"-": ({ execute, data, target, nid, ctx }) => {
|
|
||||||
let params = data.array.slice(1).map((d, i) => execute({ data: d, target: target + (i ? 0 : 1) }));
|
|
||||||
let outType = getOutType(...params.map(d => d.type));
|
|
||||||
return {
|
|
||||||
type: outType,
|
|
||||||
code: params.map((d, i) => {
|
|
||||||
if (i == 0) return [
|
|
||||||
d.code,
|
|
||||||
convertType(d.type, outType, target)
|
|
||||||
];
|
|
||||||
return [
|
|
||||||
d.code,
|
|
||||||
convertType(d.type, outType, target + 1),
|
|
||||||
` ${(["SUBU", "SUB", "FSUB"])[outType]} $${target},$${target},$${target + 1}`
|
|
||||||
];
|
|
||||||
}).flat(Infinity).join("\n")
|
|
||||||
}
|
|
||||||
},
|
|
||||||
defvar: ({ execute, data, target, nid, ctx }) => {
|
|
||||||
let param = data[3];
|
|
||||||
let [type, d] = createType(param);
|
|
||||||
|
|
||||||
let varType = ctx.getType(data[2]);
|
|
||||||
if (varType.content) error("A variable only can be created with a primitive Type.", ...data[2].pos);
|
|
||||||
|
|
||||||
if (type == "var" || type == "code") {
|
|
||||||
error("devfar with input is not implemented yet.", ...param.pos)
|
|
||||||
} else {
|
|
||||||
ctx.add({ name: data[1] + "V", size: varType.size, amount: 1, type: varType.type, content: param });
|
|
||||||
return {
|
|
||||||
code: "",
|
|
||||||
type: 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
defarr: ({ execute, data, target, nid, ctx }) => {
|
|
||||||
let param = data.slice(3).map(d => Number(d));
|
|
||||||
let varType = ctx.getType(data[2]);
|
|
||||||
let amount = param.reduce((v, c) => v * c, 1);
|
|
||||||
|
|
||||||
ctx.add({ name: data[1] + "V", size: varType.size, amount: amount, type: varType.type, content: param });
|
|
||||||
|
|
||||||
return {
|
|
||||||
code: "",
|
|
||||||
type: 0
|
|
||||||
};
|
};
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
116
js/nativefuncs/bool.js
Normal file
116
js/nativefuncs/bool.js
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
import { argCount } from "../errors.js";
|
||||||
|
import { COMPUTE_TYPES, convertType, getOutType } from "../types.js";
|
||||||
|
|
||||||
|
|
||||||
|
export default {
|
||||||
|
"<": ({ execute, data, target, nid, ctx }) => {
|
||||||
|
if (data.length != 3) argCount("<",2,data.pos);
|
||||||
|
let param1 = execute({ data: data[1], target});
|
||||||
|
let param2 = execute({ data: data[2], target:target+1});
|
||||||
|
let outType = getOutType(param1.type,param2.type);
|
||||||
|
return {
|
||||||
|
type: COMPUTE_TYPES.UINT,
|
||||||
|
code: `${param1.code}
|
||||||
|
${convertType(param1.type, outType, target) }
|
||||||
|
${param2.code}
|
||||||
|
${convertType(param2.type, outType, target+1)}
|
||||||
|
${ (["CMPU", "CMP", "FCMP"])[outType] } $${ target },$${ target },$${ target + 1 }
|
||||||
|
ZSN $${target},$${target},1`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"<=": ({ execute, data, target, nid, ctx }) => {
|
||||||
|
if (data.length != 3) argCount("<=",2,data.pos);
|
||||||
|
let param1 = execute({ data: data[1], target});
|
||||||
|
let param2 = execute({ data: data[2], target:target+1});
|
||||||
|
let outType = getOutType(param1.type,param2.type);
|
||||||
|
return {
|
||||||
|
type: COMPUTE_TYPES.UINT,
|
||||||
|
code: `${param1.code}
|
||||||
|
${convertType(param1.type, outType, target) }
|
||||||
|
${param2.code}
|
||||||
|
${convertType(param2.type, outType, target+1)}
|
||||||
|
${ (["CMPU", "CMP", "FCMP"])[outType] } $${ target },$${ target },$${ target + 1 }
|
||||||
|
ZSNP $${target},$${target},1`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"=": ({ execute, data, target, nid, ctx }) => {
|
||||||
|
if (data.length != 3) argCount("=",2,data.pos);
|
||||||
|
let param1 = execute({ data: data[1], target});
|
||||||
|
let param2 = execute({ data: data[2], target:target+1});
|
||||||
|
let outType = getOutType(param1.type,param2.type);
|
||||||
|
return {
|
||||||
|
type: COMPUTE_TYPES.UINT,
|
||||||
|
code: `${param1.code}
|
||||||
|
${convertType(param1.type, outType, target) }
|
||||||
|
${param2.code}
|
||||||
|
${convertType(param2.type, outType, target+1)}
|
||||||
|
${ (["CMPU", "CMP", "FCMP"])[outType] } $${ target },$${ target },$${ target + 1 }
|
||||||
|
ZSZ $${target},$${target},1`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
">=": ({ execute, data, target, nid, ctx }) => {
|
||||||
|
if (data.length != 3) argCount(">=",2,data.pos);
|
||||||
|
let param1 = execute({ data: data[1], target});
|
||||||
|
let param2 = execute({ data: data[2], target:target+1});
|
||||||
|
let outType = getOutType(param1.type,param2.type);
|
||||||
|
return {
|
||||||
|
type: COMPUTE_TYPES.UINT,
|
||||||
|
code: `${param1.code}
|
||||||
|
${convertType(param1.type, outType, target) }
|
||||||
|
${param2.code}
|
||||||
|
${convertType(param2.type, outType, target+1)}
|
||||||
|
${ (["CMPU", "CMP", "FCMP"])[outType] } $${ target },$${ target },$${ target + 1 }
|
||||||
|
ZSNN $${target},$${target},1`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
">": ({ execute, data, target, nid, ctx }) => {
|
||||||
|
if (data.length != 3) argCount(">",2,data.pos);
|
||||||
|
let param1 = execute({ data: data[1], target});
|
||||||
|
let param2 = execute({ data: data[2], target:target+1});
|
||||||
|
let outType = getOutType(param1.type,param2.type);
|
||||||
|
return {
|
||||||
|
type: COMPUTE_TYPES.UINT,
|
||||||
|
code: `${param1.code}
|
||||||
|
${convertType(param1.type, outType, target) }
|
||||||
|
${param2.code}
|
||||||
|
${convertType(param2.type, outType, target+1)}
|
||||||
|
${ (["CMPU", "CMP", "FCMP"])[outType] } $${ target },$${ target },$${ target + 1 }
|
||||||
|
ZSP $${target},$${target},1`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"!=": ({ execute, data, target, nid, ctx }) => {
|
||||||
|
if (data.length != 3) argCount("!=",2,data.pos);
|
||||||
|
let param1 = execute({ data: data[1], target});
|
||||||
|
let param2 = execute({ data: data[2], target:target+1});
|
||||||
|
let outType = getOutType(param1.type,param2.type);
|
||||||
|
return {
|
||||||
|
type: COMPUTE_TYPES.UINT,
|
||||||
|
code: `${param1.code}
|
||||||
|
${convertType(param1.type, outType, target) }
|
||||||
|
${param2.code}
|
||||||
|
${convertType(param2.type, outType, target+1)}
|
||||||
|
${ (["CMPU", "CMP", "FCMP"])[outType] } $${ target },$${ target },$${ target + 1 }
|
||||||
|
ZSNZ $${target},$${target},1`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"!": ({ execute, data, target, nid, ctx }) => {
|
||||||
|
if (data.length != 2) argCount("!", 1, data.pos);
|
||||||
|
let param = execute({ data: data[1], target });
|
||||||
|
return {
|
||||||
|
type: COMPUTE_TYPES.UINT,
|
||||||
|
code: `${param.code}
|
||||||
|
${(["CMPU", "CMP", "FCMP"])[param.type]} $${target},$${target},0
|
||||||
|
ZSZ $${target},$${target},1`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"!!": ({ execute, data, target, nid, ctx }) => {
|
||||||
|
if (data.length != 2) argCount("!!", 1, data.pos);
|
||||||
|
let param = execute({ data: data[1], target });
|
||||||
|
return {
|
||||||
|
type: COMPUTE_TYPES.UINT,
|
||||||
|
code: `${param.code}
|
||||||
|
${(["CMPU", "CMP", "FCMP"])[param.type]} $${target},$${target},0
|
||||||
|
ZSNZ $${target},$${target},1`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
33
js/nativefuncs/lanes.js
Normal file
33
js/nativefuncs/lanes.js
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
import { argsCount } from "../errors.js";
|
||||||
|
|
||||||
|
|
||||||
|
export default {
|
||||||
|
progn: ({ execute, data, target, nid, ctx }) => {
|
||||||
|
if (data.length < 2) argsCount("progn", 1, data.pos);
|
||||||
|
let newctx = ctx.nextLevel();
|
||||||
|
return {
|
||||||
|
type: 0,
|
||||||
|
code: `//new code Block
|
||||||
|
${data.array.slice(1).map(d => execute({ data: d, target, ctx: newctx })).join("\n")}
|
||||||
|
//end Code Block`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
if: ({ execute, data, target, nid, ctx }) => {
|
||||||
|
if (data.length < 3) argsCount("if", 2, data.pos);
|
||||||
|
let condition = execute({ data: data[1], target });
|
||||||
|
let id1 = nid();
|
||||||
|
let id2 = nid();
|
||||||
|
return {
|
||||||
|
type: 0,
|
||||||
|
code: `//if
|
||||||
|
${condition.code}
|
||||||
|
BZ $${target},else${id1}
|
||||||
|
${execute({ data: data[2] }).code}
|
||||||
|
${data.length > 3 ? "JMP fi" + id2 : ""}
|
||||||
|
else${id1} SWYM
|
||||||
|
${data.length > 3 ? execute({ data: data[2] }).code : ""}
|
||||||
|
fi${id2} SWYM
|
||||||
|
`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
81
js/nativefuncs/math.js
Normal file
81
js/nativefuncs/math.js
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
import { argsCount } from "../errors.js";
|
||||||
|
import { convertType, getOutType } from "../types.js"
|
||||||
|
|
||||||
|
export default {
|
||||||
|
"+": ({ execute, data, target, nid, ctx }) => {
|
||||||
|
if (data.length < 3) argsCount("+",2,data.pos);
|
||||||
|
let params = data.array.slice(1).map((d, i) => execute({ data: d, target: target + (i ? 0 : 1) }));
|
||||||
|
let outType = getOutType(...params.map(d => d.type));
|
||||||
|
return {
|
||||||
|
type: outType,
|
||||||
|
code: params.map((d, i) => {
|
||||||
|
if (i == 0) return [
|
||||||
|
d.code,
|
||||||
|
convertType(d.type, outType, target)
|
||||||
|
];
|
||||||
|
return [
|
||||||
|
d.code,
|
||||||
|
convertType(d.type, outType, target + 1),
|
||||||
|
` ${(["ADDU", "ADD", "FADD"])[outType]} $${target},$${target},$${target + 1}`
|
||||||
|
];
|
||||||
|
}).flat(Infinity).join("\n")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"-": ({ execute, data, target, nid, ctx }) => {
|
||||||
|
if (data.length < 3) argsCount("-", 2, data.pos);
|
||||||
|
let params = data.array.slice(1).map((d, i) => execute({ data: d, target: target + (i ? 0 : 1) }));
|
||||||
|
let outType = getOutType(...params.map(d => d.type));
|
||||||
|
return {
|
||||||
|
type: outType,
|
||||||
|
code: params.map((d, i) => {
|
||||||
|
if (i == 0) return [
|
||||||
|
d.code,
|
||||||
|
convertType(d.type, outType, target)
|
||||||
|
];
|
||||||
|
return [
|
||||||
|
d.code,
|
||||||
|
convertType(d.type, outType, target + 1),
|
||||||
|
` ${(["SUBU", "SUB", "FSUB"])[outType]} $${target},$${target},$${target + 1}`
|
||||||
|
];
|
||||||
|
}).flat(Infinity).join("\n")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"*": ({ execute, data, target, nid, ctx }) => {
|
||||||
|
if (data.length < 3) argsCount("*", 2, data.pos);
|
||||||
|
let params = data.array.slice(1).map((d, i) => execute({ data: d, target: target + (i ? 0 : 1) }));
|
||||||
|
let outType = getOutType(...params.map(d => d.type));
|
||||||
|
return {
|
||||||
|
type: outType,
|
||||||
|
code: params.map((d, i) => {
|
||||||
|
if (i == 0) return [
|
||||||
|
d.code,
|
||||||
|
convertType(d.type, outType, target)
|
||||||
|
];
|
||||||
|
return [
|
||||||
|
d.code,
|
||||||
|
convertType(d.type, outType, target + 1),
|
||||||
|
` ${(["MULU", "MUL", "FMUL"])[outType]} $${target},$${target},$${target + 1}`
|
||||||
|
];
|
||||||
|
}).flat(Infinity).join("\n")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/": ({ execute, data, target, nid, ctx }) => {
|
||||||
|
if (data.length < 3) argsCount("/", 2, data.pos);
|
||||||
|
let params = data.array.slice(1).map((d, i) => execute({ data: d, target: target + (i ? 0 : 1) }));
|
||||||
|
let outType = getOutType(...params.map(d => d.type));
|
||||||
|
return {
|
||||||
|
type: outType,
|
||||||
|
code: params.map((d, i) => {
|
||||||
|
if (i == 0) return [
|
||||||
|
d.code,
|
||||||
|
convertType(d.type, outType, target)
|
||||||
|
];
|
||||||
|
return [
|
||||||
|
d.code,
|
||||||
|
convertType(d.type, outType, target + 1),
|
||||||
|
` ${(["DIVU", "DIV", "FDIV"])[outType]} $${target},$${target},$${target + 1}`
|
||||||
|
];
|
||||||
|
}).flat(Infinity).join("\n")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
40
js/nativefuncs/sys.js
Normal file
40
js/nativefuncs/sys.js
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
|
||||||
|
|
||||||
|
export default {
|
||||||
|
assm: ({ execute, data, target, nid, ctx }) => {
|
||||||
|
let cmds = data.array.slice(1, -1);
|
||||||
|
let type = data.array.slice(-1)[0];
|
||||||
|
return {
|
||||||
|
code: "\n" + cmds.map(d => {
|
||||||
|
let out = d.slice(1, -1);
|
||||||
|
([["?7", 7], ["?6", 6], ["?5", 5], ["?4", 4], ["?3", 3], ["?2", 2], ["?1", 1], ["?0", 0]]).map(a => {
|
||||||
|
out = out.split(a[0]).join("$" + (target + a[1]));
|
||||||
|
});
|
||||||
|
return out;
|
||||||
|
}).join("\n") + "\n",
|
||||||
|
type
|
||||||
|
};
|
||||||
|
},
|
||||||
|
printRaw: ({ execute, data, target, nid, ctx }) => {
|
||||||
|
let { code, type } = execute({ data: data[1], target: target });
|
||||||
|
return {
|
||||||
|
code: `${code}
|
||||||
|
SET $255,$${target}
|
||||||
|
TRAP 0,Fputs,StdOut`,
|
||||||
|
type
|
||||||
|
};
|
||||||
|
},
|
||||||
|
addr: ({ execute, data, target, nid, ctx }) => {
|
||||||
|
let nv = ctx.find(data[1], "V");
|
||||||
|
return {
|
||||||
|
code: ` LDA $${target},${nv.name}`,
|
||||||
|
type: 0
|
||||||
|
};
|
||||||
|
},
|
||||||
|
exit: () => {
|
||||||
|
return {
|
||||||
|
code: " TRAP 0,Halt,0",
|
||||||
|
type: 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
56
js/nativefuncs/vars.js
Normal file
56
js/nativefuncs/vars.js
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
import { createType, error, LISPcmd } from "../lexer.js";
|
||||||
|
import { COMPUTE_TYPES, convertType } from "../types.js";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
defvar: ({ execute, data, target, nid, ctx }) => {
|
||||||
|
let param = data[3];
|
||||||
|
let [type, d] = createType(param);
|
||||||
|
|
||||||
|
let varType = ctx.getType(data[2]);
|
||||||
|
if (varType.content) error("A variable only can be created with a primitive Type.", ...data[2].pos);
|
||||||
|
|
||||||
|
if (type == "var" || type == "code") {
|
||||||
|
error("devfar with input is not implemented yet.", ...param.pos)
|
||||||
|
} else {
|
||||||
|
ctx.add({ name: data[1], vType: "V", size: varType.size, amount: 1, type: varType.type, content: param });
|
||||||
|
return {
|
||||||
|
code: "",
|
||||||
|
type: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
set: ({ execute, data, target, nid, ctx }) => {
|
||||||
|
let toSet = ctx.find(data[1],"V");
|
||||||
|
let { code, type } = execute({ data: data[2], target });
|
||||||
|
if(toSet.type == COMPUTE_TYPES.FLOAT){
|
||||||
|
return {
|
||||||
|
code: `${code}
|
||||||
|
${convertType(type, toSet.type, target)}
|
||||||
|
${toSet.size > 4 ? "STOU" : "STSF"} $${target},${toSet.name}`,
|
||||||
|
type: toSet.type
|
||||||
|
};
|
||||||
|
|
||||||
|
}else{
|
||||||
|
return {
|
||||||
|
code: `${code}
|
||||||
|
${convertType(type, toSet.type, target)}
|
||||||
|
ST${(["B", "W", "T", "T", "O", "O", "O", "O"])[toSet.size - 1]}${type == 0 ? "U" : ""} $${target},${toSet.name}`,
|
||||||
|
type: toSet.type
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
defarr: ({ execute, data, target, nid, ctx }) => {
|
||||||
|
let param = data.array.slice(3, -1).map(d => Number(d));
|
||||||
|
|
||||||
|
let varType = ctx.getType(data[2]);
|
||||||
|
let amount = param.reduce((v, c) => v * c, 1);
|
||||||
|
|
||||||
|
ctx.add({ name: data[1], vType:"V", size: varType.size, amount: amount, type: varType.type, config: param, content: data.array.slice(-1)[0] });
|
||||||
|
|
||||||
|
return {
|
||||||
|
code: "",
|
||||||
|
type: 0
|
||||||
|
};
|
||||||
|
},
|
||||||
|
}
|
|
@ -33,7 +33,6 @@ export const convertType = (typein,typeout,reg) => {
|
||||||
SET $${reg + 1},#7fffffffffffffff
|
SET $${reg + 1},#7fffffffffffffff
|
||||||
AND $${reg},$${reg},$${reg+1}`;
|
AND $${reg},$${reg},$${reg+1}`;
|
||||||
}
|
}
|
||||||
console.log(typein,typeout)
|
|
||||||
error("[System error] Could not find a possible Type conversion.")
|
error("[System error] Could not find a possible Type conversion.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
4
main.js
4
main.js
|
@ -17,11 +17,11 @@ let code = "";
|
||||||
var ctx = new context();
|
var ctx = new context();
|
||||||
for (var i = 0; i < data.length; i++) {
|
for (var i = 0; i < data.length; i++) {
|
||||||
let { code: c, type } = execute({ data: data[i], ctx });
|
let { code: c, type } = execute({ data: data[i], ctx });
|
||||||
code += c;
|
if(c=="")continue;
|
||||||
|
code += c+"\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = ctx.build();
|
let result = ctx.build();
|
||||||
result+=code;
|
result+=code;
|
||||||
console.log(result);
|
|
||||||
fs.writeFileSync(pathout, result);
|
fs.writeFileSync(pathout, result);
|
||||||
console.log(`Finished compiling in ${Math.round(performance.now()) / 1000}sec. Assembly saved to: ${pathout}`);
|
console.log(`Finished compiling in ${Math.round(performance.now()) / 1000}sec. Assembly saved to: ${pathout}`);
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"type":"module",
|
"type":"module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
|
"run": "node . test.lisp test.mms && mmixal test.mms && mmix test.mmo"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|
Loading…
Reference in a new issue