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