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{ 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