diff --git a/.gitignore b/.gitignore index f7ee883..4b49bcc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,135 +1,139 @@ -node_modules/ -test.lisp -test.mms -test.mmo - -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* -.pnpm-debug.log* - -# Diagnostic reports (https://nodejs.org/api/report.html) -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage -*.lcov - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (https://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules/ -jspm_packages/ - -# Snowpack dependency directory (https://snowpack.dev/) -web_modules/ - -# TypeScript cache -*.tsbuildinfo - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Optional stylelint cache -.stylelintcache - -# Microbundle cache -.rpt2_cache/ -.rts2_cache_cjs/ -.rts2_cache_es/ -.rts2_cache_umd/ - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variable files -.env -.env.development.local -.env.test.local -.env.production.local -.env.local - -# parcel-bundler cache (https://parceljs.org/) -.cache -.parcel-cache - -# Next.js build output -.next -out - -# Nuxt.js build / generate output -.nuxt -dist - -# Gatsby files -.cache/ -# Comment in the public line in if your project uses Gatsby and not Next.js -# https://nextjs.org/blog/next-9-1#public-directory-support -# public - -# vuepress build output -.vuepress/dist - -# vuepress v2.x temp and cache directory -.temp -.cache - -# Docusaurus cache and generated files -.docusaurus - -# Serverless directories -.serverless/ - -# FuseBox cache -.fusebox/ - -# DynamoDB Local files -.dynamodb/ - -# TernJS port file -.tern-port - -# Stores VSCode versions used for testing VSCode extensions -.vscode-test - -# yarn v2 -.yarn/cache -.yarn/unplugged -.yarn/build-state.yml -.yarn/install-state.gz +node_modules/ +test.lisp +test.mms +test.mmo + +testfun.lisp +testfun.mms +testfun.mmo + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# vuepress v2.x temp and cache directory +.temp +.cache + +# Docusaurus cache and generated files +.docusaurus + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz .pnp.* \ No newline at end of file diff --git a/js/ctx.js b/js/ctx.js index 1791a69..444d0ba 100644 --- a/js/ctx.js +++ b/js/ctx.js @@ -1,99 +1,169 @@ -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; - } +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{ - 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); -} +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); +} diff --git a/js/execute.js b/js/execute.js index f4e1680..d9f46d3 100644 --- a/js/execute.js +++ b/js/execute.js @@ -1,65 +1,142 @@ -import { context } from "./ctx.js"; -import { createType, error } from "./lexer.js"; -import nativefunc from "./nativefunc.js"; -import { COMPUTE_TYPES } from "./types.js"; - -let nid = 0; - - -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); - if(type == "code"){ - try { - 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}; - } catch (e) { - console.log(e); - error(`'${data[0]}' is not a function`,...data.pos); - } - }else if (type == "var"){ - let { size, amount, type, name } = ctx.find(d,"V",data.pos); - if (size <= 8 && amount == 1){ - if(type == COMPUTE_TYPES.FLOAT){ - return { - type: 2, - code: ` ${size > 4 ? "LDOU" :"LDSF"} $${target},${name}` - } - }else{ - return { - type: type, - code: ` LD${(["B", "W", "T", "T", "O", "O", "O", "O"])[size-1]}${type==0?"U":""} $${target},${name}` - } - } - }else{ - return { - type: 0, - code: ` LDA $${target},${name}` - } - } - - }else if (type == "bool"){ - return { - code: ` SET $${target},${d}`, - type: COMPUTE_TYPES.UINT - } - }else if (type == "num"){ - return { - code: ` SET $${target},${d}`, - type: COMPUTE_TYPES.UINT - } - }else if (type == "str"){ - - return { - code: ` SET $${target},"${d}"`, - type: COMPUTE_TYPES.UINT - } - } - throw new Error("nothing found"); +import { context } from "./ctx.js"; +import { createType, error } from "./lexer.js"; +import nativefunc from "./nativefunc.js"; +import { COMPUTE_TYPES, convertType } from "./types.js"; + +let nid = 0; + + +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); + if(type == "code"){ + let userFunc = ctx.findFunction(data[0]); + + if(userFunc){ + let params = data.array.slice(1,userFunc.args.length+1).map((d, i) => execute({ data: d, target,ctx})); + if(params.length{ + let arg = userFunc.args[i]; + return [ + p.code, + convertType(p.type,arg.type,target), + ` LDOU $${target + 1},HEAPpoint`, + ` SET $${target + 2},${ctxSize+arg.pos()}`, + ` ${arg.type == COMPUTE_TYPES.FLOAT?(arg.size > 4 ? "STOU" : "STSF"):("ST"+("BWTTOOOO")[arg.size - 1])+(arg.type == 0 ? "U" : "")} $${target},$${target + 1},$${target + 2}` + ] +}).flat(Infinity).join("\n")} + + LDOU $${target},HEAPpoint + ADDU $${target},$${target},${ctxSize} + STOU $${target},HEAPpoint + + GET $${target},rJ + PUSHJ $${target+1},${userFunc.name} + PUT rJ,$${target} + + LDOU $${target},HEAPpoint + SUBU $${target},$${target},${ctxSize} + STOU $${target},HEAPpoint + + SET $${target},$${target+1} + `; + return { + code, + type:userFunc.type.type + } + } + try { + 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}; + } catch (e) { + console.log(e); + error(`'${data[0]}' is not a function`,...data.pos); + } + }else if (type == "var"){ + let { size, amount, type, name,pos } = ctx.find(d,"V",data.pos); + if(ctx.local){ + if (size <= 8 && amount == 1) { + if (type == COMPUTE_TYPES.FLOAT) { + return { + type: 2, + code: ` LDOU $${target},HEAPpoint + SET $${target + 1},${pos()} + ${size > 4 ? "LDOU" : "LDSF"} $${target},$${target},$${target+1}` + } + } else { + return { + type: type, + code: ` LDOU $${target },HEAPpoint + SET $${target + 1},${pos()} + LD${("BWTTOOOO")[size - 1]}${type == 0 ? "U" : ""} $${target},$${target},$${target + 1}` + } + } + } else { + return { + type: 0, + code: ` LDOU $${target},HEAPpoint + SET $${target + 1},${pos()} + ADDU $${target},$${target},$${target + 1}` + } + } + }else{ + if (size <= 8 && amount == 1) { + if (type == COMPUTE_TYPES.FLOAT) { + return { + type: 2, + code: ` ${size > 4 ? "LDOU" : "LDSF"} $${target},${name}` + } + } else { + return { + type: type, + code: ` LD${("BWTTOOOO")[size - 1]}${type == 0 ? "U" : ""} $${target},${name}` + } + } + } else { + return { + type: 0, + code: ` LDA $${target},${name}` + } + } + } + + + }else if (type == "bool"){ + return { + code: ` SET $${target},${d}`, + type: COMPUTE_TYPES.UINT + } + }else if (type == "num"){ + let hex = ""; + if(Number.isInteger(d)){ + hex = d; + }else{ + var buf = new ArrayBuffer(8); + (new Float64Array(buf))[0] = d; + let ddd = (new Uint32Array(buf)); + hex ="#"; + hex+=ddd[0].toString(16); + hex+=ddd[1].toString(16); + } + + return { + code: ` SET $${target},${hex}`, + type: COMPUTE_TYPES.UINT + } + }else if (type == "str"){ + + return { + code: ` SET $${target},"${d}"`, + type: COMPUTE_TYPES.UINT + } + } + throw new Error("nothing found"); } \ No newline at end of file diff --git a/js/lexer.js b/js/lexer.js index 083f504..8330be5 100644 --- a/js/lexer.js +++ b/js/lexer.js @@ -1,182 +1,182 @@ -export class LISPstring extends String { - #l; - #c; - constructor(string, line, char) { - super(string); - this.#l = line; - this.#c = char; - } - get lineCount() { - return this.#l; - } - get charCount() { - return this.#l; - } - get pos() { - return [this.#l, this.#c]; - } -} - -export class LISPcmd extends Array { - #l; - #c; - - constructor(code, line, char) { - var childs = cutCmd(code, line, char); - - super(...childs); - this.#l = line; - this.#c = char; - } - get lineCount() { - return this.#l; - } - get charCount() { - return this.#l; - } - get pos() { - return [this.#l, this.#c]; - } - get array(){ - return new Array(...this); - } -} - -export function error(msg, l = null, c = null) { - var out = "Error" - if (l != null && c != null) out += ` in line ${l} and character ${c}`; - out += ": " + msg; - console.log("\x1b[31m", out, "\x1b[0m"); - process.exit(1); -} - -var lispSeperator = [" ", ":", "\n"]; - -function cutCmd(code, line, chars) { - if (!code.startsWith("(")) return ["", error("Compiler Error", line, chars)]; - - if (!code.endsWith(")")) return ["", error("Compiler Error", line, chars)]; - - code = code.substring(1, code.length - 1); - - var countLinesBegin = line; - var countCharsBegin = chars; - - var countLines = line; - var countChars = chars; - var inC = 0; - var wasinC = false; - var inStr = 0; - var buffer = ""; - var i = 0; - var out = []; - - function finishBuff() { - out.push( - wasinC ? - new LISPcmd(buffer.trim(), countLinesBegin, countCharsBegin) - : - new LISPstring(buffer.trim(), countLinesBegin, countCharsBegin) - ); - countLinesBegin = countLines; - countCharsBegin = countChars; - buffer = ""; - wasinC = false; - } - - for (var i = 0; i < code.length; i++) { - - countChars++; - //console.log(code,countLines,countChars); - let c = code[i]; - if (!inC && !inStr) { - countLinesBegin = countLines; - countCharsBegin = countChars; - } - if (c == "\\") { - buffer += code[++i]; - continue; - } - if (inStr) { - if (c == "\n") { - countLines++; - countChars = 0; - } else if (c == '"') { - buffer += c; - if (!inC) finishBuff(); - inStr = false; - } else { - buffer += c; - } - continue; - } - if (c == '"') { - inStr = true; - buffer += c; - continue; - } - if (c == ";" && !inC) { - while (code[++i] != "\n") { } - countLines++; - countChars = 0; - continue; - } - if (c == "\n") { - countLines++; - countChars = 0; - } - if (/*(c == " "||c=="\n")*/lispSeperator.includes(c) && !inC) { - if (buffer.trim() != "") { - finishBuff(); - } - continue; - } - if (c == "(") { - if (!inC && buffer.trim() != "") { - finishBuff(); - } - inC++; - wasinC = true; - } - if (c == ")") { - inC--; - if (inC < 0) error("Closing braket to much!", countLines, countChars); - if (!inC) { - buffer += c; - finishBuff(); - continue; - } - } - buffer += c; - - } - if (inStr) error("Missing closing quotation mark!", countLines, countChars); - if (inC) error("Missing closing braket!", countLines, countChars); - - if (buffer.trim() != "") finishBuff(); - - return out; -} - - -export function createType(data) { - if (data == "true") { - return ["bool", 1]; - } - if (data == "false") { - return ["bool", 0]; - } - /*if (data == "NaN") { - return ["num", NaN]; - }*/ - if ((data instanceof LISPstring)&&data.startsWith('"') && data.endsWith('"')){ - return ["str", data.slice(1,-1)]; - } - if ((data instanceof LISPstring) && !isNaN(data)) { - return ["num", Number(data)]; - } - if (data instanceof LISPcmd) { - return ["code", data]; - } - return ["var", data]; +export class LISPstring extends String { + #l; + #c; + constructor(string, line, char) { + super(string); + this.#l = line; + this.#c = char; + } + get lineCount() { + return this.#l; + } + get charCount() { + return this.#l; + } + get pos() { + return [this.#l, this.#c]; + } +} + +export class LISPcmd extends Array { + #l; + #c; + + constructor(code, line, char) { + var childs = cutCmd(code, line, char); + + super(...childs); + this.#l = line; + this.#c = char; + } + get lineCount() { + return this.#l; + } + get charCount() { + return this.#l; + } + get pos() { + return [this.#l, this.#c]; + } + get array(){ + return new Array(...this); + } +} + +export function error(msg, l = null, c = null) { + var out = "Error" + if (l != null && c != null) out += ` in line ${l} and character ${c}`; + out += ": " + msg; + console.log("\x1b[31m", out, "\x1b[0m"); + process.exit(1); +} + +var lispSeperator = [" ", ":", "\n"]; + +function cutCmd(code, line, chars) { + if (!code.startsWith("(")) return ["", error("Compiler Error", line, chars)]; + + if (!code.endsWith(")")) return ["", error("Compiler Error", line, chars)]; + + code = code.substring(1, code.length - 1); + + var countLinesBegin = line; + var countCharsBegin = chars; + + var countLines = line; + var countChars = chars; + var inC = 0; + var wasinC = false; + var inStr = 0; + var buffer = ""; + var i = 0; + var out = []; + + function finishBuff() { + out.push( + wasinC ? + new LISPcmd(buffer.trim(), countLinesBegin, countCharsBegin) + : + new LISPstring(buffer.trim(), countLinesBegin, countCharsBegin) + ); + countLinesBegin = countLines; + countCharsBegin = countChars; + buffer = ""; + wasinC = false; + } + + for (var i = 0; i < code.length; i++) { + + countChars++; + //console.log(code,countLines,countChars); + let c = code[i]; + if (!inC && !inStr) { + countLinesBegin = countLines; + countCharsBegin = countChars; + } + if (c == "\\") { + buffer += code[++i]; + continue; + } + if (inStr) { + if (c == "\n") { + countLines++; + countChars = 0; + } else if (c == '"') { + buffer += c; + if (!inC) finishBuff(); + inStr = false; + } else { + buffer += c; + } + continue; + } + if (c == '"') { + inStr = true; + buffer += c; + continue; + } + if (c == ";" && !inC) { + while (code[++i] != "\n") { } + countLines++; + countChars = 0; + continue; + } + if (c == "\n") { + countLines++; + countChars = 0; + } + if (/*(c == " "||c=="\n")*/lispSeperator.includes(c) && !inC) { + if (buffer.trim() != "") { + finishBuff(); + } + continue; + } + if (c == "(") { + if (!inC && buffer.trim() != "") { + finishBuff(); + } + inC++; + wasinC = true; + } + if (c == ")") { + inC--; + if (inC < 0) error("Closing braket to much!", countLines, countChars); + if (!inC) { + buffer += c; + finishBuff(); + continue; + } + } + buffer += c; + + } + if (inStr) error("Missing closing quotation mark!", countLines, countChars); + if (inC) error("Missing closing braket!", countLines, countChars); + + if (buffer.trim() != "") finishBuff(); + + return out; +} + + +export function createType(data) { + if (data == "true") { + return ["bool", 1]; + } + if (data == "false") { + return ["bool", 0]; + } + /*if (data == "NaN") { + return ["num", NaN]; + }*/ + if ((data instanceof LISPstring)&&data.startsWith('"') && data.endsWith('"')){ + return ["str", data.slice(1,-1)]; + } + if ((data instanceof LISPstring) && !isNaN(data)) { + return ["num", Number(data)]; + } + if (data instanceof LISPcmd) { + return ["code", data]; + } + return ["var", data]; } \ No newline at end of file diff --git a/js/nativefunc.js b/js/nativefunc.js index 213efe3..570f606 100644 --- a/js/nativefunc.js +++ b/js/nativefunc.js @@ -1,13 +1,13 @@ -import bool from "./nativefuncs/bool.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 { - ...math, - ...vars, - ...lanes, - ...sys, - ...bool, +import bool from "./nativefuncs/bool.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 { + ...math, + ...vars, + ...lanes, + ...sys, + ...bool, }; \ No newline at end of file diff --git a/js/nativefuncs/bool.js b/js/nativefuncs/bool.js index 9eba072..74e206b 100644 --- a/js/nativefuncs/bool.js +++ b/js/nativefuncs/bool.js @@ -1,116 +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` - } - }, +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` + } + }, }; \ No newline at end of file diff --git a/js/nativefuncs/lanes.js b/js/nativefuncs/lanes.js index 4d18b03..d48a3ea 100644 --- a/js/nativefuncs/lanes.js +++ b/js/nativefuncs/lanes.js @@ -1,33 +1,91 @@ -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 - ` - } - }, +import { argsCount } from "../errors.js"; +import { createType, error } from "../lexer.js"; + + +export default { + progn: ({ execute, data, target, nid, ctx }) => { + if (data.length < 2) argsCount("progn", 1, data.pos); + let newctx = ctx.nextLevel(false); + let content = data.array.slice(1).map(d => execute({ data: d, target: target, ctx: newctx }).code).join("\n") + return { + type: 0, + code: `//new code Block +${content} +//end Code Block` + } + }, + defun: ({ execute, data, target, nid, ctx }) => { + if(data.length < 5)argsCount("defun",4,...data[0].pos); + let newctx = ctx.nextLevel(true); + let type = ctx.getType(data[2]); + let [argType,argsList] = createType(data[3]); + if(argType!="code")error("The third Argument of defun must contain the args!",...data[3].pos); + let args = []; + if(argsList.length%2!=0)error("The Argument List must cotain an even amount of Names + Types",...data[3].pos); + for (let i = 0; i < argsList.length; i+=2) { + let name = argsList[i]; + let type = ctx.getType(argsList[i+1]); + args.push(newctx.add({name,vType:"V",size:8,type:type.type})); + + } + + let fun = ctx.addFunction({name:data[1],code:"",type,args:args}); + + let code = data.array.slice(4).map(l=>{ + let {type,code} = execute({data:l,target:0,ctx:newctx}); + return code; + }).join("\n"); + + fun.code = code; + fun.code += "\n POP 1,0"; + + return { + code:"", + type: 0 + }; + }, + return:({ execute, data, target, nid, ctx })=>{ + if(data.length == 1){ + return { + type:0, + code:` POP 1,0 + ` + } + } + let {type,code} = execute({ data: data[1], target:0}); + return { + type:0, + code:` +${code} + POP 1,0 + ` + } + }, + 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(); + if(data.length == 3){ + return { + type: 0, + code: `//if +${condition.code} + BZ $${target},fi${id1} +${execute({ data: data[2],target }).code} +fi${id1} SWYM` + } + } + return { + type: 0, + code: `//if +${condition.code} + BZ $${target},else${id1} +${execute({ data: data[2],target }).code} + JMP fi${id2} +else${id1} SWYM +${data.length > 3 ? execute({ data: data[2],target }).code : ""} +fi${id2} SWYM` + } + }, }; \ No newline at end of file diff --git a/js/nativefuncs/math.js b/js/nativefuncs/math.js index bc8bb0b..93973dd 100644 --- a/js/nativefuncs/math.js +++ b/js/nativefuncs/math.js @@ -1,81 +1,155 @@ -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") - } - }, +import { argCount, argsCount } from "../errors.js"; +import { error } from "../lexer.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 ? 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 ? 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 ? 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 ? 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") + } + }, + "round": ({ execute, data, target, nid, ctx }) => { + if (data.length < 2) argCount("round", 1, data.pos); + let param = execute({ data: data[1], target: target }); + return { + type: 1, + code: `${param.code} + ${convertType(param.type,2,target)} + FINT $${target}$${target}` + } + }, + "sqrt": ({ execute, data, target, nid, ctx }) => { + if (data.length < 2) argCount("sqrt", 1, data.pos); + let param = execute({ data: data[1], target: target }); + return { + type: 1, + code: `${param.code} + ${convertType(param.type,2,target)} + FSQRT $${target}$${target}` + } + }, + "uint": ({ execute, data, target, nid, ctx }) => { + if (data.length < 2) argCount("int", 1, data.pos); + let param = execute({ data: data[1], target: target }); + return { + type: 1, + code: `${param.code} + ${convertType(param.type,0,target)}` + } + }, + "int": ({ execute, data, target, nid, ctx }) => { + if (data.length < 2) argCount("uint", 1, data.pos); + let param = execute({ data: data[1], target: target }); + return { + type: 1, + code: `${param.code} + ${convertType(param.type,1,target)}` + } + }, + "float": ({ execute, data, target, nid, ctx }) => { + if (data.length < 2) argCount("float", 1, data.pos); + let param = execute({ data: data[1], target: target }); + return { + type: 1, + code: `${param.code} + ${convertType(param.type,2,target)}` + } + }, + "mod": ({ execute, data, target, nid, ctx }) => { + if (data.length < 3) argCount("mod", 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); + let code = `${param1.code} + ${convertType(param1.type,outType,target)} +${param2.code} +${convertType(param2.type,outType,target+1)} +`; + if(outType == 0){ + code+=` DIVU $${target},$${target},$${target+1} + GET $${target},rR`; + }else if(outType == 1){ + code+=` DIV $${target},${target},$${target+1} + GET $${target},rR`; + }else if(outType == 2){ + code+=` FREM $${target},$${target},$${target+1}`; + }else{ + error("Unexpected Type: "+outType,...data[1].pos); + } + return{ + type:outType, + code + } + }, } \ No newline at end of file diff --git a/js/nativefuncs/sys.js b/js/nativefuncs/sys.js index e557658..1758feb 100644 --- a/js/nativefuncs/sys.js +++ b/js/nativefuncs/sys.js @@ -1,40 +1,47 @@ - - -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 - } - }, +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"); + if(ctx.local){ + return { + code: ` LDOU $${target},HEAPpoint + SET $${target + 1},${nv.pos()} + ADDU $${target},$${target},$${target + 1 }`, + type: 0 + }; + + } + return { + code: ` LDA $${target},${nv.name}`, + type: 0 + }; + }, + exit: () => { + return { + code: " TRAP 0,Halt,0", + type: 0 + } + }, }; \ No newline at end of file diff --git a/js/nativefuncs/vars.js b/js/nativefuncs/vars.js index 6d00973..ce16349 100644 --- a/js/nativefuncs/vars.js +++ b/js/nativefuncs/vars.js @@ -1,56 +1,113 @@ -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 - }; - }, -} \ No newline at end of file +import { createType, error, LISPcmd } from "../lexer.js"; +import { COMPUTE_TYPES, convertType } from "../types.js"; + +const vars = { + 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" || ctx.local) { + ctx.add({ name: data[1], vType: "V", size: varType.size, amount: 1, type: varType.type, content: 0 }); + let{code,type} = vars.set({execute,data:["set", data[1], data[3]],target,nid,ctx}); + return { + code: code, + type: type + } + } else { + let content = "0"; + if(type == "num"){ + if(Number.isInteger(d)){ + content = d; + }else{ + var buf = new ArrayBuffer(8); + (new Float64Array(buf))[0] = d; + let ddd = (new Uint32Array(buf)); + content ="#"; + content+=ddd[1].toString(16); + content+=ddd[0].toString(16); + } + }else{ + content=param; + } + ctx.add({ name: data[1], vType: "V", size: varType.size, amount: 1, type: varType.type, content }); + + + 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(ctx.local){ + if (toSet.type == COMPUTE_TYPES.FLOAT) { + return { + code: `${code} +${convertType(type, toSet.type, target)} + LDOU $${target + 1},HEAPpoint + SET $${target + 2},${toSet.pos()} + ${toSet.size > 4 ? "STOU" : "STSF"} $${target},$${target+1},$${target + 2}`, + type: toSet.type + }; + + } else { + return { + code: `${code} +${convertType(type, toSet.type, target)} + LDOU $${target + 1},HEAPpoint + SET $${target + 2},${toSet.pos()} + ST${("BWTTOOOO")[toSet.size - 1]}${toSet.type == 0 ? "U" : ""} $${target},$${target + 1},$${target + 2}`, + type: toSet.type + }; + } + }else{ + 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${("BWTTOOOO")[toSet.size - 1]}${toSet.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 + }; + }, + readarr: ({ execute, data, target, nid, ctx })=>{ + let arr = ctx.find(data[1],"V"); + if (arr.config.length > data.length - 2) error(data[1] + " is a " + arr.config.length +"dim Array. You have to provide at least this much Arguments beside the Array name!",...data[1].pos); + let params = data.array.slice(2).map((d, i) => execute({ data: d, target: target })); + return{ + code:` + + `, + type:arr.type + } + } +}; + +export default vars; \ No newline at end of file diff --git a/js/preprocessor.js b/js/preprocessor.js new file mode 100644 index 0000000..fd15b5b --- /dev/null +++ b/js/preprocessor.js @@ -0,0 +1,37 @@ +import * as path from "path"; + +function join(p1,p2){ + if(p2.startsWith("/"))return p2; + return path.join(p1,"..",p2); +} +function unComment(str){ + let out = ""; + let inK = false; + for (let i = 0; i < str.length; i++) { + if(str[i] == "\\"){ + out+=str[i+1]??""; + i+=2; + }else if(str[i] == "\""){ + inK = !inK; + out += str[i]; + }else if(str[i] == ";" || str[i] == " "){ + if(inK)out += str[i]; + else break; + }else{ + out += str[i]; + } + } + return out.trim(); +} + +export default (str,filename,readFile)=>str.split("\n").map(d=>d.trim()).map((l,i)=>{ + if(!l.startsWith("#"))return l; + if(l.startsWith("#import")){ + let toImport = unComment(l.substring(8).trim()); + if(toImport.startsWith("\"") && toImport.startsWith("\"")){ + return readFile(join(filename,toImport.slice(1,-1)),i); + }else{ + return readFile("lisp/"+toImport+".lisp",i); + } + } +}).join("\n"); \ No newline at end of file diff --git a/js/types.js b/js/types.js index 16e9b18..3b32287 100644 --- a/js/types.js +++ b/js/types.js @@ -1,38 +1,38 @@ -import { error } from "./lexer.js"; - -export const COMPUTE_TYPES = { - UINT: 0, - INT: 1, - FLOAT: 2 -} - -export const getOutType = (...types)=>Math.max(...types); - -export const convertType = (typein,typeout,reg) => { - if(typein == typeout) return "//no type conversion nessesary"; - if(typein == COMPUTE_TYPES.UINT && typeout == COMPUTE_TYPES.INT){ - return "//no type conversion nessesary (u -> i)"; - } - if(typein == COMPUTE_TYPES.INT && typeout == COMPUTE_TYPES.UINT){ - return `SET $${reg + 1},#7fffffffffffffff - AND $${reg},$${reg},$${reg + 1} convert i -> u`; - } - if(typein == COMPUTE_TYPES.INT && typeout == COMPUTE_TYPES.FLOAT){ - return ` FLOT $${reg},$${reg} convert i -> f`; - } - if(typein == COMPUTE_TYPES.UINT && typeout == COMPUTE_TYPES.FLOAT){ - return `SET $${reg + 1},#7fffffffffffffff - AND $${reg},$${reg},$${reg + 1} - FLOT $${reg},$${reg} convert i -> f`; - } - if(typein == COMPUTE_TYPES.FLOAT && typeout == COMPUTE_TYPES.INT){ - return ` FIX $${reg},$${reg} convert f -> i`; - } - if(typein == COMPUTE_TYPES.FLOAT && typeout == COMPUTE_TYPES.UINT){ - return ` FLOT $${reg},$${reg} convert i -> f - SET $${reg + 1},#7fffffffffffffff - AND $${reg},$${reg},$${reg+1}`; - } - error("[System error] Could not find a possible Type conversion.") -} - +import { error } from "./lexer.js"; + +export const COMPUTE_TYPES = { + UINT: 0, + INT: 1, + FLOAT: 2 +} + +export const getOutType = (...types)=>Math.max(...types); + +export const convertType = (typein,typeout,reg) => { + if(typein == typeout) return "//no type conversion nessesary"; + if(typein == COMPUTE_TYPES.UINT && typeout == COMPUTE_TYPES.INT){ + return "//no type conversion nessesary (u -> i)"; + } + if(typein == COMPUTE_TYPES.INT && typeout == COMPUTE_TYPES.UINT){ + return ` LDOU $${reg + 1},intMask + AND $${reg},$${reg},$${reg + 1} //convert i -> u`; + } + if(typein == COMPUTE_TYPES.INT && typeout == COMPUTE_TYPES.FLOAT){ + return ` FLOT $${reg},$${reg} //convert i -> f`; + } + if(typein == COMPUTE_TYPES.UINT && typeout == COMPUTE_TYPES.FLOAT){ + return ` LDOU $${reg + 1},intMask + AND $${reg},$${reg},$${reg + 1} + FLOT $${reg},$${reg} //convert u -> f`; + } + if(typein == COMPUTE_TYPES.FLOAT && typeout == COMPUTE_TYPES.INT){ + return ` FIX $${reg},$${reg} //convert f -> i`; + } + if(typein == COMPUTE_TYPES.FLOAT && typeout == COMPUTE_TYPES.UINT){ + return ` FIX $${reg},$${reg} //convert f -> u + LDOU $${reg + 1},intMask + AND $${reg},$${reg},$${reg+1}`; + } + error("[System error] Could not find a possible Type conversion. ("+typein+", "+typeout+")"); +} + diff --git a/lisp/math.lisp b/lisp/math.lisp new file mode 100644 index 0000000..3c62e87 --- /dev/null +++ b/lisp/math.lisp @@ -0,0 +1,3 @@ +(defvar pi:f64 3.14159265358979323846) +(defvar e:f64 2.71828182845904523536) + diff --git a/main.js b/main.js index 9d68961..4c269a0 100644 --- a/main.js +++ b/main.js @@ -1,27 +1,36 @@ -import * as fs from "fs"; -import { context } from "./js/ctx.js"; -import { execute } from "./js/execute.js"; -import { LISPcmd, LISPstring, createType } from "./js/lexer.js"; -var path = process.argv[2]; -var pathout = process.argv[3]; -if (!path || !pathout) { - console.log("PLease this Schema: node ToAs.js [path] [pathout]"); - process.exit(); -} -var file = fs.readFileSync(path).toString(); - -var data = new LISPcmd("(\n" + file + "\n)", 0, 0); - - -let code = ""; -var ctx = new context(); -for (var i = 0; i < data.length; i++) { - let { code: c, type } = execute({ data: data[i], ctx }); - if(c=="")continue; - code += c+"\n"; -} - -let result = ctx.build(); -result+=code; -fs.writeFileSync(pathout, result); -console.log(`Finished compiling in ${Math.round(performance.now()) / 1000}sec. Assembly saved to: ${pathout}`); +import * as fs from "fs"; +import { context } from "./js/ctx.js"; +import { execute } from "./js/execute.js"; +import { LISPcmd, LISPstring, createType, error } from "./js/lexer.js"; +import preprocessor from "./js/preprocessor.js"; +var path = process.argv[2]; +var pathout = process.argv[3]; +if (!path || !pathout) { + console.log("PLease this Schema: node ToAs.js [path] [pathout]"); + process.exit(); +} +var file = fs.readFileSync(path).toString(); + +let strcode = preprocessor(file,path,(path,line)=>{ + try{ + return fs.readFileSync(path).toString(); + }catch(_){ + error("Can not import file: "+path+" -> "+_, line, 0); + } +}); +var data = new LISPcmd("(\n" + strcode + "\n)", 0, 0); + + +let code = ""; +var ctx = new context(); +for (var i = 0; i < data.length; i++) { + let { code: c, type } = execute({ data: data[i], ctx }); + if(c=="")continue; + code += c+"\n"; +} + +let result = ctx.build(); +result+=code; +result+=ctx.buildFunctions(); +fs.writeFileSync(pathout, result); +console.log(`Finished compiling in ${Math.round(performance.now()) / 1000}sec. Assembly saved to: ${pathout}`); diff --git a/package-lock.json b/package-lock.json index d990780..30914c6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,13 +9,44 @@ "version": "0.0.1", "license": "UNLICENSED", "dependencies": { - "fs": "^0.0.1-security" + "fs": "^0.0.1-security", + "path": "^0.12.7" } }, "node_modules/fs": { "version": "0.0.1-security", "resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz", "integrity": "sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w==" + }, + "node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" + }, + "node_modules/path": { + "version": "0.12.7", + "resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz", + "integrity": "sha512-aXXC6s+1w7otVF9UletFkFcDsJeO7lSZBPUQhtb5O0xJe8LtYhj/GxldoL09bBj9+ZmE2hNoHqQSFMN5fikh4Q==", + "dependencies": { + "process": "^0.11.1", + "util": "^0.10.3" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/util": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", + "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", + "dependencies": { + "inherits": "2.0.3" + } } }, "dependencies": { @@ -23,6 +54,33 @@ "version": "0.0.1-security", "resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz", "integrity": "sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w==" + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" + }, + "path": { + "version": "0.12.7", + "resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz", + "integrity": "sha512-aXXC6s+1w7otVF9UletFkFcDsJeO7lSZBPUQhtb5O0xJe8LtYhj/GxldoL09bBj9+ZmE2hNoHqQSFMN5fikh4Q==", + "requires": { + "process": "^0.11.1", + "util": "^0.10.3" + } + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==" + }, + "util": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", + "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", + "requires": { + "inherits": "2.0.3" + } } } } diff --git a/package.json b/package.json index 11acec4..d747317 100644 --- a/package.json +++ b/package.json @@ -3,10 +3,10 @@ "version": "0.0.1", "description": "", "main": "main.js", - "type":"module", + "type": "module", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", - "run": "node . test.lisp test.mms && mmixal test.mms && mmix test.mmo" + "run": "node . testfun.lisp testfun.mms && mmixal testfun.mms && mmix testfun.mmo" }, "repository": { "type": "git", @@ -15,6 +15,7 @@ "author": "jusax23", "license": "UNLICENSED", "dependencies": { - "fs": "^0.0.1-security" + "fs": "^0.0.1-security", + "path": "^0.12.7" } }