mirror of
https://github.com/vgstation-coders/vgstation13.git
synced 2025-12-10 10:21:11 +00:00
NTSL code cleanup.
This commit is contained in:
@@ -5,10 +5,8 @@
|
||||
Class: n_Scanner
|
||||
An object responsible for breaking up source code into tokens for use by the parser.
|
||||
*/
|
||||
/n_Scanner
|
||||
var
|
||||
code
|
||||
list
|
||||
/datum/n_Scanner
|
||||
var/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.
|
||||
@@ -16,54 +14,50 @@
|
||||
See Also:
|
||||
- <scriptError>
|
||||
*/
|
||||
errors = new
|
||||
var/list/errors = new
|
||||
/*
|
||||
Var: warnings
|
||||
A list of non-fatal problems in the source code found by the scanner.
|
||||
*/
|
||||
warnings = new
|
||||
var/list/warnings = new
|
||||
|
||||
proc
|
||||
/*
|
||||
Proc: LoadCode
|
||||
Loads source code.
|
||||
*/
|
||||
LoadCode(c)
|
||||
code=c
|
||||
/datum/n_Scanner/proc/LoadCode(var/c)
|
||||
code=c
|
||||
|
||||
/*
|
||||
Proc: LoadCodeFromFile
|
||||
Gets the code from a file and calls <LoadCode()>.
|
||||
*/
|
||||
LoadCodeFromFile(f)
|
||||
LoadCode(file2text(f))
|
||||
/datum/n_Scanner/proc/LoadCodeFromFile(var/f)
|
||||
LoadCode(file2text(f))
|
||||
|
||||
/*
|
||||
Proc: Scan
|
||||
Runs the scanner and returns the resulting list of tokens. Ensure that <LoadCode()> has been called first.
|
||||
*/
|
||||
Scan()
|
||||
/datum/n_Scanner/proc/Scan()
|
||||
|
||||
/*
|
||||
Class: nS_Scanner
|
||||
A scanner implementation for n_Script.
|
||||
*/
|
||||
/n_Scanner/nS_Scanner
|
||||
|
||||
var
|
||||
/datum/n_Scanner/nS_Scanner
|
||||
/*
|
||||
Variable: codepos
|
||||
The scanner's position in the source code.
|
||||
*/
|
||||
codepos = 1
|
||||
line = 1
|
||||
linepos = 0 //column=codepos-linepos
|
||||
n_scriptOptions/nS_Options/options
|
||||
var/codepos = 1
|
||||
var/line = 1
|
||||
var/linepos = 0 //column=codepos-linepos
|
||||
var/datum/n_scriptOptions/nS_Options/options
|
||||
|
||||
commenting = 0
|
||||
var/commenting = 0
|
||||
// 1: single-line
|
||||
// 2: multi-line
|
||||
list
|
||||
/*
|
||||
Variable: ignore
|
||||
A list of characters that are ignored by the scanner.
|
||||
@@ -71,7 +65,7 @@
|
||||
Default Value:
|
||||
Whitespace
|
||||
*/
|
||||
ignore = list(" ", "\t", "\n") //Don't add tokens for whitespace
|
||||
var/list/ignore = list(" ", "\t", "\n") //Don't add tokens for whitespace
|
||||
/*
|
||||
Variable: end_stmt
|
||||
A list of characters that end a statement. Each item may only be one character long.
|
||||
@@ -79,7 +73,7 @@
|
||||
Default Value:
|
||||
Semicolon
|
||||
*/
|
||||
end_stmt = list(";")
|
||||
var/list/end_stmt = list(";")
|
||||
/*
|
||||
Variable: string_delim
|
||||
A list of characters that can start and end strings.
|
||||
@@ -87,12 +81,12 @@
|
||||
Default Value:
|
||||
Double and single quotes.
|
||||
*/
|
||||
string_delim = list("\"", "'")
|
||||
var/list/string_delim = list("\"", "'")
|
||||
/*
|
||||
Variable: delim
|
||||
A list of characters that denote the start of a new token. This list is automatically populated.
|
||||
*/
|
||||
delim = new
|
||||
var/list/delim = new
|
||||
|
||||
/*
|
||||
Macro: COL
|
||||
@@ -106,45 +100,52 @@
|
||||
code - The source code to tokenize.
|
||||
options - An <nS_Options> object used to configure the scanner.
|
||||
*/
|
||||
New(code, n_scriptOptions/nS_Options/options)
|
||||
.=..()
|
||||
ignore+= ascii2text(13) //Carriage return
|
||||
delim += ignore + options.symbols + end_stmt + string_delim
|
||||
src.options=options
|
||||
LoadCode(code)
|
||||
/datum/n_Scanner/nS_Scanner/New(var/code, 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)
|
||||
|
||||
Scan() //Creates a list of tokens from source code
|
||||
var/list/tokens=new
|
||||
for(, src.codepos<=length(code), src.codepos++)
|
||||
/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)
|
||||
if(char=="\n")
|
||||
line++
|
||||
linepos=codepos
|
||||
var/char = copytext(code, codepos, codepos + 1)
|
||||
var/nextchar = copytext(code, codepos + 1, codepos + 2)
|
||||
if(char == "\n")
|
||||
line++
|
||||
linepos = codepos
|
||||
|
||||
if(ignore.Find(char))
|
||||
continue
|
||||
else if(char == "/")
|
||||
ReadComment()
|
||||
else if(end_stmt.Find(char))
|
||||
tokens+=new /token/end(char, line, COL)
|
||||
else if(string_delim.Find(char))
|
||||
codepos++ //skip string delimiter
|
||||
tokens+=ReadString(char)
|
||||
else if(options.CanStartID(char))
|
||||
tokens+=ReadWord()
|
||||
else if(options.IsDigit(char))
|
||||
tokens+=ReadNumber()
|
||||
else if(options.symbols.Find(char))
|
||||
tokens+=ReadSymbol()
|
||||
if(ignore.Find(char))
|
||||
continue
|
||||
|
||||
else if(char == "/" && (nextchar == "*" || nextchar == "/"))
|
||||
ReadComment()
|
||||
|
||||
else if(end_stmt.Find(char))
|
||||
tokens += new/datum/token/end(char, line, COL)
|
||||
|
||||
else if(string_delim.Find(char))
|
||||
codepos++ //skip string delimiter
|
||||
tokens += ReadString(char)
|
||||
|
||||
else if(options.CanStartID(char))
|
||||
tokens += ReadWord()
|
||||
|
||||
else if(options.IsDigit(char))
|
||||
tokens += ReadNumber()
|
||||
|
||||
else if(options.symbols.Find(char))
|
||||
tokens += ReadSymbol()
|
||||
|
||||
|
||||
codepos=initial(codepos)
|
||||
line=initial(line)
|
||||
linepos=initial(linepos)
|
||||
return tokens
|
||||
codepos = initial(codepos)
|
||||
line = initial(line)
|
||||
linepos = initial(linepos)
|
||||
return tokens
|
||||
|
||||
|
||||
proc
|
||||
/*
|
||||
Proc: ReadString
|
||||
Reads a string in the source code into a token.
|
||||
@@ -152,136 +153,139 @@
|
||||
Parameters:
|
||||
start - The character used to start the string.
|
||||
*/
|
||||
ReadString(start)
|
||||
var
|
||||
buf
|
||||
for(, codepos <= length(code), codepos++)//codepos to length(code))
|
||||
var/char=copytext(code, codepos, codepos+1)
|
||||
/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)
|
||||
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)
|
||||
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)
|
||||
switch(char)
|
||||
if("\\") //Double backslash
|
||||
buf+="\\"
|
||||
if("n") //\n Newline
|
||||
buf+="\n"
|
||||
else
|
||||
if(char==start) //\" Doublequote
|
||||
buf+=start
|
||||
else //Unknown escaped text
|
||||
buf+=char
|
||||
if("\n")
|
||||
. = new/token/string(buf, line, COL)
|
||||
errors+=new/scriptError("Unterminated string. Newline reached.", .)
|
||||
line++
|
||||
linepos=codepos
|
||||
break
|
||||
if("\\") //Double backslash
|
||||
buf += "\\"
|
||||
if("n") //\n Newline
|
||||
buf += "\n"
|
||||
else
|
||||
if(char==start) //string delimiter found, end string
|
||||
break
|
||||
else
|
||||
buf+=char //Just a normal character in a string
|
||||
if(!.) return new/token/string(buf, line, COL)
|
||||
if(char == start) //\" Doublequote
|
||||
buf += start
|
||||
else //Unknown escaped text
|
||||
buf += char
|
||||
if("\n")
|
||||
. = new/datum/token/string(buf, line, COL)
|
||||
errors += new/datum/scriptError("Unterminated string. Newline reached.", .)
|
||||
line++
|
||||
linepos = codepos
|
||||
break
|
||||
else
|
||||
if(char == start) //string delimiter found, end string
|
||||
break
|
||||
else
|
||||
buf += char //Just a normal character in a string
|
||||
if(!.)
|
||||
return new/datum/token/string(buf, line, COL)
|
||||
|
||||
/*
|
||||
Proc: ReadWord
|
||||
Reads characters separated by an item in <delim> into a token.
|
||||
*/
|
||||
ReadWord()
|
||||
var
|
||||
char=copytext(code, codepos, codepos+1)
|
||||
buf
|
||||
while(!delim.Find(char) && codepos<=length(code))
|
||||
buf+=char
|
||||
char=copytext(code, ++codepos, codepos+1)
|
||||
codepos-- //allow main Scan() proc to read the delimiter
|
||||
if(options.keywords.Find(buf))
|
||||
return new /token/keyword(buf, line, COL)
|
||||
else
|
||||
return new /token/word(buf, line, COL)
|
||||
/datum/n_Scanner/nS_Scanner/proc/ReadWord()
|
||||
var/char = copytext(code, codepos, codepos + 1)
|
||||
var/buf
|
||||
|
||||
while(!delim.Find(char) && codepos <= length(code))
|
||||
buf += char
|
||||
char = copytext(code, ++codepos, codepos + 1)
|
||||
codepos-- //allow main Scan() proc to read the delimiter
|
||||
if(options.keywords.Find(buf))
|
||||
return new/datum/token/keyword(buf, line, COL)
|
||||
else
|
||||
return new/datum/token/word(buf, line, COL)
|
||||
|
||||
/*
|
||||
Proc: ReadSymbol
|
||||
Reads a symbol into a token.
|
||||
*/
|
||||
ReadSymbol()
|
||||
var
|
||||
char=copytext(code, codepos, codepos+1)
|
||||
buf
|
||||
/datum/n_Scanner/nS_Scanner/proc/ReadSymbol()
|
||||
var/char=copytext(code, codepos, codepos + 1)
|
||||
var/buf
|
||||
|
||||
while(options.symbols.Find(buf+char))
|
||||
buf+=char
|
||||
if(++codepos>length(code)) break
|
||||
char=copytext(code, codepos, codepos+1)
|
||||
while(options.symbols.Find(buf + char))
|
||||
buf += char
|
||||
if(++codepos > length(code)) break
|
||||
char = copytext(code, codepos, codepos + 1)
|
||||
|
||||
codepos-- //allow main Scan() proc to read the next character
|
||||
return new /token/symbol(buf, line, COL)
|
||||
codepos-- //allow main Scan() proc to read the next character
|
||||
return new /datum/token/symbol(buf, line, COL)
|
||||
|
||||
/*
|
||||
Proc: ReadNumber
|
||||
Reads a number into a token.
|
||||
*/
|
||||
ReadNumber()
|
||||
var
|
||||
char=copytext(code, codepos, codepos+1)
|
||||
buf
|
||||
dec=0
|
||||
/datum/n_Scanner/nS_Scanner/proc/ReadNumber()
|
||||
var/char = copytext(code, codepos, codepos + 1)
|
||||
var/buf
|
||||
var/dec = 0
|
||||
|
||||
while(options.IsDigit(char) || (char=="." && !dec))
|
||||
if(char==".") dec=1
|
||||
buf+=char
|
||||
codepos++
|
||||
char=copytext(code, codepos, codepos+1)
|
||||
var/token/number/T=new(buf, line, COL)
|
||||
if(isnull(text2num(buf)))
|
||||
errors+=new/scriptError("Bad number: ", T)
|
||||
T.value=0
|
||||
codepos-- //allow main Scan() proc to read the next character
|
||||
return T
|
||||
while(options.IsDigit(char) || (char == "." && !dec))
|
||||
if(char == ".")
|
||||
dec = 1
|
||||
|
||||
buf += char
|
||||
codepos++
|
||||
char = copytext(code, codepos, codepos + 1)
|
||||
|
||||
var/datum/token/number/T = new(buf, line, COL)
|
||||
if(isnull(text2num(buf)))
|
||||
errors += new/datum/scriptError("Bad number: ", T)
|
||||
T.value = 0
|
||||
|
||||
codepos-- //allow main Scan() proc to read the next character
|
||||
return T
|
||||
|
||||
/*
|
||||
Proc: ReadComment
|
||||
Reads a comment and outputs the type of comment
|
||||
*/
|
||||
|
||||
ReadComment()
|
||||
var
|
||||
char=copytext(code, codepos, codepos+1)
|
||||
nextchar=copytext(code, codepos+1, codepos+2)
|
||||
charstring = char+nextchar
|
||||
comm = 1
|
||||
// 1: single-line comment
|
||||
// 2: multi-line comment
|
||||
/datum/n_Scanner/nS_Scanner/proc/ReadComment()
|
||||
var/char = copytext(code, codepos, codepos + 1)
|
||||
var/nextchar = copytext(code, codepos + 1, codepos + 2)
|
||||
var/charstring = char + nextchar
|
||||
var/comm = 1
|
||||
// 1: single-line comment
|
||||
// 2: multi-line comment
|
||||
var/expectedend = 0
|
||||
|
||||
if(charstring == "//" || charstring == "/*")
|
||||
if(charstring == "/*")
|
||||
comm = 2 // starts a multi-line comment
|
||||
|
||||
while(comm)
|
||||
if(++codepos > length(code))
|
||||
break
|
||||
|
||||
if(expectedend) // ending statement expected...
|
||||
char = copytext(code, codepos, codepos + 1)
|
||||
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)
|
||||
if(char == "*")
|
||||
expectedend = 1
|
||||
continue
|
||||
else
|
||||
char = copytext(code, codepos, codepos + 1)
|
||||
if(char == "\n")
|
||||
comm = 0
|
||||
break
|
||||
|
||||
if(expectedend)
|
||||
expectedend = 0
|
||||
|
||||
if(charstring == "//" || charstring == "/*")
|
||||
if(charstring == "/*")
|
||||
comm = 2 // starts a multi-line comment
|
||||
|
||||
while(comm)
|
||||
if(++codepos>length(code)) break
|
||||
|
||||
if(expectedend) // ending statement expected...
|
||||
char = copytext(code, codepos, codepos+1)
|
||||
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)
|
||||
if(char == "*")
|
||||
expectedend = 1
|
||||
continue
|
||||
else
|
||||
char = copytext(code, codepos, codepos+1)
|
||||
if(char == "\n")
|
||||
comm = 0
|
||||
break
|
||||
|
||||
if(expectedend) expectedend = 0
|
||||
|
||||
if(comm == 2)
|
||||
errors+=new/scriptError/UnterminatedComment()
|
||||
if(comm == 2)
|
||||
errors += new/datum/scriptError/UnterminatedComment()
|
||||
|
||||
|
||||
@@ -1,38 +1,40 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33
|
||||
|
||||
/*
|
||||
Class: Token
|
||||
Represents an entity and position in the source code.
|
||||
*/
|
||||
/token
|
||||
/datum/token
|
||||
var/value
|
||||
var/line
|
||||
var/column
|
||||
|
||||
New(v, l=0, c=0)
|
||||
value=v
|
||||
line=l
|
||||
column=c
|
||||
/datum/token/New(v, l = 0, c = 0)
|
||||
value = v
|
||||
line = l
|
||||
column = c
|
||||
|
||||
string
|
||||
symbol
|
||||
word
|
||||
keyword
|
||||
number
|
||||
New()
|
||||
.=..()
|
||||
if(!isnum(value))
|
||||
value=text2num(value)
|
||||
ASSERT(!isnull(value))
|
||||
accessor
|
||||
var/object
|
||||
var/member
|
||||
/datum/token/string
|
||||
|
||||
New(object, member, l=0, c=0)
|
||||
src.object=object
|
||||
src.member=member
|
||||
src.value="[object].[member]" //for debugging only
|
||||
src.line=l
|
||||
src.column=c
|
||||
/datum/token/symbol
|
||||
|
||||
end
|
||||
/datum/token/word
|
||||
|
||||
/datum/token/keyword
|
||||
|
||||
/datum/token/number/New()
|
||||
. = ..()
|
||||
if(!isnum(value))
|
||||
value = text2num(value)
|
||||
ASSERT(!isnull(value))
|
||||
|
||||
/datum/token/accessor
|
||||
var/object
|
||||
var/member
|
||||
|
||||
/datum/token/accessor/New(object, member, l = 0, c = 0)
|
||||
src.object = object
|
||||
src.member = member
|
||||
src.value = "[object].[member]" //for debugging only
|
||||
src.line = l
|
||||
src.column = c
|
||||
|
||||
/datum/token/end
|
||||
|
||||
Reference in New Issue
Block a user