diff --git a/code/__DEFINES/vv.dm b/code/__DEFINES/vv.dm index 3acd09a1a81..22e13f87f8a 100644 --- a/code/__DEFINES/vv.dm +++ b/code/__DEFINES/vv.dm @@ -18,4 +18,5 @@ #define VV_NEW_LIST "New List" #define VV_NULL "NULL" #define VV_RESTORE_DEFAULT "Restore to Default" -#define VV_MARKED_DATUM "Marked Datum" \ No newline at end of file +#define VV_MARKED_DATUM "Marked Datum" +#define VV_REGEX "Regex" \ No newline at end of file diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index 54c79d26a7f..5fb559651d5 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -547,3 +547,5 @@ proc/checkhtml(var/t) text = replacetext(text, "", "\[cell\]") text = replacetext(text, "", "\[logo\]") return text + +#define string2charlist(string) (splittext(string, regex("(\\x0A|.)")) - splittext(string, "")) \ No newline at end of file diff --git a/code/game/machinery/telecomms/telecomunications.dm b/code/game/machinery/telecomms/telecomunications.dm index 9dc30edf61e..0b9b1449137 100644 --- a/code/game/machinery/telecomms/telecomunications.dm +++ b/code/game/machinery/telecomms/telecomunications.dm @@ -436,7 +436,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list() var/totaltraffic = 0 // gigabytes (if > 1024, divide by 1024 -> terrabytes) var/list/memory = list() // stored memory - var/rawcode = "" // the code to compile (raw text) + var/list/rawcode = list() // the code to compile (list of characters) var/datum/TCS_Compiler/Compiler // the compiler that compiles and runs the code var/autoruncode = 0 // 1 if the code is set to run every time a signal is picked up @@ -516,10 +516,9 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list() relay_information(signal, "/obj/machinery/telecomms/broadcaster") -/obj/machinery/telecomms/server/proc/setcode(var/t) - if(t) - if(istext(t)) - rawcode = t +/obj/machinery/telecomms/server/proc/setcode(var/list/code) + if(istype(code)) + rawcode = code /obj/machinery/telecomms/server/proc/compile(mob/user as mob) if(Compiler) @@ -548,8 +547,8 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list() /obj/machinery/telecomms/server/proc/admin_log(var/mob/mob) var/msg="[key_name(mob)] has compiled a script to server [src]:" log_game("NTSL: [msg]") - log_game("NTSL: [rawcode]") - src.investigate_log("[msg]
[rawcode]", "ntsl") + log_game("NTSL: [rawcode.Join("")]") + src.investigate_log("[msg]
[rawcode.Join("")]", "ntsl") if(length(rawcode)) // Let's not bother the admins for empty code. message_admins("[key_name_admin(mob)] has compiled and uploaded a NTSL script to [src.id] (JMP)") diff --git a/code/game/machinery/telecomms/traffic_control.dm b/code/game/machinery/telecomms/traffic_control.dm index a2580285a38..45f0817ef55 100644 --- a/code/game/machinery/telecomms/traffic_control.dm +++ b/code/game/machinery/telecomms/traffic_control.dm @@ -117,6 +117,7 @@ function compileCode() { var codeText = cMirror_fSubmit.getValue(); document.getElementById("cMirrorPost").value = codeText; + document.getElementById("cMirrorPostList").value = JSON.stringify(codeText.split('')); document.getElementById("theform").submit(); } @@ -135,6 +136,7 @@ + "} else @@ -189,6 +191,10 @@ if(code) storedcode = code + var/list/codelist = href_list["cMirrorList"] + if(istext(codelist)) + codelist = json_decode(codelist) + add_fingerprint(user) user.set_machine(src) @@ -198,14 +204,14 @@ switch(href_list["choice"]) if("Compile") - if(!code) + if(!istype(codelist)) return 0 if(user != editingcode) return 0 //only one editor if(SelectedServer) var/obj/machinery/telecomms/server/Server = SelectedServer - Server.setcode(code) + Server.setcode(codelist) spawn(0) // Output all the compile-time errors @@ -234,7 +240,7 @@ updateUsrDialog() for(var/obj/machinery/telecomms/server/Server in servers) - Server.setcode(code) + Server.setcode(codelist) var/list/compileerrors = Server.compile(user) if(!telecomms_check(user)) return diff --git a/code/modules/admin/verbs/modifyvariables.dm b/code/modules/admin/verbs/modifyvariables.dm index dfca07426c5..c1e28a48f8d 100644 --- a/code/modules/admin/verbs/modifyvariables.dm +++ b/code/modules/admin/verbs/modifyvariables.dm @@ -46,6 +46,8 @@ var/list/VVpixelmovement = list("step_x", "step_y", "step_size", "bound_height", else if(isfile(var_value)) . = VV_FILE + else if(istype(var_value, /regex)) + . = VV_REGEX else . = VV_NULL @@ -66,6 +68,7 @@ var/list/VVpixelmovement = list("step_x", "step_y", "step_size", "bound_height", VV_DATUM_TYPE, VV_TYPE, VV_MATRIX, + VV_REGEX, VV_FILE, VV_NEW_ATOM, VV_NEW_DATUM, @@ -141,6 +144,14 @@ var/list/VVpixelmovement = list("step_x", "step_y", "step_size", "bound_height", .["class"] = null return + if(VV_REGEX) + var/reg = input("Enter regex", "Regex", "") as null|text + if(!reg) + return + .["value"] = regex(reg) + if(.["value"] == null) + .["class"] = null + if(VV_ATOM_REFERENCE) var/type = pick_closest_path(FALSE) diff --git a/code/modules/scripting/Implementations/Telecomms.dm b/code/modules/scripting/Implementations/Telecomms.dm index 16640a8b4c8..a24a9522b38 100644 --- a/code/modules/scripting/Implementations/Telecomms.dm +++ b/code/modules/scripting/Implementations/Telecomms.dm @@ -24,14 +24,22 @@ interpreter.GC() +//temp +/datum/TCS_Compiler + var/datum/n_scriptOptions/nS_Options/options + var/datum/n_Scanner/nS_Scanner/scanner + var/list/tokens + var/datum/n_Parser/nS_Parser/parser + var/datum/node/BlockDefinition/GlobalBlock/program + /* -- Compile a raw block of text -- */ -/datum/TCS_Compiler/proc/Compile(code as message) - var/datum/n_scriptOptions/nS_Options/options = new() - var/datum/n_Scanner/nS_Scanner/scanner = new(code, options) - var/list/tokens = scanner.Scan() - var/datum/n_Parser/nS_Parser/parser = new(tokens, options) - var/datum/node/BlockDefinition/GlobalBlock/program = parser.Parse() +/datum/TCS_Compiler/proc/Compile(list/code) + options = new() + scanner = new(code, options) + tokens = scanner.Scan() + parser = new(tokens, options) + program = parser.Parse() var/list/returnerrors = list() diff --git a/code/modules/scripting/Interpreter/Interpreter.dm b/code/modules/scripting/Interpreter/Interpreter.dm index 79802ff2fa5..c24e9ba5e3a 100644 --- a/code/modules/scripting/Interpreter/Interpreter.dm +++ b/code/modules/scripting/Interpreter/Interpreter.dm @@ -184,6 +184,8 @@ Runs each statement in a block of code. else RaiseError(new/datum/runtimeError/UnknownInstruction()) + CHECK_TICK + if(status) break diff --git a/code/modules/scripting/Options.dm b/code/modules/scripting/Options.dm index b27acff91d3..be471756359 100644 --- a/code/modules/scripting/Options.dm +++ b/code/modules/scripting/Options.dm @@ -36,11 +36,12 @@ File: Options if(!CanStartID(id)) //don't need to grab first char in id, since text2ascii does it automatically return 0 - if(length(id) == 1) + var/list/charmap = string2charlist(id) + if(charmap.len == 1) return 1 - for(var/i=2 to length(id)) - if(!IsValidIDChar(copytext(id, i, i + 1))) + for(var/i = 2 to charmap.len) + if(!IsValidIDChar(charmap[i])) return 0 return 1 diff --git a/code/modules/scripting/Scanner/Scanner.dm b/code/modules/scripting/Scanner/Scanner.dm index 011621c8ea8..da6a2c04803 100644 --- a/code/modules/scripting/Scanner/Scanner.dm +++ b/code/modules/scripting/Scanner/Scanner.dm @@ -6,7 +6,7 @@ An object responsible for breaking up source code into tokens for use by the parser. */ /datum/n_Scanner - var/code + var/list/code /* Var: errors A list of fatal errors found by the scanner. If there are any items in this list, then it is not safe to parse the returned tokens. @@ -25,7 +25,7 @@ Proc: LoadCode Loads source code. */ -/datum/n_Scanner/proc/LoadCode(var/c) +/datum/n_Scanner/proc/LoadCode(var/list/c) code=c /* @@ -100,24 +100,23 @@ code - The source code to tokenize. options - An object used to configure the scanner. */ -/datum/n_Scanner/nS_Scanner/New(var/code, var/datum/n_scriptOptions/nS_Options/options) +/datum/n_Scanner/nS_Scanner/New(var/list/c, var/datum/n_scriptOptions/nS_Options/options) . = ..() ignore += ascii2text(13) //Carriage return delim += ignore + options.symbols + end_stmt + string_delim src.options = options - LoadCode(code) + LoadCode(c) /datum/n_Scanner/nS_Scanner/Scan() //Creates a list of tokens from source code var/list/tokens = new - for(, src.codepos <= length(code), src.codepos++) - - var/char = copytext(code, codepos, codepos + 1) - var/nextchar = copytext(code, codepos + 1, codepos + 2) + for(, src.codepos <= code.len, src.codepos++) + var/char = code[codepos] + var/nextchar = TCOMMS_SAFE_INDEX(code, codepos + 1) if(char == "\n") line++ linepos = codepos - if(ignore.Find(char)) + if(char in ignore) continue else if(char == "/" && (nextchar == "*" || nextchar == "/")) @@ -139,6 +138,7 @@ else if(options.symbols.Find(char)) tokens += ReadSymbol() + CHECK_TICK codepos = initial(codepos) line = initial(line) @@ -155,12 +155,12 @@ */ /datum/n_Scanner/nS_Scanner/proc/ReadString(start) var/buf - for(, codepos <= length(code), codepos++)//codepos to length(code)) - var/char = copytext(code, codepos, codepos + 1) + for(, codepos <= code.len, codepos++)//codepos to length(code)) + var/char = code[codepos] switch(char) if("\\") //Backslash (\) encountered in string codepos++ //Skip next character in string, since it was escaped by a backslash - char = copytext(code, codepos, codepos+1) + char = TCOMMS_SAFE_INDEX(code, codepos) switch(char) if("\\") //Double backslash buf += "\\" @@ -190,12 +190,14 @@ Reads characters separated by an item in into a token. */ /datum/n_Scanner/nS_Scanner/proc/ReadWord() - var/char = copytext(code, codepos, codepos + 1) + var/char = code[codepos] var/buf - while(!delim.Find(char) && codepos <= length(code)) + while(!delim.Find(char)) buf += char - char = copytext(code, ++codepos, codepos + 1) + if(++codepos > code.len) break + char = code[codepos] + codepos-- //allow main Scan() proc to read the delimiter if(options.keywords.Find(buf)) return new/datum/token/keyword(buf, line, COL) @@ -207,13 +209,13 @@ Reads a symbol into a token. */ /datum/n_Scanner/nS_Scanner/proc/ReadSymbol() - var/char=copytext(code, codepos, codepos + 1) + var/char = code[codepos] var/buf while(options.symbols.Find(buf + char)) buf += char - if(++codepos > length(code)) break - char = copytext(code, codepos, codepos + 1) + if(++codepos > code.len) break + char = code[codepos] codepos-- //allow main Scan() proc to read the next character return new /datum/token/symbol(buf, line, COL) @@ -223,7 +225,7 @@ Reads a number into a token. */ /datum/n_Scanner/nS_Scanner/proc/ReadNumber() - var/char = copytext(code, codepos, codepos + 1) + var/char = code[codepos] var/buf var/dec = 0 @@ -233,7 +235,7 @@ buf += char codepos++ - char = copytext(code, codepos, codepos + 1) + char = TCOMMS_SAFE_INDEX(code, codepos) var/datum/token/number/T = new(buf, line, COL) if(isnull(text2num(buf))) @@ -249,8 +251,8 @@ */ /datum/n_Scanner/nS_Scanner/proc/ReadComment() - var/char = copytext(code, codepos, codepos + 1) - var/nextchar = copytext(code, codepos + 1, codepos + 2) + var/char = code[codepos] + var/nextchar = TCOMMS_SAFE_INDEX(code, codepos + 1) var/charstring = char + nextchar var/comm = 1 // 1: single-line comment @@ -262,23 +264,23 @@ comm = 2 // starts a multi-line comment while(comm) - if(++codepos > length(code)) + if(++codepos > code.len) break if(expectedend) // ending statement expected... - char = copytext(code, codepos, codepos + 1) + char = code[codepos] if(char == "/") // ending statement found - beak the comment comm = 0 break if(comm == 2) // multi-line comments are broken by ending statements - char = copytext(code, codepos, codepos + 1) + char = code[codepos] if(char == "*") expectedend = 1 continue else - char = copytext(code, codepos, codepos + 1) + char = code[codepos] if(char == "\n") comm = 0 break diff --git a/code/modules/scripting/__defines.dm b/code/modules/scripting/__defines.dm new file mode 100644 index 00000000000..52f30e68fdc --- /dev/null +++ b/code/modules/scripting/__defines.dm @@ -0,0 +1 @@ +#define TCOMMS_SAFE_INDEX(list, index) list.len > index ? list[index] : null diff --git a/paradise.dme b/paradise.dme index f9ee9ca47ea..dcd6fe0a002 100644 --- a/paradise.dme +++ b/paradise.dme @@ -2105,6 +2105,7 @@ #include "code\modules\research\xenobiology\xenobio_camera.dm" #include "code\modules\research\xenobiology\xenobiology.dm" #include "code\modules\ruins\ruin_areas.dm" +#include "code\modules\scripting\__defines.dm" #include "code\modules\scripting\Errors.dm" #include "code\modules\scripting\Options.dm" #include "code\modules\scripting\AST\AST Nodes.dm"