99 lines
No EOL
3 KiB
JavaScript
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;
|
|
}
|
|
} |