Post version history/View/0.1.0 BT3/Extra update

Compiled by RM, 11 March 2022 2:04 UTC "use strict"; // We of course want our code to be completely perfect, so yeah

// Imports, read entered code const fs = require("fs"); const code = fs.readFileSync("code.txt").toString.split("\n");

// Define global variables var logs = []; // Logs for good measure var doing = -1; // The line we're doing var status = 6; // The status of the compilation var hasComment = false; // If the current line we're on has a comment

var module = ""; var command = ""; var params = [];

var olr = []; // One line ram var mlr = []; // Many line ram var installed = []; // Installed modules

var loops = []; // What loops we're in right now var repeatcountdown = 0;

const showErrors = true; // If false then errors will not be consoleLogged

// Define possible modules const modules = [ "sys","math","tt","time","build" ];

// Globally used functions function getCurrentTime { // Get the current time in HH:MM:SS format return `${("00" + today.getHours).slice(-2)}:${("00" + today.getMinutes).slice(-2)}:${("00" + today.getSeconds).slice(-2)}`; }

function log(message) { // Logs a message logs.push(`${getCurrentTime}: ${message}`); }

function consoleLog(message) { // Should be used instead of console.log so if this is ported over to other JS launchers we // don't need to go scour all console.logs and change them to the one the new JS launcher supports // We just need to change this one - the single line of code below console.log(message); }

function error(message) { // Shows an error and logs it log(`Error: ${message}`); if (showErrors) { consoleLog(`Error at line ${doing + 1}:\n ${code[doing]}\n  ${message}`); } }

function isBlank(str) { // True if the string is only spaces or completely blank, else false return (!str || /^\s*$/.test(str)); // Jslint warned }

function getType(tocheck) { if (isBlank(tocheck)) { return "invalid"; } else if (tocheck.startsWith("<")) { return "varinput"; } else if (tocheck.startsWith("\"")) {   return "str";  } else if (tocheck.startsWith("'")) {    return "num";  } else if (tocheck === "true" || tocheck === "false" || tocheck === "neutral") {    return "bool";  } else if (tocheck === "null") {    return "null";  } else {    return "invalid";  } }

// Function utility functions function param(index,wantedTypes,defaultValue) { if (wantedTypes.includes("any")) { return params[index]; } else if (wantedTypes.includes(getType(params[index]))) { var jstc = getType(params[index]); if (jstc === "num" || jstc === "str") { return params[index].slice(1); } else if (jstc === "varinput") { return ""; // TEMPORARY, until we get a proper variable system } else { return params[index]; } } else { log(`On a param check, expected ${wantedTypes.join(" or ")} but got ${getType(params[index])}.`); return defaultValue; } }

function funcReturn(returned) { consoleLog(`A function returned: ${returned.toString}`); // TEMPORARY, until we have a proper function returning system // .toString is required as all functions are expected to return strings (JS types) }

// Function-specific function getRandomInteger(min,max) { return Math.floor(Math.random * (max - min) ) + min; }

var htmlBuilder = [];

var today = new Date; // TEMPORARY - Would this still be ok if its a constant const utilMonthNames = ["January","Febuary"]; const utilWeekdayNames = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];

// TEMPORARY - NEEDS REVIEW Date.prototype.getWeek = function { // Credit: https://weeknumber.com/how-to/javascript var date = new Date(this.getTime); // Jslint warned date.setHours(0, 0, 0, 0); date.setDate(date.getDate + 3 - (date.getDay + 6) % 7); var week1 = new Date(date.getFullYear, 0, 4); return 1 + Math.round(((date.getTime - week1.getTime) / 86400000 - 3 + (week1.getDay + 6) % 7) / 7); };

// TEMPORARY - NEEDS REVIEW Date.prototype.isLeapYear = function { // Credit: https://stackoverflow.com/a/26426761 var year = this.getFullYear; // Jslint warned if((year & 3) != 0) return false; // Also Jslint warned return ((year % 100) != 0 || (year % 400) === 0); };

// TEMPORARY - NEEDS REVIEW Date.prototype.getDOY = function { // Credit: Also https://stackoverflow.com/a/26426761 var dayCount = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334]; var mn = this.getMonth; var dn = this.getDate; var dayOfYear = dayCount[mn] + dn; if(mn > 1 && this.isLeapYear) dayOfYear++; return dayOfYear; };

// Start main loop while (doing <= code.length) { // Increment the line number that we are on and reset olr if (repeatcountdown === 0) { doing++; } else { repeatcountdown--; } olr = [];

// Check if it's a blank line if (isBlank(code[doing])) { log("Blank line has been passed over."); continue; }

// Escape comment and define module if (code[doing].includes("#")) { // There is a comment params = code[doing].substring(0,code[doing].indexOf("#")).split("."); hasComment = true; } else { // There is no comment params = code[doing].split("."); hasComment = false; } module = params[0];

// Is it a coating start (statement, loop, function) or coating end if (module === "end") { if (loops.slice(-1)[0] === "repeat") { // It's a repeat loop, so we break out of it     repeatcountdown = 0; loops.pop } else { // It's a statement, so we end it     continue; // TEMPORARY - need to add a way to end statements - statements not added yet } } else if (module === "repeat") { loops.push("repeat"); repeatcountdown = parseInt(params[1]); doing++; // We don't want it to run the current line (the coating top) again else it would become a ...loopception continue; }

// So, its not a coating, is there actually a module if (params.length === 1) { error("There is no command, only the module is found."); continue; }

// Is the given module actually a module and is it installed /* if (module === "install") { // A new module will be installed if (installed.includes(params[1])) { error(`Install failed: ${params[1]} is already installed.`); } else if (modules.includes(params[1])) { installed.push(params[1]); } else { error(`Install failed: ${params[1]} is not a module.`); }   continue; } else if (!installed.includes(module)) { // The module is not installed if (modules.includes(module)) { // The module does exist, its just not installed error(`The module "${module}" is not installed.`); } else { // The module doesn't exist at all error(`The module "${module}" does not exist and thus isn't installed.`); }   continue; } */

// Define command and params command = params[1]; params = params.slice(2); if (hasComment) { log(`Line ${doing + 1}: ${code[doing]}: Module:${module}, Command:${command}, Params:${params}, Has a comment`); } else { log(`Line ${doing + 1}: ${code[doing]}: Module:${module}, Command:${command}, Params:${params}, No comment`); }

// Finally, begin execute the function itself if (module === "sys") { if (command === "print") { consoleLog(param(0,["str"],"")); } else if (command === "log") { log(`${param(0,["str"],"")} (user-created)`); } else if (command === "error") { error(`${param(0,["str"],"")} (user-created)`); } else if (command === "exit") { consoleLog(`Exited with message ${param(0,["str"],"(no message)")}.`); status = 3; // We are finished, but with sys.exit - normal done is 2, sys.exit done is 3 break; } } else if (module === "math") { if (command === "plus") { funcReturn(parseInt(param(0,["num"],"0")) + parseInt(param(1,["num"],"0"))); } else if (command === "minus") { funcReturn(parseInt(param(0,["num"],"0")) - parseInt(param(1,["num"],"0"))); } else if (command === "multiply") { funcReturn(parseInt(param(0,["num"],"0")) * parseInt(param(1,["num"],"0"))); } else if (command === "divide") { funcReturn(parseInt(param(0,["num"],"0")) / parseInt(param(1,["num"],"1"))); } else if (command === "remainder") { funcReturn(parseInt(param(0,["num"],"0")) % parseInt(param(1,["num"],"1"))); } else if (command === "power") { funcReturn(parseInt(param(0,["num"],"0")) ** parseInt(param(1,["num"],"0"))); } else if (command === "sqrt") { funcReturn(Math.sqrt(parseInt(param(0,["num"],"0")))); } else if (command === "cbrt") { funcReturn(Math.cbrt(parseInt(param(0,["num"],"0")))); } else if (command === "incre") { funcReturn(parseInt(param(0,["num"],"0")) + 1); } else if (command === "decre") { funcReturn(parseInt(param(0,["num"],"0")) - 1); } else if (command === "abs") { funcReturn(Math.abs(parseInt(param(0,["num"],"0")))); } else if (command === "round") { funcReturn(Math.round(parseInt(param(0,["num"],"0")))); } else if (command === "floor") { funcReturn(Math.floor(parseInt(param(0,["num"],"0")))); } else if (command === "ceil") { funcReturn(Math.ceil(parseInt(param(0,["num"],"0")))); } else if (command === "type") { // Number is whole or decimal and negative or positive if (param(0,["num"],"0").includes(".0")) { if (param(0,["num"],"0").includes("-")) { funcReturn(["negative","whole","withDotZero"]); } else { funcReturn(["positive","whole","withDotZero"]); }     } else if (param(0,["num"],"0").includes(".")) { if (param(0,["num"],"0").includes("-")) { funcReturn(["negative","decimal","pure"]); } else { funcReturn(["positive","decimal","pure"]); }     } else { if (param(0,["num"],"0").includes("-")) { funcReturn(["negative","whole","pure"]); } else { funcReturn(["positive","whole","pure"]); }     }    } else if (command === "sin") { funcReturn(Math.sin(parseInt(param(0,["num"],"0")))); } else if (command === "cos") { funcReturn(Math.cos(parseInt(param(0,["num"],"0")))); } else if (command === "tan") { funcReturn(Math.tan(parseInt(param(0,["num"],"0")))); } else if (command === "logar") { funcReturn(Math.log(parseInt(param(0,["num"],"0")))); } else if (command === "truefalse") { if (Math.round(Math.random) === 1) { funcReturn("true"); } else { funcReturn("false"); }   } else if (command === "random") { funcReturn(getRandomInteger(parseInt(param(0,["num"],"0")),parseInt(param(1,["num"],"0")))); } } else if (module === "tt") { if (command === "gettype") { funcReturn(getType(param(0,["str"],""))); } else if (command === "isblank") { funcReturn(isBlank(param(0,["str"],""))); } else if (command === "upper") { funcReturn(param(0,["str"],"").toUpperCase); } else if (command === "lower") { funcReturn(param(0,["str"],"").toLowerCase); } else if (command === "charat") { funcReturn(param(0,["str"],"").charAt(parseInt(param(1,["num"],"0")))); } else if (command === "firstindex") { funcReturn(param(0,["str"],"").indexOf(param(1,["str"],""))); } else if (command === "lastindex") { funcReturn(param(0,["str"],"").lastIndexOf(param(1,["str"],""))); } else if (command === "startswith") { funcReturn(param(0,["str"],"").startsWith(param(1,["str"],""))); } else if (command === "endswith") { funcReturn(param(0,["str"],"").endsWith(param(1,["str"],""))); } else if (command === "includes") { funcReturn(param(0,["str"],"").includes(param(1,["str"],""))); } else if (command === "length") { funcReturn(param(0,["str"],"").length); } else if (command === "dupe") { funcReturn(param(0,["str"],"").repeat(parseInt(param(1,["num"],"0")))); } else if (command === "replace") { funcReturn(param(0,["str"],"").replace(param(1,["str"],""),param(2,["str"],""))); } else if (command === "remove") { funcReturn(param(0,["str"],"").replace(param(1,["str"],""),"")); } else if (command === "wrap") { olr[0] = param(0,["str"],""); while (olr[0].includes(" ")) { olr[0] = olr[0].replace(" "," ") }     funcReturn(olr[0]); // TEMPORARY - could be very improved performance wise } else if (command === "slice") { funcReturn(param(0,["str"],"").slice(parseInt(param(1,["num"],"0")),parseInt(param(2,["num"],"0")))); } else if (command === "split") { funcReturn(param(0,["str"],"").split(param(1,["str"],""))); } else if (command === "join") { // TEMPORARY - kinda deprecated, this should be in the list/array/dict module funcReturn(param(0,["str"],"").join(param(1,["str"],""))); } else if (command === "reverse") { funcReturn(param(0,["str"],"").split("").reverse.join("")); } else if (command === "trim") { funcReturn(param(0,["str"],"").trim); } else if (command === "trimleft") { funcReturn(param(0,["str"],"").trimLeft); } } else if (module === "time") { if (command === "format") { olr[0] = param(0,["str"],""); olr[0] = olr[0].replace("%c",Math.ceil(today.getFullYear / 100)); olr[0] = olr[0].replace("%z",`${Math.ceil(today.getFullYear.toString.slice(0,-1))}0s`); olr[0] = olr[0].replace("%y",today.getFullYear); olr[0] = olr[0].replace("%m",today.getMonth + 1); olr[0] = olr[0].replace("%M",utilMonthNames[today.getMonth]); olr[0] = olr[0].replace("%w",today.getWeek) olr[0] = olr[0].replace("%o",today.getDay) // Day of week olr[0] = olr[0].replace("%O",utilWeekdayNames[today.getDay]); olr[0] = olr[0].replace("%d",today.getDate); olr[0] = olr[0].replace("%a",today.getDOY) olr[0] = olr[0].replace("%h",today.getHours); olr[0] = olr[0].replace("%n",today.getMinutes); olr[0] = olr[0].replace("%s",today.getSeconds); olr[0] = olr[0].replace("%i",today.getMilliseconds); funcReturn(olr[0]) } else if (command === "isleap") { funcReturn(today.isLeapYear); } else if (command === "timestamp") { funcReturn(today.getTime); } else if (command === "isweekend") { if (today.getDay === 0 || today.getDay === 6) { funcReturn("true"); } else { funcReturn("false"); }   } else if (command === "fromutc") { funcReturn(today.getTimezoneOffset); } else if (command === "wait") { continue; // TEMPORARY - no function seems feasible yet } } else if (module === "build") { if (command === "reset") { htmlBuilder = []; } else if (command === "getbuilt") { funcReturn(htmlBuilder); } else if (command === "basic") { // TEMPORARY - doesn't actually work for some reason htmlBuilder.push("<!DOCTYPE html>"); htmlBuilder.push(" "); htmlBuilder.push(" "); htmlBuilder.push(``); htmlBuilder.push(``); htmlBuilder.push(` ${param(0,["str"],"")} `); htmlBuilder.push(" "); htmlBuilder.push(" "); htmlBuilder.push(" This is a really, and I mean really, basic website coded in HTML! "); htmlBuilder.push(" And this is just a normal paragraph :) ");     htmlBuilder.push(" ");    }  } } if (status === 6) {  status = 2; // We're done! } consoleLog(`<< Process done, exited with status ${status} >>   [(?)]`);