lispToMmix/js/ctx.js

169 lines
5.6 KiB
JavaScript
Raw Normal View History

2022-10-21 23:57:06 +02:00
import { error } from "./lexer.js";
let count = 0;
export class context{
#list = {
V:[]
};
#functions = {
};
#types = {
v: { size: 1,type: 0, content: false },
u8: { size: 1,type: 0, content: false },
u16: { size: 2,type: 0, content: false },
u32: { size: 4,type: 0, content: false },
u64: { size: 8,type: 0, content: false },
i8: { size: 1,type: 1, content: false },
i16: { size: 2,type: 1, content: false },
i32: { size: 4,type: 1, content: false },
i64: { size: 8,type: 1, content: false },
f32: { size: 4,type: 2, content: false },
f64: { size: 8,type: 2, content: false },
void: {link: "v"},
char: {link:"u8"},
c: {link:"u8"},
bool: {link:"u8"},
boolean: {link:"bool"},
b: {link:"bool"},
uint8_t: { link:"u8" },
uint16_t: { link:"u16" },
uint32_t: { link:"u32" },
uint64_t: { link:"u64" },
int8_t: { link:"i8" },
int16_t: { link:"i16" },
int32_t: { link:"i32" },
int64_t: { link:"i64" },
float: { link:"f32" },
double: { link:"f64" },
};
#upper = [];
#lower = [];
#isLocal = false;
constructor(upper = null,local = false){
this.#upper = upper;
this.#isLocal = local;
}
get local(){
return this.#isLocal;
}
nextLevel(local = true){
let newCon = new context(this,local||this.#isLocal);
if(!local)this.#lower.push(newCon);
return newCon;
}
add({name,vType,size,amount=1,type = 0, content = 0,config = [1]}){
if (!this.#list[vType]) this.#list[vType] = [];
let nowid = this.#list[vType].push({varName:name+"",name: vType+(count++),size,amount,type,content,config,pos:()=>{
return this.#list[vType].reduce((v,e,i)=>v+(i<nowid?(e.size*e.amount):0),0);
},used:false})-1;
return this.#list[vType][this.#list[vType].length-1];
}
find(name, vType,pos=name.pos,quit=true){
let nowId = (this.#list[vType] ?? []).findIndex((v)=>{
if(v.varName==name+"")return true;
});
//let elem = (this.#list[vType]??{})[name+""]??null;
let elem = (this.#list[vType] ?? [])[nowId]??null;
if (nowId==-1 && this.#upper){
elem = this.#upper.find(name+"",vType,pos,false);
}
if(!elem&&quit) error("Can not find '"+name+"' in Variable context!",...pos);
elem.used = true;
return elem;
}
getType(name,pos=name.pos, quit = true){
let lastName = name;
let type = this.#types[name+""];
if(!type){
if(this.#upper) type = this.#upper.getType(name+"", pos, false);
if (!type) error("Can not find '" + name + "' in Type context", ...pos);
return type;
}else{
if(type.link){
type = this.getType(type.link,pos,false);
if (!type) error("Can not find '" + name + "' in Type context", ...pos);
return type;
}else{
return type;
}
}
}
addLinkType(name,link){
this.#types[name] = {link};
}
size(){
let size = Object.entries(this.#list).reduce((va,tt)=>va+tt[1].reduce((v, e) => v + (e.size * e.amount), 0),0);
size+=8-size%8;
return size;
}
addFunction({ name, code, type = 0,args=[] }){
this.#functions[name+""] = {name:"F"+(count++),code,type,args,used:false};
return this.#functions[name+""];
}
findFunction(name){
let elem = this.#functions[name+""] ?? null;
if (!elem && this.#upper) {
elem = this.#upper.findFunction(name);
}
if (!elem) return false;
elem.used = true;
return elem;
}
buildFunctions(){
let code = "";
for(let funName in this.#functions){
const fun = this.#functions[funName];
if(!fun.used)continue;
code += `
${fun.name} SWYM
${fun.code}
`;
}
for (let i = 0; i < this.#lower.length; i++) {
const e = this.#lower[i];
code+=e.buildFunctions();
}
return code;
}
build(varsonly=false){
if(this.#isLocal) return "";
let out = ` LOC Data_Segment
GREG @
`;
if(varsonly)out="";
for(let vType in this.#list){
for(let id = 0;id<this.#list[vType].length;id++){
let { size, amount, type, content, name ,used} = this.#list[vType][id];
if(!used)continue;
if (!isNaN(content)) content = Number(content);
if (size <= 8 && amount == 1) {
out += `${name} ${(["BYTE", "WYDE", "TETRA", "TETRA", "OCTA", "OCTA", "OCTA", "OCTA"])[size - 1]} ${content}\n`;
} else {
out += `
${name} BYTE ${content}
LOC ${name}+${size * amount + 1}\n`;
}
}
}
for (let i = 0; i < this.#lower.length; i++) {
const e = this.#lower[i];
out+=e.build(true);
}
if(varsonly)return out
out += "intMask OCTA #7fffffffffffffff\n";
out += "HEAPpoint OCTA 0\n";
out += "HEAP BYTE 0\n";
out += " LOC #100\n"
out+= "Main LDA $0,HEAP\n";
out+= " STOU $0,HEAPpoint\n";
return out;
}
2022-10-14 19:30:47 +02:00
}