From 40b0b585e17f084dd1e0f20f6b785ecf9f618a99 Mon Sep 17 00:00:00 2001 From: Daniel Xie Date: Mon, 14 Nov 2016 00:42:31 -0600 Subject: [PATCH] Added InputStream, Tokenizer, and Parser(unfinished) class. Changed Newerth to Aevum --- src/Company.js | 4 +- src/Faction.js | 5 +- src/Netscript/InputStream.js | 25 +++++ src/Netscript/Parser.js | 10 ++ src/Netscript/Tokenizer.js | 172 +++++++++++++++++++++++++++++++++++ src/Player.js | 2 +- src/Server.js | 12 ++- 7 files changed, 220 insertions(+), 10 deletions(-) create mode 100644 src/Netscript/InputStream.js create mode 100644 src/Netscript/Parser.js create mode 100644 src/Netscript/Tokenizer.js diff --git a/src/Company.js b/src/Company.js index c542293ba..09f984abb 100644 --- a/src/Company.js +++ b/src/Company.js @@ -238,7 +238,7 @@ Companies = { LexoCorp: new Company(), RhoConstruction: new Company(), AlphaEnterprises: new Company(), - NewerthPolice: new Company(), + AevumPolice: new Company(), SysCoreSecurities: new Company(), CompuTek: new Company(), NetLinkTechnologies: new Company(), @@ -294,7 +294,7 @@ Companies = { Companies.LexoCorp.init("LexoCorp", 1.4, 1.4); Companies.RhoConstruction.init("Rho Construction", 1.3, 1.3); Companies.AlphaEnterprises.init("Alpha Enterprises", 1.5, 1.5); - Companies.NewerthPolice.init("Newerth Police", 1.3, 1.3); + Companies.AevumPolice.init("Aevum Police", 1.3, 1.3); Companies.SysCoreSecurities.init("SysCore Securities", 1.3, 1.3); Companies.CompuTek.init("CompuTek", 1.2, 1.2); Companies.NetLinkTechnologies.init("NetLink Technologies", 1.2, 1.2); diff --git a/src/Faction.js b/src/Faction.js index 263fe29a2..4b6adca21 100644 --- a/src/Faction.js +++ b/src/Faction.js @@ -41,6 +41,7 @@ Factions = { BlackHand: new Faction("The Black Hand"); NiteSec: new Faction("NiteSec"); - //City factions, essentially governments - Newerth: new Faction("Newerth"); + //City factions, essentially governments and gangs + Aevum: new Faction("Aevum"); + Ishima: new Faction("Ishima"); } \ No newline at end of file diff --git a/src/Netscript/InputStream.js b/src/Netscript/InputStream.js new file mode 100644 index 000000000..99ffddbb7 --- /dev/null +++ b/src/Netscript/InputStream.js @@ -0,0 +1,25 @@ +/* InputStream class. Creates a "stream object" that provides operations to read + * from a string. */ +function InputStream(input) { + var pos = 0, line = 1, col = 0; + return { + next : next, + peek : peek, + eof : eof, + croak : croak, + }; + function next() { + var ch = input.charAt(pos++); + if (ch == "\n") line++, col = 0; else col++; + return ch; + } + function peek() { + return input.charAt(pos); + } + function eof() { + return peek() == ""; + } + function croak(msg) { + throw new Error(msg + " (" + line + ":" + col + ")"); + } +} \ No newline at end of file diff --git a/src/Netscript/Parser.js b/src/Netscript/Parser.js new file mode 100644 index 000000000..61d4e12ac --- /dev/null +++ b/src/Netscript/Parser.js @@ -0,0 +1,10 @@ +/* Parser + * Creates Abstract Syntax Tree Nodes + * Operates on a stream of tokens from the Tokenizer + */ + +var FALSE = {type: "bool", value: false}; + +function Parser(input) { + +} \ No newline at end of file diff --git a/src/Netscript/Tokenizer.js b/src/Netscript/Tokenizer.js new file mode 100644 index 000000000..5575bb67e --- /dev/null +++ b/src/Netscript/Tokenizer.js @@ -0,0 +1,172 @@ +/* Tokenizer + * Acts on top of the InputStream class. Takes in a character input stream and and parses it into tokens. + * Tokens can be accessed with peek() and next(). + * + * Token types: + * {type: "punc", value: "(" } // punctuation: parens, comma, semicolon etc. + * {type: "num", value: 5 } // numbers + * {type: "str", value: "Hello World!" } // strings + * {type: "kw", value: "lambda" } // keywords + * {type: "var", value: "a" } // identifiers + * {type: "op", value: "!=" } // operators + * + * + * + * + * + * + * + * + * + * + */ + +function Tokenizer(input) { + var current = null; + var keywords = " if then else true false while for "; + + return { + next : next, + peek : peek, + eof : eof, + croak : input.croak + } + + function is_keyword(x) { + return keywords.indexOf(" " + x + " ") >= 0; + } + + function is_digit(ch) { + return /[0-9]/i.test(ch); + } + + //An identifier can start with any letter or an underscore + function is_id_start(ch) { + return /[a-z_]/i.test(ch); + } + + function is_id(ch) { + return is_id_start(ch) || "?!-<>=0123456789".indexOf(ch) >= 0; + } + + function is_op_char(ch) { + return "+-*/%=&|<>!".indexOf(ch) >= 0; + } + + function is_punc(ch) { + return ",;(){}[]".indexOf(ch) >= 0; + } + + function is_whitespace(ch) { + return " \t\n".indexOf(ch) >= 0; + } + + function read_while(predicate) { + var str = ""; + while (!input.eof() && predicate(input.peek())) + str += input.next(); + return str; + } + + function read_number() { + var has_dot = false; + //Reads the number from the input. Checks for only a single decimal point + var number = read_while(function(ch){ + if (ch == ".") { + if (has_dot) return false; + has_dot = true; + return true; + } + return is_digit(ch); + }); + return { type: "num", value: parseFloat(number) }; + } + + //This function also checks the identifier against a list of known keywords (defined at the top) + //and will return a kw object rather than identifier if it is one + function read_ident() { + //Identifier must start with a letter or underscore..and can contain anything from ?!-<>=0123456789 + var id = read_while(is_id); + return { + type : is_keyword(id) ? "kw" : "var", + value : id + }; + } + + function read_escaped(end) { + var escaped = false, str = ""; + input.next(); //Skip the quotation mark + while (!input.eof()) { + var ch = input.next(); + if (escaped) { + str += ch; + escaped = false; + } else if (ch == "\\") { + escaped = true; + } else if (ch == end) { + break; + } else { + str += ch; + } + } + return str; + } + + function read_string() { + return { type: "str", value: read_escaped('"') }; + } + + //Only supports single-line comments right now + function skip_comment() { + read_while(function(ch){ return ch != "\n" }); + input.next(); + } + + //Gets the next token + function read_next() { + //Skip over whitespace + read_while(is_whitespace); + + if (input.eof()) return null; + + //Peek the next character and decide what to do based on what that + //next character is + var ch = input.peek(); + + if (ch == "//") { + skip_comment(); + return read_next(); + } + + if (ch == '"') return read_string(); + if (is_digit(ch)) return read_number(); + if (is_id_start(ch)) return read_ident(); + if (is_punc(ch)) return { + type : "punc", + value : input.next() + } + if (is_op_char(ch)) return { + type : "op", + value : read_while(is_op_char) + } + + } + + function peek() { + //Returns current token, unless its null in which case it grabs the next one + //and returns it + return current || (current = read_next()); + } + + function next() { + //The token might have been peaked already, in which case read_next() was already + //called so just return current + var tok = current; + current = null; + return tok || read_next(); + } + + function eof() { + return peek() == null; + } +} diff --git a/src/Player.js b/src/Player.js index 08aebb561..38d86007c 100644 --- a/src/Player.js +++ b/src/Player.js @@ -87,7 +87,7 @@ var Player = { }, //Calculates skill level based on experience. The same formula will be used for every skill - // At the maximum possible exp (MAX_INT = 9007199254740991), the hacking skill will by 1796 + // At the maximum possible exp (MAX_INT = 9007199254740991), the hacking skill will be 1796 // Gets to level 1000 hacking skill at ~1,100,000,000 exp calculateSkill: function(exp) { return Math.max(Math.floor(50 * log(9007199254740991+ 2.270) - 40), 1); diff --git a/src/Server.js b/src/Server.js index 5c9f08876..60333d310 100644 --- a/src/Server.js +++ b/src/Server.js @@ -95,6 +95,8 @@ ForeignServers = { //TODO add "secret" servers for factions and anything else? These are servers //that do not get connected to anything in the createNetwork() function //Secret Servers + world_daemon: new Server(), //Final server for 2nd tier prestige. Discover that the world is a simulation + //Megacorporations (each one forms its own faction?) @@ -141,7 +143,7 @@ ForeignServers = { LexoCorp: new Server(), //Group6 RhoConstruction: new Server(), //Group6 AlphaEnterprises: new Server(), //Group6 - NewerthPolice: new Server(), //Group6 + AevumPolice: new Server(), //Group6 RothmanUniversity: new Server(), //Group5 ZBInstituteOfTechnology: new Server(), //Group5 SummitUniversity: new Server(), //Group5 @@ -320,9 +322,9 @@ ForeignServers = { ForeignServers.AlphaEnterprises.setHackingParameters(550, 800000000, 60, 55); ForeignServers.AlphaEnterprises.setPortProperties(4); - ForeignServers.NewerthPolice.init(createRandomIp(), "newerth-police", "Newerth Police Network", true, false, false, false, 160); - ForeignServers.NewerthPolice.setHackingParameters(425, 100000000, 75, 40); - ForeignServers.NewerthPolice.setPortProperties(4); + ForeignServers.AevumPolice.init(createRandomIp(), "aevum-police", "Aevum Police Network", true, false, false, false, 160); + ForeignServers.AevumPolice.setHackingParameters(425, 100000000, 75, 40); + ForeignServers.AevumPolice.setPortProperties(4); ForeignServers.RothmanUniversity.init(createRandomIp(), "rothman-uni", "Rothman University Network", true, false, false, false, 160); ForeignServers.RothmanUniversity.setHackingParameters(400, 250000000, 50, 40); @@ -444,7 +446,7 @@ ForeignServers = { var NetworkGroup3 = [ForeignServers.OmegaSoftware, ForeignServers.Phantasy, ForeignServers.SilverHelix, ForeignServers.NeoNightclub]; var NetworkGroup4 = [ForeignServers.CrushFitnessGym, ForeignServers.NetLinkTechnologies, ForeignServers.CompuTek, ForeignServers.TheHub, ForeignServers.JohnsonOrthopedics]; var NetworkGroup5 = [ForeignServers.CatalystVentures, ForeignServers.SysCoreSecurities, ForeignServers.SummitUniversity, ForeignServers.ZBInstituteOfTechnology, ForeignServers.RothmanUniversity]; - var NetworkGroup6 = [ForeignServers.LexoCorp, ForeignServers.RhoConstruction, ForeignServers.AlphaEnterprises, ForeignServers.NewerthPolice, ForeignServers.MilleniumFitnessGym]; + var NetworkGroup6 = [ForeignServers.LexoCorp, ForeignServers.RhoConstruction, ForeignServers.AlphaEnterprises, ForeignServers.AevumPolice, ForeignServers.MilleniumFitnessGym]; var NetworkGroup7 = [ForeignServers.GlobalPharmaceuticals, ForeignServers.AeroCorp, ForeignServers.GalacticCybersystems, ForeignServers.SnapFitnessGym]; var NetworkGroup8 = [ForeignServers.DeltaOne, ForeignServers.UnitaLifeGroup, ForeignServers.OmniaCybersystems]; var NetworkGroup9 = [ForeignServers.ZeusMedical, ForeignServers.SolarisSpaceSystems, ForeignServers.UniversalEnergy, ForeignServers.IcarusMicrosystems, ForeignServers.DefComm];