NTSL code cleanup.

This commit is contained in:
PJB3005
2015-10-11 22:13:17 +02:00
parent 8a541b54f8
commit 1446346171
21 changed files with 2506 additions and 2393 deletions

View File

@@ -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()

View File

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