Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

[READY] NTSL refactor #4486

Merged
merged 13 commits into from Feb 24, 2019
1 change: 1 addition & 0 deletions yogstation.dme
Expand Up @@ -3115,6 +3115,7 @@
#include "yogstation\code\modules\scripting\Interpreter\Evaluation.dm"
#include "yogstation\code\modules\scripting\Interpreter\Interaction.dm"
#include "yogstation\code\modules\scripting\Interpreter\Interpreter.dm"
#include "yogstation\code\modules\scripting\Interpreter\Objects.dm"
#include "yogstation\code\modules\scripting\Interpreter\Scope.dm"
#include "yogstation\code\modules\scripting\Parser\Expressions.dm"
#include "yogstation\code\modules\scripting\Parser\Keywords.dm"
Expand Down
5 changes: 3 additions & 2 deletions yogstation/code/game/machinery/telecomms/machines/server.dm
Expand Up @@ -2,7 +2,7 @@

/obj/item/radio/server/can_receive(frequency,levels)
return FALSE // The server's radio isn't for receiving, it's for outputting. For now.

/obj/machinery/telecomms/server
//NTSL-related stuffs
var/datum/TCS_Compiler/Compiler // the compiler that compiles and runs the code
Expand All @@ -11,8 +11,9 @@
var/rawcode = "" // the code to compile (raw-ass text)
var/obj/item/radio/server/server_radio // Allows the server to talk on the radio, via broadcast() in NTSL
var/last_signal = 0 // Marks the last time an NTSL script called signal() from this server, to stop spam.
var/list/compile_warnings = list()
//End-NTSL

//NTSL-related procs
/obj/machinery/telecomms/server/Initialize()
Compiler = new()
Expand Down
50 changes: 40 additions & 10 deletions yogstation/code/modules/scripting/AST/AST Nodes.dm
Expand Up @@ -16,7 +16,7 @@
/*
Macros: Operator Precedence
The higher the value, the lower the priority in the precedence.

OOP_OR - Logical or
OOP_AND - Logical and
OOP_BIT - Bitwise operations
Expand All @@ -28,6 +28,7 @@
OOP_UNARY - Unary Operators
OOP_GROUP - Parentheses
*/
#define OOP_ASSIGN 0
#define OOP_OR 1 //||
#define OOP_AND 2 //&&
#define OOP_BIT 3 //&, |
Expand All @@ -43,6 +44,7 @@
Class: node
*/
/node
var/token/token // for line number informatino
proc
ToString()
return "[src.type]"
Expand All @@ -53,9 +55,10 @@
var
id_name

New(id)
New(id, token)
.=..()
src.id_name=id
src.token = token

ToString()
return id_name
Expand All @@ -75,22 +78,40 @@
name
precedence

New()
New(token, exp)
.=..()
if(!src.name) src.name="[src.type]"
src.token = token
src.exp = exp

ToString()
return "operator: [name]"

/node/expression/member
var/node/expression/object
var/tmp/temp_object // so you can pre-eval it, used for function calls and assignments
New(token)
src.token = token
return ..()

/node/expression/member/dot
var/node/identifier/id

/node/expression/member/brackets
var/node/expression/index
var/tmp/temp_index


/*
Class: FunctionCall
*/
/node/expression/FunctionCall
//Function calls can also be expressions or statements.
var
func_name
node/identifier/object
list/parameters=new
var/node/expression/function
var/list/parameters=list()
New(token)
.=..()
src.token = token

/*
Class: literal
Expand All @@ -117,24 +138,33 @@
id


New(ident)
New(ident, token)
.=..()
src.token = token
id=ident
if(istext(id))id=new(id)

ToString()
return src.id.ToString()

/node/expression/value/list_init
var/list/init_list

New(token)
. = ..()
src.token = token

/*
Class: reference
*/
/node/expression/value/reference
var
datum/value

New(value)
New(value, token)
.=..()
src.token = token
src.value=value

ToString()
return "ref: [src.value] ([src.value.type])"
return "ref: [src.value] ([src.value.type])"
Expand Up @@ -172,3 +172,15 @@
//
Modulo
precedence=OOP_MULTIPLY

Assign
precedence=OOP_ASSIGN
BitwiseAnd
BitwiseOr
BitwiseXor
Add
Subtract
Multiply
Divide
Power
Modulo
Expand Up @@ -45,7 +45,3 @@
//
group
precedence=OOP_GROUP

New(node/expression/exp)
src.exp=exp
return ..()
15 changes: 4 additions & 11 deletions yogstation/code/modules/scripting/AST/Statements.dm
Expand Up @@ -6,16 +6,9 @@
An object representing a single instruction run by an interpreter.
*/
/node/statement
/*
Class: FunctionCall
Represents a call to a function.
*/
//
FunctionCall
var
func_name
node/identifier/object
list/parameters=new
New(token)
.=..()
src.token=token

/*
Class: FunctionDefinition
Expand Down Expand Up @@ -123,4 +116,4 @@
//
ReturnStatement
var
node/expression/value
node/expression/value
51 changes: 44 additions & 7 deletions yogstation/code/modules/scripting/Errors.dm
Expand Up @@ -69,6 +69,12 @@
line = t.line
message = "[line]: [message]"

InvalidAssignment
message="Left side of assignment cannot be assigned to."

OutdatedScript
message = "Your script looks like it was for an older version of NTSL! Your script may not work as intended. See documentation for new syntax and API."

/*
Class: runtimeError
An error thrown by the interpreter in running the script.
Expand All @@ -81,7 +87,8 @@
A basic description as to what went wrong.
*/
message
stack/stack
scope/scope
token/token

proc
/*
Expand All @@ -90,11 +97,27 @@
*/
ToString()
. = "[name]: [message]"
if(!stack.Top()) return
.+="\nStack:"
while(stack.Top())
var/node/statement/FunctionCall/stmt=stack.Pop()
. += "\n\t [stmt.func_name]()"
if(!scope) return
var/last_line
var/last_col
if(token)
last_line = token.line
last_col = token.column
var/scope/cur_scope = scope
while(cur_scope)
if(cur_scope.function)
. += "\n\tat [cur_scope.function.func_name]([last_line]:[last_col])"
if(cur_scope.call_node && cur_scope.call_node.token)
last_line = cur_scope.call_node.token.line
last_col = cur_scope.call_node.token.column
else
last_line = null
last_col = null
cur_scope = cur_scope.parent
if(last_line)
. += "\n\tat \[global]([last_line]:[last_col])"
else
. += "\n\tat \[internal]"

TypeMismatch
name="TypeMismatchError"
Expand All @@ -111,13 +134,19 @@

UnknownInstruction
name="UnknownInstructionError"
message="Unknown instruction type. This may be due to incompatible compiler and interpreter versions or a lack of implementation."
New(node/op)
message="Unknown instruction type '[op.type]'. This may be due to incompatible compiler and interpreter versions or a lack of implementation."
Altoids1 marked this conversation as resolved.
Show resolved Hide resolved

UndefinedVariable
name="UndefinedVariableError"
New(variable)
message="Variable '[variable]' has not been declared."

IndexOutOfRange
name="IndexOutOfRangeError"
New(obj, idx)
message="Index [obj]\[[idx]] is out of range."

UndefinedFunction
name="UndefinedFunctionError"
New(function)
Expand All @@ -140,7 +169,15 @@
name="DivideByZeroError"
message="Division by zero (or a NULL value) attempted."

InvalidAssignment
message="Left side of assignment cannot be assigned to."

MaxCPU
name="MaxComputationalUse"
New(maxcycles)
message="Maximum amount of computational cycles reached (>= [maxcycles])."

Internal
name="InternalError"
New(exception/E)
message = E.name
12 changes: 12 additions & 0 deletions yogstation/code/modules/scripting/IDE.dm
Expand Up @@ -86,6 +86,18 @@
M << output("<font color = blue>TCS compilation successful!</font color>", "tcserror")
M << output("Time of compile: [gameTimestamp("hh:mm:ss")]","tcserror")
M << output("(0 errors)", "tcserror")
if(Server.compile_warnings.len)
src << output("<b>Compile Warnings</b>", "tcserror")
for(var/scriptError/e in Server.compile_warnings)
src << output("<font color = yellow>\t>[e.message]</font color>", "tcserror")
src << output("([Server.compile_warnings.len] warnings)", "tcserror")
for(var/fuck_you_for_making_me_do_this_altoids in Machine.viewingcode)
var/mob/M = fuck_you_for_making_me_do_this_altoids
if(M.client)
M << output("<b>Compile Warnings</b>", "tcserror")
for(var/scriptError/e in Server.compile_warnings)
M << output("<font color = yellow>\t>[e.message]</font color>", "tcserror")
M << output("([Server.compile_warnings.len] warnings)", "tcserror")

else
src << output(null, "tcserror")
Expand Down