lispToMmix/js/ctx.js
2022-10-16 15:49:34 +02:00

99 lines
No EOL
3 KiB
JavaScript

import { link } from "fs";
import { error } from "./lexer.js";
let count = 0;
export class context{
#list = {};
#types = {
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 },
char: {link:"u8"},
c: {link:"u8"},
bool: {link:"u8"},
b: {link:"bool"},
};
#upper = [];
constructor(upper = null){
this.#upper = upper;
}
nextLevel(){
return new context(this);
}
add({name,vType,size,amount=1,type = 0, content = 0,config = [1]}){
if (!this.#list[vType]) this.#list[vType] = {};
this.#list[vType][name+""] = {name: vType+(count++),size,amount,type,content,config};
}
find(name, vType,pos=name.pos,quit=true){
let elem = (this.#list[vType]??{})[name+""]??null;
if (!elem && this.#upper){
elem = this.#upper.find(name+"",vType,pos,false);
}
if(!elem&&quit) error("Can not find '"+name+"' in context!",...pos);
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 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]
else type = this.#types[name];
}while(type&&type.link);*/
}
addLinkType(name,link){
this.#types[name] = {link};
}
build(){
let out = `
LOC Data_Segment
GREG @
`;
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) {
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`;
}
}
}
out +=" LOC #100\nMain SWYM\n";
return out;
}
}