removed the use of globals

This commit is contained in:
Bram Dingelstad 2021-11-20 13:37:28 +01:00
parent 14f37f90c8
commit 6c565b0865
12 changed files with 618 additions and 617 deletions

View file

@ -11,6 +11,7 @@ signal node_completed(node)
signal started signal started
signal finished signal finished
const Constants = preload('res://addons/Wol/core/constants.gd')
const WolCompiler = preload('res://addons/Wol/core/compiler/compiler.gd') const WolCompiler = preload('res://addons/Wol/core/compiler/compiler.gd')
const WolDialogue = preload('res://addons/Wol/core/dialogue.gd') const WolDialogue = preload('res://addons/Wol/core/dialogue.gd')
@ -72,19 +73,19 @@ func _handle_line(line):
var id = line.id var id = line.id
var string = program.strings[id] var string = program.strings[id]
call_deferred('emit_signal', 'line', string) call_deferred('emit_signal', 'line', string)
return WolGlobals.HandlerState.PauseExecution return Constants.HandlerState.PauseExecution
func _handle_command(command): func _handle_command(command):
call_deferred('emit_signal', 'command', command) call_deferred('emit_signal', 'command', command)
if get_signal_connection_list('command').size() > 0: if get_signal_connection_list('command').size() > 0:
return WolGlobals.HandlerState.PauseExecution return Constants.HandlerState.PauseExecution
else: else:
return WolGlobals.HandlerState.ContinueExecution return Constants.HandlerState.ContinueExecution
func _handle_options(options): func _handle_options(options):
call_deferred('emit_signal' ,'options', options) call_deferred('emit_signal' ,'options', options)
return WolGlobals.HandlerState.PauseExecution return Constants.HandlerState.PauseExecution
func _handle_dialogue_complete(): func _handle_dialogue_complete():
emit_signal('finished') emit_signal('finished')
@ -105,7 +106,7 @@ func _handle_node_start(node):
func _handle_node_complete(node): func _handle_node_complete(node):
emit_signal('node_completed', node) emit_signal('node_completed', node)
running = false running = false
return WolGlobals.HandlerState.ContinueExecution return Constants.HandlerState.ContinueExecution
func select_option(id): func select_option(id):
dialogue.get_vm().set_selected_option(id) dialogue.get_vm().set_selected_option(id)

View file

@ -1,11 +1,12 @@
extends Object extends Object
class_name Compiler class_name Compiler
const Lexer = preload("res://addons/Wol/core/compiler/lexer.gd") const Constants = preload('res://addons/Wol/core/constants.gd')
const Program = preload("res://addons/Wol/core/program.gd") const Lexer = preload('res://addons/Wol/core/compiler/lexer.gd')
const Program = preload('res://addons/Wol/core/program.gd')
#patterns #patterns
const INVALIDTITLENAME = "[\\[<>\\]{}\\|:\\s#\\$]" const INVALIDTITLENAME = '[\\[<>\\]{}\\|:\\s#\\$]'
#ERROR Codes #ERROR Codes
const NO_ERROR = 0x00 const NO_ERROR = 0x00
@ -28,23 +29,23 @@ var _labelCount : int = 0
#<String, Program.Line> #<String, Program.Line>
var _stringTable : Dictionary = {} var _stringTable : Dictionary = {}
var _stringCount : int = 0 var _stringCount : int = 0
#<int, WolGlobals.TokenType> #<int, Constants.TokenType>
var _tokens : Dictionary = {} var _tokens : Dictionary = {}
static func compile_string(source: String, filename: String): static func compile_string(source: String, filename: String):
var Parser = load("res://addons/Wol/core/compiler/parser.gd") var Parser = load('res://addons/Wol/core/compiler/parser.gd')
var Compiler = load("res://addons/Wol/core/compiler/compiler.gd") var Compiler = load('res://addons/Wol/core/compiler/compiler.gd')
var compiler = Compiler.new() var compiler = Compiler.new()
compiler._fileName = filename compiler._fileName = filename
#--------------Nodes #--------------Nodes
var headerSep : RegEx = RegEx.new() var headerSep : RegEx = RegEx.new()
headerSep.compile("---(\r\n|\r|\n)") headerSep.compile('---(\r\n|\r|\n)')
var headerProperty : RegEx = RegEx.new() var headerProperty : RegEx = RegEx.new()
headerProperty.compile("(?<field>.*): *(?<value>.*)") headerProperty.compile('(?<field>.*): *(?<value>.*)')
assert(not not headerSep.search(source), "No headers found") assert(not not headerSep.search(source), 'No headers found')
var lineNumber: int = 0 var lineNumber: int = 0
@ -67,13 +68,13 @@ static func compile_string(source: String, filename: String):
if !line.empty(): if !line.empty():
var result = headerProperty.search(line) var result = headerProperty.search(line)
if result != null : if result != null :
var field : String = result.get_string("field") var field : String = result.get_string('field')
var value : String = result.get_string("value") var value : String = result.get_string('value')
if field == "title": if field == 'title':
title = value title = value
if(lineNumber >= sourceLines.size() || sourceLines[lineNumber] == "---"): if(lineNumber >= sourceLines.size() || sourceLines[lineNumber] == '---'):
break break
@ -82,7 +83,7 @@ static func compile_string(source: String, filename: String):
#past header #past header
var bodyLines : PoolStringArray = [] var bodyLines : PoolStringArray = []
while lineNumber < sourceLines.size() && sourceLines[lineNumber]!="===": while lineNumber < sourceLines.size() && sourceLines[lineNumber]!='===':
bodyLines.append(sourceLines[lineNumber]) bodyLines.append(sourceLines[lineNumber])
lineNumber+=1 lineNumber+=1
@ -117,7 +118,7 @@ static func compile_string(source: String, filename: String):
func compile_node(program, parsedNode): func compile_node(program, parsedNode):
if program.nodes.has(parsedNode.name): if program.nodes.has(parsedNode.name):
emit_error(DUPLICATE_NODES_IN_PROGRAM) emit_error(DUPLICATE_NODES_IN_PROGRAM)
printerr("Duplicate node in program: %s" % parsedNode.name) printerr('Duplicate node in program: %s' % parsedNode.name)
else: else:
var nodeCompiled = Program.WolNode.new() var nodeCompiled = Program.WolNode.new()
@ -127,11 +128,11 @@ func compile_node(program, parsedNode):
#raw text #raw text
if parsedNode.source != null && !parsedNode.source.empty(): if parsedNode.source != null && !parsedNode.source.empty():
nodeCompiled.sourceId = register_string(parsedNode.source,parsedNode.name, nodeCompiled.sourceId = register_string(parsedNode.source,parsedNode.name,
"line:"+parsedNode.name, 0, []) 'line:'+parsedNode.name, 0, [])
else: else:
#compile node #compile node
var startLabel : String = register_label() var startLabel : String = register_label()
emit(WolGlobals.ByteCode.Label,nodeCompiled,[Program.Operand.new(startLabel)]) emit(Constants.ByteCode.Label,nodeCompiled,[Program.Operand.new(startLabel)])
for statement in parsedNode.statements: for statement in parsedNode.statements:
generate_statement(nodeCompiled,statement) generate_statement(nodeCompiled,statement)
@ -142,27 +143,27 @@ func compile_node(program, parsedNode):
var danglingOptions = false var danglingOptions = false
for instruction in nodeCompiled.instructions : for instruction in nodeCompiled.instructions :
if instruction.operation == WolGlobals.ByteCode.AddOption: if instruction.operation == Constants.ByteCode.AddOption:
danglingOptions = true danglingOptions = true
if instruction.operation == WolGlobals.ByteCode.ShowOptions: if instruction.operation == Constants.ByteCode.ShowOptions:
danglingOptions = false danglingOptions = false
if danglingOptions: if danglingOptions:
emit(WolGlobals.ByteCode.ShowOptions, nodeCompiled) emit(Constants.ByteCode.ShowOptions, nodeCompiled)
emit(WolGlobals.ByteCode.RunNode, nodeCompiled) emit(Constants.ByteCode.RunNode, nodeCompiled)
else: else:
emit(WolGlobals.ByteCode.Stop, nodeCompiled) emit(Constants.ByteCode.Stop, nodeCompiled)
program.nodes[nodeCompiled.name] = nodeCompiled program.nodes[nodeCompiled.name] = nodeCompiled
func register_string(text:String,nodeName:String,id:String="",lineNumber:int=-1,tags:Array=[])->String: func register_string(text:String,nodeName:String,id:String='',lineNumber:int=-1,tags:Array=[])->String:
var lineIdUsed : String var lineIdUsed : String
var implicit : bool var implicit : bool
if id.empty(): if id.empty():
lineIdUsed = "%s-%s-%d" % [self._fileName,nodeName,self._stringCount] lineIdUsed = '%s-%s-%d' % [self._fileName,nodeName,self._stringCount]
self._stringCount+=1 self._stringCount+=1
#use this when we generate implicit tags #use this when we generate implicit tags
@ -181,9 +182,9 @@ func register_string(text:String,nodeName:String,id:String="",lineNumber:int=-1,
return lineIdUsed return lineIdUsed
func register_label(comment:String="")->String: func register_label(comment:String='')->String:
_labelCount+=1 _labelCount+=1
return "L%s%s" %[ _labelCount , comment] return 'L%s%s' %[ _labelCount , comment]
func emit(bytecode, node = _currentNode, operands = []): func emit(bytecode, node = _currentNode, operands = []):
var instruction = Program.Instruction.new(null) var instruction = Program.Instruction.new(null)
@ -191,12 +192,12 @@ func emit(bytecode, node = _currentNode, operands = []):
instruction.operands = operands instruction.operands = operands
if node == null: if node == null:
printerr("trying to emit to null node with byteCode: %s" % bytecode) printerr('trying to emit to null node with byteCode: %s' % bytecode)
return return
node.instructions.append(instruction) node.instructions.append(instruction)
if bytecode == WolGlobals.ByteCode.Label: if bytecode == Constants.ByteCode.Label:
#add to label table #add to label table
node.labels[instruction.operands[0].value] = node.instructions.size()-1 node.labels[instruction.operands[0].value] = node.instructions.size()-1
@ -212,100 +213,100 @@ func generate_header():
#this will walk through all child branches #this will walk through all child branches
#of the parse tree #of the parse tree
func generate_statement(node,statement): func generate_statement(node,statement):
# print("generating statement") # print('generating statement')
match statement.type: match statement.type:
WolGlobals.StatementTypes.CustomCommand: Constants.StatementTypes.CustomCommand:
generate_custom_command(node,statement.customCommand) generate_custom_command(node,statement.customCommand)
WolGlobals.StatementTypes.ShortcutOptionGroup: Constants.StatementTypes.ShortcutOptionGroup:
generate_shortcut_group(node,statement.shortcutOptionGroup) generate_shortcut_group(node,statement.shortcutOptionGroup)
WolGlobals.StatementTypes.Block: Constants.StatementTypes.Block:
generate_block(node,statement.block.statements) generate_block(node,statement.block.statements)
WolGlobals.StatementTypes.IfStatement: Constants.StatementTypes.IfStatement:
generate_if(node,statement.ifStatement) generate_if(node,statement.ifStatement)
WolGlobals.StatementTypes.OptionStatement: Constants.StatementTypes.OptionStatement:
generate_option(node,statement.optionStatement) generate_option(node,statement.optionStatement)
WolGlobals.StatementTypes.AssignmentStatement: Constants.StatementTypes.AssignmentStatement:
generate_assignment(node,statement.assignment) generate_assignment(node,statement.assignment)
WolGlobals.StatementTypes.Line: Constants.StatementTypes.Line:
generate_line(node,statement,statement.line) generate_line(node,statement,statement.line)
_: _:
emit_error(ERR_COMPILATION_FAILED) emit_error(ERR_COMPILATION_FAILED)
printerr("illegal statement type [%s]- could not generate code" % statement.type) printerr('illegal statement type [%s]- could not generate code' % statement.type)
#compile instructions for custom commands #compile instructions for custom commands
func generate_custom_command(node,command): func generate_custom_command(node,command):
#print("generating custom command") #print('generating custom command')
#can evaluate command #can evaluate command
if command.expression != null: if command.expression != null:
generate_expression(node,command.expression) generate_expression(node,command.expression)
else: else:
var commandString = command.clientCommand var commandString = command.clientCommand
if commandString == "stop": if commandString == 'stop':
emit(WolGlobals.ByteCode.Stop,node) emit(Constants.ByteCode.Stop,node)
else : else :
emit(WolGlobals.ByteCode.RunCommand,node,[Program.Operand.new(commandString)]) emit(Constants.ByteCode.RunCommand,node,[Program.Operand.new(commandString)])
#compile instructions for linetags and use them #compile instructions for linetags and use them
# \#line:number # \#line:number
func generate_line(node,statement,line:String): func generate_line(node,statement,line:String):
var num : String = register_string(line, node.name, "", statement.lineNumber, []); var num : String = register_string(line, node.name, '', statement.lineNumber, []);
emit(WolGlobals.ByteCode.RunLine, node, [Program.Operand.new(num)]) emit(Constants.ByteCode.RunLine, node, [Program.Operand.new(num)])
func generate_shortcut_group(node,shortcutGroup): func generate_shortcut_group(node,shortcutGroup):
# print("generating shortcutoptopn group") # print('generating shortcutoptopn group')
var end : String = register_label("group_end") var end : String = register_label('group_end')
var labels : Array = []#String var labels : Array = []#String
var optionCount : int = 0 var optionCount : int = 0
for option in shortcutGroup.options: for option in shortcutGroup.options:
var opDestination : String = register_label("option_%s"%[optionCount+1]) var opDestination : String = register_label('option_%s'%[optionCount+1])
labels.append(opDestination) labels.append(opDestination)
var endofClause : String = "" var endofClause : String = ''
if option.condition != null : if option.condition != null :
endofClause = register_label("conditional_%s"%optionCount) endofClause = register_label('conditional_%s'%optionCount)
generate_expression(node,option.condition) generate_expression(node,option.condition)
emit(WolGlobals.ByteCode.JumpIfFalse,node,[Program.Operand.new(endofClause)]) emit(Constants.ByteCode.JumpIfFalse,node,[Program.Operand.new(endofClause)])
var labelLineId : String = ""#no tag TODO: ADD TAG SUPPORT var labelLineId : String = ''#no tag TODO: ADD TAG SUPPORT
var labelStringId : String = register_string(option.label,node.nodeName, var labelStringId : String = register_string(option.label,node.nodeName,
labelLineId,option.lineNumber,[]) labelLineId,option.lineNumber,[])
emit(WolGlobals.ByteCode.AddOption,node,[Program.Operand.new(labelStringId),Program.Operand.new(opDestination)]) emit(Constants.ByteCode.AddOption,node,[Program.Operand.new(labelStringId),Program.Operand.new(opDestination)])
if option.condition != null : if option.condition != null :
emit(WolGlobals.ByteCode.Label,node,[Program.Operand.new(endofClause)]) emit(Constants.ByteCode.Label,node,[Program.Operand.new(endofClause)])
emit(WolGlobals.ByteCode.Pop,node) emit(Constants.ByteCode.Pop,node)
optionCount+=1 optionCount+=1
emit(WolGlobals.ByteCode.ShowOptions,node) emit(Constants.ByteCode.ShowOptions,node)
emit(WolGlobals.ByteCode.Jump,node) emit(Constants.ByteCode.Jump,node)
optionCount = 0 optionCount = 0
for option in shortcutGroup.options: for option in shortcutGroup.options:
emit(WolGlobals.ByteCode.Label,node,[Program.Operand.new(labels[optionCount])]) emit(Constants.ByteCode.Label,node,[Program.Operand.new(labels[optionCount])])
if option.node != null : if option.node != null :
generate_block(node,option.node.statements) generate_block(node,option.node.statements)
emit(WolGlobals.ByteCode.JumpTo,node,[Program.Operand.new(end)]) emit(Constants.ByteCode.JumpTo,node,[Program.Operand.new(end)])
optionCount+=1 optionCount+=1
#end of option group #end of option group
emit(WolGlobals.ByteCode.Label,node,[Program.Operand.new(end)]) emit(Constants.ByteCode.Label,node,[Program.Operand.new(end)])
#clean up #clean up
emit(WolGlobals.ByteCode.Pop,node) emit(Constants.ByteCode.Pop,node)
#compile instructions for block #compile instructions for block
#blocks are just groups of statements #blocks are just groups of statements
func generate_block(node,statements:Array=[]): func generate_block(node,statements:Array=[]):
# print("generating block") # print('generating block')
if !statements.empty(): if !statements.empty():
for statement in statements: for statement in statements:
generate_statement(node,statement) generate_statement(node,statement)
@ -313,56 +314,56 @@ func generate_block(node,statements:Array=[]):
#compile if branching instructions #compile if branching instructions
func generate_if(node,ifStatement): func generate_if(node,ifStatement):
# print("generating if") # print('generating if')
#jump to label @ end of every clause #jump to label @ end of every clause
var endif : String = register_label("endif") var endif : String = register_label('endif')
for clause in ifStatement.clauses: for clause in ifStatement.clauses:
var endClause : String = register_label("skip_clause") var endClause : String = register_label('skip_clause')
if clause.expression!=null: if clause.expression!=null:
generate_expression(node,clause.expression) generate_expression(node,clause.expression)
emit(WolGlobals.ByteCode.JumpIfFalse,node,[Program.Operand.new(endClause)]) emit(Constants.ByteCode.JumpIfFalse,node,[Program.Operand.new(endClause)])
generate_block(node,clause.statements) generate_block(node,clause.statements)
emit(WolGlobals.ByteCode.JumpTo,node,[Program.Operand.new(endif)]) emit(Constants.ByteCode.JumpTo,node,[Program.Operand.new(endif)])
if clause.expression!=null: if clause.expression!=null:
emit(WolGlobals.ByteCode.Label,node,[Program.Operand.new(endClause)]) emit(Constants.ByteCode.Label,node,[Program.Operand.new(endClause)])
if clause.expression!=null: if clause.expression!=null:
emit(WolGlobals.ByteCode.Pop) emit(Constants.ByteCode.Pop)
emit(WolGlobals.ByteCode.Label,node,[Program.Operand.new(endif)]) emit(Constants.ByteCode.Label,node,[Program.Operand.new(endif)])
#compile instructions for options #compile instructions for options
func generate_option(node,option): func generate_option(node,option):
# print("generating option") # print('generating option')
var destination : String = option.destination var destination : String = option.destination
if option.label == null || option.label.empty(): if option.label == null || option.label.empty():
#jump to another node #jump to another node
emit(WolGlobals.ByteCode.RunNode,node,[Program.Operand.new(destination)]) emit(Constants.ByteCode.RunNode,node,[Program.Operand.new(destination)])
else : else :
var lineID : String = ""#tags not supported TODO: ADD TAG SUPPORT var lineID : String = ''#tags not supported TODO: ADD TAG SUPPORT
var stringID = register_string(option.label,node.nodeName,lineID,option.lineNumber,[]) var stringID = register_string(option.label,node.nodeName,lineID,option.lineNumber,[])
emit(WolGlobals.ByteCode.AddOption,node,[Program.Operand.new(stringID),Program.Operand.new(destination)]) emit(Constants.ByteCode.AddOption,node,[Program.Operand.new(stringID),Program.Operand.new(destination)])
#compile instructions for assigning values #compile instructions for assigning values
func generate_assignment(node,assignment): func generate_assignment(node,assignment):
# print("generating assign") # print('generating assign')
#assignment #assignment
if assignment.operation == WolGlobals.TokenType.EqualToOrAssign: if assignment.operation == Constants.TokenType.EqualToOrAssign:
#evaluate the expression to a value for the stack #evaluate the expression to a value for the stack
generate_expression(node,assignment.value) generate_expression(node,assignment.value)
else : else :
#this is combined op #this is combined op
#get value of var #get value of var
emit(WolGlobals.ByteCode.PushVariable,node,[assignment.destination]) emit(Constants.ByteCode.PushVariable,node,[assignment.destination])
#evaluate the expression and push value to stack #evaluate the expression and push value to stack
generate_expression(node,assignment.value) generate_expression(node,assignment.value)
@ -370,68 +371,68 @@ func generate_assignment(node,assignment):
#stack contains oldvalue and result #stack contains oldvalue and result
match assignment.operation: match assignment.operation:
WolGlobals.TokenType.AddAssign: Constants.TokenType.AddAssign:
emit(WolGlobals.ByteCode.CallFunc,node, emit(Constants.ByteCode.CallFunc,node,
[Program.Operand.new(WolGlobals.token_type_name(WolGlobals.TokenType.Add))]) [Program.Operand.new(Constants.token_type_name(Constants.TokenType.Add))])
WolGlobals.TokenType.MinusAssign: Constants.TokenType.MinusAssign:
emit(WolGlobals.ByteCode.CallFunc,node, emit(Constants.ByteCode.CallFunc,node,
[Program.Operand.new(WolGlobals.token_type_name(WolGlobals.TokenType.Minus))]) [Program.Operand.new(Constants.token_type_name(Constants.TokenType.Minus))])
WolGlobals.TokenType.MultiplyAssign: Constants.TokenType.MultiplyAssign:
emit(WolGlobals.ByteCode.CallFunc,node, emit(Constants.ByteCode.CallFunc,node,
[Program.Operand.new(WolGlobals.token_type_name(WolGlobals.TokenType.MultiplyAssign))]) [Program.Operand.new(Constants.token_type_name(Constants.TokenType.MultiplyAssign))])
WolGlobals.TokenType.DivideAssign: Constants.TokenType.DivideAssign:
emit(WolGlobals.ByteCode.CallFunc,node, emit(Constants.ByteCode.CallFunc,node,
[Program.Operand.new(WolGlobals.token_type_name(WolGlobals.TokenType.DivideAssign))]) [Program.Operand.new(Constants.token_type_name(Constants.TokenType.DivideAssign))])
_: _:
printerr("Unable to generate assignment") printerr('Unable to generate assignment')
#stack contains destination value #stack contains destination value
#store the top of the stack in variable #store the top of the stack in variable
emit(WolGlobals.ByteCode.StoreVariable,node,[Program.Operand.new(assignment.destination)]) emit(Constants.ByteCode.StoreVariable,node,[Program.Operand.new(assignment.destination)])
#clean stack #clean stack
emit(WolGlobals.ByteCode.Pop,node) emit(Constants.ByteCode.Pop,node)
#compile expression instructions #compile expression instructions
func generate_expression(node,expression): func generate_expression(node,expression):
# print("generating expression") # print('generating expression')
#expression = value || func call #expression = value || func call
match expression.type: match expression.type:
WolGlobals.ExpressionType.Value: Constants.ExpressionType.Value:
generate_value(node,expression.value) generate_value(node,expression.value)
WolGlobals.ExpressionType.FunctionCall: Constants.ExpressionType.FunctionCall:
#eval all parameters #eval all parameters
for param in expression.params: for param in expression.params:
generate_expression(node,param) generate_expression(node,param)
#put the num of of params to stack #put the num of of params to stack
emit(WolGlobals.ByteCode.PushNumber,node,[Program.Operand.new(expression.params.size())]) emit(Constants.ByteCode.PushNumber,node,[Program.Operand.new(expression.params.size())])
#call function #call function
emit(WolGlobals.ByteCode.CallFunc,node,[Program.Operand.new(expression.function)]) emit(Constants.ByteCode.CallFunc,node,[Program.Operand.new(expression.function)])
_: _:
printerr("no expression") printerr('no expression')
#compile value instructions #compile value instructions
func generate_value(node,value): func generate_value(node,value):
# print("generating value") # print('generating value')
#push value to stack #push value to stack
match value.value.type: match value.value.type:
WolGlobals.ValueType.Number: Constants.ValueType.Number:
emit(WolGlobals.ByteCode.PushNumber,node,[Program.Operand.new(value.value.as_number())]) emit(Constants.ByteCode.PushNumber,node,[Program.Operand.new(value.value.as_number())])
WolGlobals.ValueType.Str: Constants.ValueType.Str:
var id : String = register_string(value.value.as_string(), var id : String = register_string(value.value.as_string(),
node.nodeName,"",value.lineNumber,[]) node.nodeName,'',value.lineNumber,[])
emit(WolGlobals.ByteCode.PushString,node,[Program.Operand.new(id)]) emit(Constants.ByteCode.PushString,node,[Program.Operand.new(id)])
WolGlobals.ValueType.Boolean: Constants.ValueType.Boolean:
emit(WolGlobals.ByteCode.PushBool,node,[Program.Operand.new(value.value.as_bool())]) emit(Constants.ByteCode.PushBool,node,[Program.Operand.new(value.value.as_bool())])
WolGlobals.ValueType.Variable: Constants.ValueType.Variable:
emit(WolGlobals.ByteCode.PushVariable,node,[Program.Operand.new(value.value.variable)]) emit(Constants.ByteCode.PushVariable,node,[Program.Operand.new(value.value.variable)])
WolGlobals.ValueType.Nullean: Constants.ValueType.Nullean:
emit(WolGlobals.ByteCode.PushNull,node) emit(Constants.ByteCode.PushNull,node)
_: _:
printerr("Unrecognized valuenode type: %s" % value.value.type) printerr('Unrecognized valuenode type: %s' % value.value.type)
#get the error flags #get the error flags
@ -453,8 +454,8 @@ func emit_error(error : int)->void:
static func print_tokens(tokens:Array=[]): static func print_tokens(tokens:Array=[]):
var list : PoolStringArray = [] var list : PoolStringArray = []
list.append("\n") list.append('\n')
for token in tokens: for token in tokens:
list.append("%s (%s line %s)\n"%[WolGlobals.token_type_name(token.type),token.value,token.lineNumber]) list.append('%s (%s line %s)\n'%[Constants.token_type_name(token.type),token.value,token.lineNumber])
print("TOKENS:") print('TOKENS:')
print(list.join("")) print(list.join(''))

View file

@ -1,23 +1,25 @@
extends Object extends Object
const LINE_COMENT : String = "//" const Constants = preload('res://addons/Wol/core/constants.gd')
const FORWARD_SLASH : String = "/"
const LINE_SEPARATOR : String = "\n" const LINE_COMENT : String = '//'
const FORWARD_SLASH : String = '/'
const BASE : String = "base" const LINE_SEPARATOR : String = '\n'
const DASH : String = "-"
const COMMAND : String = "command"
const LINK : String = "link"
const SHORTCUT : String = "shortcut"
const TAG : String = "tag"
const EXPRESSION : String = "expression"
const ASSIGNMENT : String = "assignment"
const OPTION : String = "option"
const OR : String = "or"
const DESTINATION : String = "destination"
var WHITESPACE : String = "\\s*" const BASE : String = 'base'
const DASH : String = '-'
const COMMAND : String = 'command'
const LINK : String = 'link'
const SHORTCUT : String = 'shortcut'
const TAG : String = 'tag'
const EXPRESSION : String = 'expression'
const ASSIGNMENT : String = 'assignment'
const OPTION : String = 'option'
const OR : String = 'or'
const DESTINATION : String = 'destination'
var WHITESPACE : String = '\\s*'
var _states : Dictionary = {} var _states : Dictionary = {}
var _defaultState : LexerState var _defaultState : LexerState
@ -33,50 +35,50 @@ func _init():
func create_states(): func create_states():
var patterns : Dictionary = {} var patterns : Dictionary = {}
patterns[WolGlobals.TokenType.Text] = ".*" patterns[Constants.TokenType.Text] = '.*'
patterns[WolGlobals.TokenType.Number] = "\\-?[0-9]+(\\.[0-9+])?" patterns[Constants.TokenType.Number] = '\\-?[0-9]+(\\.[0-9+])?'
patterns[WolGlobals.TokenType.Str] = "\"([^\"\\\\]*(?:\\.[^\"\\\\]*)*)\"" patterns[Constants.TokenType.Str] = '\'([^\'\\\\]*(?:\\.[^\'\\\\]*)*)\''
patterns[WolGlobals.TokenType.TagMarker] = "\\#" patterns[Constants.TokenType.TagMarker] = '\\#'
patterns[WolGlobals.TokenType.LeftParen] = "\\(" patterns[Constants.TokenType.LeftParen] = '\\('
patterns[WolGlobals.TokenType.RightParen] = "\\)" patterns[Constants.TokenType.RightParen] = '\\)'
patterns[WolGlobals.TokenType.EqualTo] = "(==|is(?!\\w)|eq(?!\\w))" patterns[Constants.TokenType.EqualTo] = '(==|is(?!\\w)|eq(?!\\w))'
patterns[WolGlobals.TokenType.EqualToOrAssign] = "(=|to(?!\\w))" patterns[Constants.TokenType.EqualToOrAssign] = '(=|to(?!\\w))'
patterns[WolGlobals.TokenType.NotEqualTo] = "(\\!=|neq(?!\\w))" patterns[Constants.TokenType.NotEqualTo] = '(\\!=|neq(?!\\w))'
patterns[WolGlobals.TokenType.GreaterThanOrEqualTo] = "(\\>=|gte(?!\\w))" patterns[Constants.TokenType.GreaterThanOrEqualTo] = '(\\>=|gte(?!\\w))'
patterns[WolGlobals.TokenType.GreaterThan] = "(\\>|gt(?!\\w))" patterns[Constants.TokenType.GreaterThan] = '(\\>|gt(?!\\w))'
patterns[WolGlobals.TokenType.LessThanOrEqualTo] = "(\\<=|lte(?!\\w))" patterns[Constants.TokenType.LessThanOrEqualTo] = '(\\<=|lte(?!\\w))'
patterns[WolGlobals.TokenType.LessThan] = "(\\<|lt(?!\\w))" patterns[Constants.TokenType.LessThan] = '(\\<|lt(?!\\w))'
patterns[WolGlobals.TokenType.AddAssign] = "\\+=" patterns[Constants.TokenType.AddAssign] = '\\+='
patterns[WolGlobals.TokenType.MinusAssign] = "\\-=" patterns[Constants.TokenType.MinusAssign] = '\\-='
patterns[WolGlobals.TokenType.MultiplyAssign] = "\\*=" patterns[Constants.TokenType.MultiplyAssign] = '\\*='
patterns[WolGlobals.TokenType.DivideAssign] = "\\/=" patterns[Constants.TokenType.DivideAssign] = '\\/='
patterns[WolGlobals.TokenType.Add] = "\\+" patterns[Constants.TokenType.Add] = '\\+'
patterns[WolGlobals.TokenType.Minus] = "\\-" patterns[Constants.TokenType.Minus] = '\\-'
patterns[WolGlobals.TokenType.Multiply] = "\\*" patterns[Constants.TokenType.Multiply] = '\\*'
patterns[WolGlobals.TokenType.Divide] = "\\/" patterns[Constants.TokenType.Divide] = '\\/'
patterns[WolGlobals.TokenType.Modulo] = "\\%" patterns[Constants.TokenType.Modulo] = '\\%'
patterns[WolGlobals.TokenType.And] = "(\\&\\&|and(?!\\w))" patterns[Constants.TokenType.And] = '(\\&\\&|and(?!\\w))'
patterns[WolGlobals.TokenType.Or] = "(\\|\\||or(?!\\w))" patterns[Constants.TokenType.Or] = '(\\|\\||or(?!\\w))'
patterns[WolGlobals.TokenType.Xor] = "(\\^|xor(?!\\w))" patterns[Constants.TokenType.Xor] = '(\\^|xor(?!\\w))'
patterns[WolGlobals.TokenType.Not] = "(\\!|not(?!\\w))" patterns[Constants.TokenType.Not] = '(\\!|not(?!\\w))'
patterns[WolGlobals.TokenType.Variable] = "\\$([A-Za-z0-9_\\.])+" patterns[Constants.TokenType.Variable] = '\\$([A-Za-z0-9_\\.])+'
patterns[WolGlobals.TokenType.Comma] = "\\," patterns[Constants.TokenType.Comma] = '\\,'
patterns[WolGlobals.TokenType.TrueToken] = "true(?!\\w)" patterns[Constants.TokenType.TrueToken] = 'true(?!\\w)'
patterns[WolGlobals.TokenType.FalseToken] = "false(?!\\w)" patterns[Constants.TokenType.FalseToken] = 'false(?!\\w)'
patterns[WolGlobals.TokenType.NullToken] = "null(?!\\w)" patterns[Constants.TokenType.NullToken] = 'null(?!\\w)'
patterns[WolGlobals.TokenType.BeginCommand] = "\\<\\<" patterns[Constants.TokenType.BeginCommand] = '\\<\\<'
patterns[WolGlobals.TokenType.EndCommand] = "\\>\\>" patterns[Constants.TokenType.EndCommand] = '\\>\\>'
patterns[WolGlobals.TokenType.OptionStart] = "\\[\\[" patterns[Constants.TokenType.OptionStart] = '\\[\\['
patterns[WolGlobals.TokenType.OptionEnd] = "\\]\\]" patterns[Constants.TokenType.OptionEnd] = '\\]\\]'
patterns[WolGlobals.TokenType.OptionDelimit] = "\\|" patterns[Constants.TokenType.OptionDelimit] = '\\|'
patterns[WolGlobals.TokenType.Identifier] = "[a-zA-Z0-9_:\\.]+" patterns[Constants.TokenType.Identifier] = '[a-zA-Z0-9_:\\.]+'
patterns[WolGlobals.TokenType.IfToken] = "if(?!\\w)" patterns[Constants.TokenType.IfToken] = 'if(?!\\w)'
patterns[WolGlobals.TokenType.ElseToken] = "else(?!\\w)" patterns[Constants.TokenType.ElseToken] = 'else(?!\\w)'
patterns[WolGlobals.TokenType.ElseIf] = "elseif(?!\\w)" patterns[Constants.TokenType.ElseIf] = 'elseif(?!\\w)'
patterns[WolGlobals.TokenType.EndIf] = "endif(?!\\w)" patterns[Constants.TokenType.EndIf] = 'endif(?!\\w)'
patterns[WolGlobals.TokenType.Set] = "set(?!\\w)" patterns[Constants.TokenType.Set] = 'set(?!\\w)'
patterns[WolGlobals.TokenType.ShortcutOption] = "\\-\\>\\s*" patterns[Constants.TokenType.ShortcutOption] = '\\-\\>\\s*'
#compound states #compound states
var shortcut_option : String= SHORTCUT + DASH + OPTION var shortcut_option : String= SHORTCUT + DASH + OPTION
@ -87,84 +89,84 @@ func create_states():
_states = {} _states = {}
_states[BASE] = LexerState.new(patterns) _states[BASE] = LexerState.new(patterns)
_states[BASE].add_transition(WolGlobals.TokenType.BeginCommand,COMMAND,true) _states[BASE].add_transition(Constants.TokenType.BeginCommand,COMMAND,true)
_states[BASE].add_transition(WolGlobals.TokenType.OptionStart,LINK,true) _states[BASE].add_transition(Constants.TokenType.OptionStart,LINK,true)
_states[BASE].add_transition(WolGlobals.TokenType.ShortcutOption,shortcut_option) _states[BASE].add_transition(Constants.TokenType.ShortcutOption,shortcut_option)
_states[BASE].add_transition(WolGlobals.TokenType.TagMarker,TAG,true) _states[BASE].add_transition(Constants.TokenType.TagMarker,TAG,true)
_states[BASE].add_text_rule(WolGlobals.TokenType.Text) _states[BASE].add_text_rule(Constants.TokenType.Text)
_states[TAG] = LexerState.new(patterns) _states[TAG] = LexerState.new(patterns)
_states[TAG].add_transition(WolGlobals.TokenType.Identifier,BASE) _states[TAG].add_transition(Constants.TokenType.Identifier,BASE)
_states[shortcut_option] = LexerState.new(patterns) _states[shortcut_option] = LexerState.new(patterns)
_states[shortcut_option].track_indent = true _states[shortcut_option].track_indent = true
_states[shortcut_option].add_transition(WolGlobals.TokenType.BeginCommand,EXPRESSION,true) _states[shortcut_option].add_transition(Constants.TokenType.BeginCommand,EXPRESSION,true)
_states[shortcut_option].add_transition(WolGlobals.TokenType.TagMarker,shortcut_option_tag,true) _states[shortcut_option].add_transition(Constants.TokenType.TagMarker,shortcut_option_tag,true)
_states[shortcut_option].add_text_rule(WolGlobals.TokenType.Text,BASE) _states[shortcut_option].add_text_rule(Constants.TokenType.Text,BASE)
_states[shortcut_option_tag] = LexerState.new(patterns) _states[shortcut_option_tag] = LexerState.new(patterns)
_states[shortcut_option_tag].add_transition(WolGlobals.TokenType.Identifier,shortcut_option) _states[shortcut_option_tag].add_transition(Constants.TokenType.Identifier,shortcut_option)
_states[COMMAND] = LexerState.new(patterns) _states[COMMAND] = LexerState.new(patterns)
_states[COMMAND].add_transition(WolGlobals.TokenType.IfToken,EXPRESSION) _states[COMMAND].add_transition(Constants.TokenType.IfToken,EXPRESSION)
_states[COMMAND].add_transition(WolGlobals.TokenType.ElseToken) _states[COMMAND].add_transition(Constants.TokenType.ElseToken)
_states[COMMAND].add_transition(WolGlobals.TokenType.ElseIf,EXPRESSION) _states[COMMAND].add_transition(Constants.TokenType.ElseIf,EXPRESSION)
_states[COMMAND].add_transition(WolGlobals.TokenType.EndIf) _states[COMMAND].add_transition(Constants.TokenType.EndIf)
_states[COMMAND].add_transition(WolGlobals.TokenType.Set,ASSIGNMENT) _states[COMMAND].add_transition(Constants.TokenType.Set,ASSIGNMENT)
_states[COMMAND].add_transition(WolGlobals.TokenType.EndCommand,BASE,true) _states[COMMAND].add_transition(Constants.TokenType.EndCommand,BASE,true)
_states[COMMAND].add_transition(WolGlobals.TokenType.Identifier,command_or_expression) _states[COMMAND].add_transition(Constants.TokenType.Identifier,command_or_expression)
_states[COMMAND].add_text_rule(WolGlobals.TokenType.Text) _states[COMMAND].add_text_rule(Constants.TokenType.Text)
_states[command_or_expression] = LexerState.new(patterns) _states[command_or_expression] = LexerState.new(patterns)
_states[command_or_expression].add_transition(WolGlobals.TokenType.LeftParen,EXPRESSION) _states[command_or_expression].add_transition(Constants.TokenType.LeftParen,EXPRESSION)
_states[command_or_expression].add_transition(WolGlobals.TokenType.EndCommand,BASE,true) _states[command_or_expression].add_transition(Constants.TokenType.EndCommand,BASE,true)
_states[command_or_expression].add_text_rule(WolGlobals.TokenType.Text) _states[command_or_expression].add_text_rule(Constants.TokenType.Text)
_states[ASSIGNMENT] = LexerState.new(patterns) _states[ASSIGNMENT] = LexerState.new(patterns)
_states[ASSIGNMENT].add_transition(WolGlobals.TokenType.Variable) _states[ASSIGNMENT].add_transition(Constants.TokenType.Variable)
_states[ASSIGNMENT].add_transition(WolGlobals.TokenType.EqualToOrAssign, EXPRESSION) _states[ASSIGNMENT].add_transition(Constants.TokenType.EqualToOrAssign, EXPRESSION)
_states[ASSIGNMENT].add_transition(WolGlobals.TokenType.AddAssign, EXPRESSION) _states[ASSIGNMENT].add_transition(Constants.TokenType.AddAssign, EXPRESSION)
_states[ASSIGNMENT].add_transition(WolGlobals.TokenType.MinusAssign, EXPRESSION) _states[ASSIGNMENT].add_transition(Constants.TokenType.MinusAssign, EXPRESSION)
_states[ASSIGNMENT].add_transition(WolGlobals.TokenType.MultiplyAssign, EXPRESSION) _states[ASSIGNMENT].add_transition(Constants.TokenType.MultiplyAssign, EXPRESSION)
_states[ASSIGNMENT].add_transition(WolGlobals.TokenType.DivideAssign, EXPRESSION) _states[ASSIGNMENT].add_transition(Constants.TokenType.DivideAssign, EXPRESSION)
_states[EXPRESSION] = LexerState.new(patterns) _states[EXPRESSION] = LexerState.new(patterns)
_states[EXPRESSION].add_transition(WolGlobals.TokenType.EndCommand, BASE) _states[EXPRESSION].add_transition(Constants.TokenType.EndCommand, BASE)
_states[EXPRESSION].add_transition(WolGlobals.TokenType.Number) _states[EXPRESSION].add_transition(Constants.TokenType.Number)
_states[EXPRESSION].add_transition(WolGlobals.TokenType.Str) _states[EXPRESSION].add_transition(Constants.TokenType.Str)
_states[EXPRESSION].add_transition(WolGlobals.TokenType.LeftParen) _states[EXPRESSION].add_transition(Constants.TokenType.LeftParen)
_states[EXPRESSION].add_transition(WolGlobals.TokenType.RightParen) _states[EXPRESSION].add_transition(Constants.TokenType.RightParen)
_states[EXPRESSION].add_transition(WolGlobals.TokenType.EqualTo) _states[EXPRESSION].add_transition(Constants.TokenType.EqualTo)
_states[EXPRESSION].add_transition(WolGlobals.TokenType.EqualToOrAssign) _states[EXPRESSION].add_transition(Constants.TokenType.EqualToOrAssign)
_states[EXPRESSION].add_transition(WolGlobals.TokenType.NotEqualTo) _states[EXPRESSION].add_transition(Constants.TokenType.NotEqualTo)
_states[EXPRESSION].add_transition(WolGlobals.TokenType.GreaterThanOrEqualTo) _states[EXPRESSION].add_transition(Constants.TokenType.GreaterThanOrEqualTo)
_states[EXPRESSION].add_transition(WolGlobals.TokenType.GreaterThan) _states[EXPRESSION].add_transition(Constants.TokenType.GreaterThan)
_states[EXPRESSION].add_transition(WolGlobals.TokenType.LessThanOrEqualTo) _states[EXPRESSION].add_transition(Constants.TokenType.LessThanOrEqualTo)
_states[EXPRESSION].add_transition(WolGlobals.TokenType.LessThan) _states[EXPRESSION].add_transition(Constants.TokenType.LessThan)
_states[EXPRESSION].add_transition(WolGlobals.TokenType.Add) _states[EXPRESSION].add_transition(Constants.TokenType.Add)
_states[EXPRESSION].add_transition(WolGlobals.TokenType.Minus) _states[EXPRESSION].add_transition(Constants.TokenType.Minus)
_states[EXPRESSION].add_transition(WolGlobals.TokenType.Multiply) _states[EXPRESSION].add_transition(Constants.TokenType.Multiply)
_states[EXPRESSION].add_transition(WolGlobals.TokenType.Divide) _states[EXPRESSION].add_transition(Constants.TokenType.Divide)
_states[EXPRESSION].add_transition(WolGlobals.TokenType.Modulo) _states[EXPRESSION].add_transition(Constants.TokenType.Modulo)
_states[EXPRESSION].add_transition(WolGlobals.TokenType.And) _states[EXPRESSION].add_transition(Constants.TokenType.And)
_states[EXPRESSION].add_transition(WolGlobals.TokenType.Or) _states[EXPRESSION].add_transition(Constants.TokenType.Or)
_states[EXPRESSION].add_transition(WolGlobals.TokenType.Xor) _states[EXPRESSION].add_transition(Constants.TokenType.Xor)
_states[EXPRESSION].add_transition(WolGlobals.TokenType.Not) _states[EXPRESSION].add_transition(Constants.TokenType.Not)
_states[EXPRESSION].add_transition(WolGlobals.TokenType.Variable) _states[EXPRESSION].add_transition(Constants.TokenType.Variable)
_states[EXPRESSION].add_transition(WolGlobals.TokenType.Comma) _states[EXPRESSION].add_transition(Constants.TokenType.Comma)
_states[EXPRESSION].add_transition(WolGlobals.TokenType.TrueToken) _states[EXPRESSION].add_transition(Constants.TokenType.TrueToken)
_states[EXPRESSION].add_transition(WolGlobals.TokenType.FalseToken) _states[EXPRESSION].add_transition(Constants.TokenType.FalseToken)
_states[EXPRESSION].add_transition(WolGlobals.TokenType.NullToken) _states[EXPRESSION].add_transition(Constants.TokenType.NullToken)
_states[EXPRESSION].add_transition(WolGlobals.TokenType.Identifier) _states[EXPRESSION].add_transition(Constants.TokenType.Identifier)
_states[LINK] = LexerState.new(patterns) _states[LINK] = LexerState.new(patterns)
_states[LINK].add_transition(WolGlobals.TokenType.OptionEnd, BASE, true) _states[LINK].add_transition(Constants.TokenType.OptionEnd, BASE, true)
_states[LINK].add_transition(WolGlobals.TokenType.OptionDelimit, link_destination, true) _states[LINK].add_transition(Constants.TokenType.OptionDelimit, link_destination, true)
_states[LINK].add_text_rule(WolGlobals.TokenType.Text) _states[LINK].add_text_rule(Constants.TokenType.Text)
_states[link_destination] = LexerState.new(patterns) _states[link_destination] = LexerState.new(patterns)
_states[link_destination].add_transition(WolGlobals.TokenType.Identifier) _states[link_destination].add_transition(Constants.TokenType.Identifier)
_states[link_destination].add_transition(WolGlobals.TokenType.OptionEnd, BASE) _states[link_destination].add_transition(Constants.TokenType.OptionEnd, BASE)
_defaultState = _states[BASE] _defaultState = _states[BASE]
@ -184,7 +186,7 @@ func tokenize(text:String)->Array:
_currentState = _defaultState _currentState = _defaultState
var lines : PoolStringArray = text.split(LINE_SEPARATOR) var lines : PoolStringArray = text.split(LINE_SEPARATOR)
lines.append("") lines.append('')
var lineNumber : int = 1 var lineNumber : int = 1
@ -192,7 +194,7 @@ func tokenize(text:String)->Array:
tokens+=tokenize_line(line,lineNumber) tokens+=tokenize_line(line,lineNumber)
lineNumber+=1 lineNumber+=1
var endOfInput : Token = Token.new(WolGlobals.TokenType.EndOfInput,_currentState,lineNumber,0) var endOfInput : Token = Token.new(Constants.TokenType.EndOfInput,_currentState,lineNumber,0)
tokens.append(endOfInput) tokens.append(endOfInput)
# print(tokens) # print(tokens)
@ -202,7 +204,7 @@ func tokenize(text:String)->Array:
func tokenize_line(line:String, lineNumber : int)->Array: func tokenize_line(line:String, lineNumber : int)->Array:
var tokenStack : Array = [] var tokenStack : Array = []
var freshLine = line.replace("\t"," ").replace("\r","") var freshLine = line.replace('\t',' ').replace('\r','')
#record indentation #record indentation
var indentation = line_indentation(line) var indentation = line_indentation(line)
@ -212,8 +214,8 @@ func tokenize_line(line:String, lineNumber : int)->Array:
#we add an indenation token to record indent level #we add an indenation token to record indent level
_indentStack.push_front(IntBoolPair.new(indentation,true)) _indentStack.push_front(IntBoolPair.new(indentation,true))
var indent : Token = Token.new(WolGlobals.TokenType.Indent,_currentState,lineNumber,prevIndentation.key) var indent : Token = Token.new(Constants.TokenType.Indent,_currentState,lineNumber,prevIndentation.key)
indent.value = "%*s" % [indentation - prevIndentation.key,""] indent.value = '%*s' % [indentation - prevIndentation.key,'']
_shouldTrackIndent = false _shouldTrackIndent = false
tokenStack.push_front(indent) tokenStack.push_front(indent)
@ -224,7 +226,7 @@ func tokenize_line(line:String, lineNumber : int)->Array:
while indentation < _indentStack.front().key: while indentation < _indentStack.front().key:
var top : IntBoolPair = _indentStack.pop_front() var top : IntBoolPair = _indentStack.pop_front()
if top.value: if top.value:
var deIndent : Token = Token.new(WolGlobals.TokenType.Dedent,_currentState,lineNumber,0) var deIndent : Token = Token.new(Constants.TokenType.Dedent,_currentState,lineNumber,0)
tokenStack.push_front(deIndent) tokenStack.push_front(deIndent)
@ -233,7 +235,7 @@ func tokenize_line(line:String, lineNumber : int)->Array:
var whitespace : RegEx = RegEx.new() var whitespace : RegEx = RegEx.new()
var error = whitespace.compile(WHITESPACE) var error = whitespace.compile(WHITESPACE)
if error != OK: if error != OK:
printerr("unable to compile regex WHITESPACE") printerr('unable to compile regex WHITESPACE')
return [] return []
while column < freshLine.length(): while column < freshLine.length():
@ -251,22 +253,22 @@ func tokenize_line(line:String, lineNumber : int)->Array:
var tokenText : String var tokenText : String
if rule.tokenType == WolGlobals.TokenType.Text: if rule.tokenType == Constants.TokenType.Text:
#if this is text then we back up to the most recent #if this is text then we back up to the most recent
#delimiting token and treat everything from there as text. #delimiting token and treat everything from there as text.
var startIndex : int = indentation var startIndex : int = indentation
if tokenStack.size() > 0 : if tokenStack.size() > 0 :
while tokenStack.front().type == WolGlobals.TokenType.Identifier: while tokenStack.front().type == Constants.TokenType.Identifier:
tokenStack.pop_front() tokenStack.pop_front()
var startDelimitToken : Token = tokenStack.front() var startDelimitToken : Token = tokenStack.front()
startIndex = startDelimitToken.column startIndex = startDelimitToken.column
if startDelimitToken.type == WolGlobals.TokenType.Indent: if startDelimitToken.type == Constants.TokenType.Indent:
startIndex += startDelimitToken.value.length() startIndex += startDelimitToken.value.length()
if startDelimitToken.type == WolGlobals.TokenType.Dedent: if startDelimitToken.type == Constants.TokenType.Dedent:
startIndex = indentation startIndex = indentation
# #
@ -281,10 +283,10 @@ func tokenize_line(line:String, lineNumber : int)->Array:
column += tokenText.length() column += tokenText.length()
#pre-proccess string #pre-proccess string
if rule.tokenType == WolGlobals.TokenType.Str: if rule.tokenType == Constants.TokenType.Str:
tokenText = tokenText.substr(1,tokenText.length() - 2) tokenText = tokenText.substr(1,tokenText.length() - 2)
tokenText = tokenText.replace("\\\\", "\\") tokenText = tokenText.replace('\\\\', '\\')
tokenText = tokenText.replace("\\\"","\"") tokenText = tokenText.replace('\\\'','\'')
var token : Token = Token.new(rule.tokenType,_currentState,lineNumber,column,tokenText) var token : Token = Token.new(rule.tokenType,_currentState,lineNumber,column,tokenText)
token.delimitsText = rule.delimitsText token.delimitsText = rule.delimitsText
@ -294,7 +296,7 @@ func tokenize_line(line:String, lineNumber : int)->Array:
if rule.enterState != null && rule.enterState.length() > 0: if rule.enterState != null && rule.enterState.length() > 0:
if !_states.has(rule.enterState): if !_states.has(rule.enterState):
printerr("State[%s] not known - line(%s) col(%s)"%[rule.enterState,lineNumber,column]) printerr('State[%s] not known - line(%s) col(%s)'%[rule.enterState,lineNumber,column])
return [] return []
enter_state(_states[rule.enterState]) enter_state(_states[rule.enterState])
@ -308,7 +310,7 @@ func tokenize_line(line:String, lineNumber : int)->Array:
if !matched: if !matched:
# TODO: Send out some helpful messages # TODO: Send out some helpful messages
printerr("expectedTokens [%s] - line(%s) col(%s)"%["refineErrors.Lexer.tokenize_line",lineNumber,column]) printerr('expectedTokens [%s] - line(%s) col(%s)'%['refineErrors.Lexer.tokenize_line',lineNumber,column])
return [] return []
var lastWhiteSpace : RegExMatch = whitespace.search(line,column) var lastWhiteSpace : RegExMatch = whitespace.search(line,column)
@ -322,7 +324,7 @@ func tokenize_line(line:String, lineNumber : int)->Array:
func line_indentation(line:String)->int: func line_indentation(line:String)->int:
var indentRegex : RegEx = RegEx.new() var indentRegex : RegEx = RegEx.new()
indentRegex.compile("^(\\s*)") indentRegex.compile('^(\\s*)')
var found : RegExMatch = indentRegex.search(line) var found : RegExMatch = indentRegex.search(line)
@ -348,7 +350,7 @@ class Token:
var paramCount : int var paramCount : int
var lexerState : String var lexerState : String
func _init(type:int,state: LexerState, lineNumber:int = -1,column:int = -1,value:String =""): func _init(type:int,state: LexerState, lineNumber:int = -1,column:int = -1,value:String =''):
self.type = type self.type = type
self.lexerState = state.stateName self.lexerState = state.stateName
self.lineNumber = lineNumber self.lineNumber = lineNumber
@ -356,7 +358,7 @@ class Token:
self.value = value self.value = value
func _to_string(): func _to_string():
return "%s (%s) at %s:%s (state: %s)" % [WolGlobals.token_type_name(type),value,lineNumber,column,lexerState] return '%s (%s) at %s:%s (state: %s)' % [Constants.token_type_name(type),value,lineNumber,column,lexerState]
class LexerState: class LexerState:
@ -369,24 +371,24 @@ class LexerState:
func _init(patterns): func _init(patterns):
self.patterns = patterns self.patterns = patterns
func add_transition(type : int, state : String = "",delimitText : bool = false)->Rule: func add_transition(type : int, state : String = '',delimitText : bool = false)->Rule:
var pattern = "\\G%s" % patterns[type] var pattern = '\\G%s' % patterns[type]
# print("pattern = %s" % pattern) # print('pattern = %s' % pattern)
var rule = Rule.new(type,pattern,state,delimitText) var rule = Rule.new(type,pattern,state,delimitText)
rules.append(rule) rules.append(rule)
return rule return rule
func add_text_rule(type : int, state : String = "")->Rule: func add_text_rule(type : int, state : String = '')->Rule:
if contains_text_rule() : if contains_text_rule() :
printerr("State already contains Text rule") printerr('State already contains Text rule')
return null return null
var delimiters:Array = [] var delimiters:Array = []
for rule in rules: for rule in rules:
if rule.delimitsText: if rule.delimitsText:
delimiters.append("%s" % rule.regex.get_pattern().substr(2)) delimiters.append('%s' % rule.regex.get_pattern().substr(2))
var pattern = "\\G((?!%s).)*" % [PoolStringArray(delimiters).join("|")] var pattern = '\\G((?!%s).)*' % [PoolStringArray(delimiters).join('|')]
var rule : Rule = add_transition(type,state) var rule : Rule = add_transition(type,state)
rule.regex = RegEx.new() rule.regex = RegEx.new()
rule.regex.compile(pattern) rule.regex.compile(pattern)
@ -416,7 +418,7 @@ class Rule:
self.delimitsText = delimitsText self.delimitsText = delimitsText
func _to_string(): func _to_string():
return "[Rule : %s - %s]" % [WolGlobals.token_type_name(tokenType),regex] return '[Rule : %s - %s]' % [Constants.token_type_name(tokenType),regex]
class IntBoolPair: class IntBoolPair:
var key : int var key : int

View file

@ -1,8 +1,7 @@
extends Object extends Object
const WolGlobals = preload("res://addons/Wol/autoloads/execution_states.gd") const Constants = preload('res://addons/Wol/core/constants.gd')
const Lexer = preload("res://addons/Wol/core/compiler/lexer.gd") const Lexer = preload('res://addons/Wol/core/compiler/lexer.gd')
var _tokens : Array = []#token var _tokens : Array = []#token
@ -15,7 +14,7 @@ enum Associativity {
} }
func parse_node()->WolNode: func parse_node()->WolNode:
return WolNode.new("Start",null,self) return WolNode.new('Start',null,self)
func next_symbol_is(validTypes:Array)->bool: func next_symbol_is(validTypes:Array)->bool:
var type = self._tokens.front().type var type = self._tokens.front().type
@ -37,8 +36,8 @@ func expect_symbol(tokenTypes:Array = [])->Lexer.Token:
var size = tokenTypes.size() var size = tokenTypes.size()
if size == 0: if size == 0:
if t.type == WolGlobals.TokenType.EndOfInput: if t.type == Constants.TokenType.EndOfInput:
printerr("unexpected end of input") printerr('unexpected end of input')
return null return null
return t return t
@ -46,11 +45,11 @@ func expect_symbol(tokenTypes:Array = [])->Lexer.Token:
if t.type == type: if t.type == type:
return t return t
printerr("unexpexted token: expected[ %s ] but got [ %s ]"% (tokenTypes+[t.type])) printerr('unexpexted token: expected[ %s ] but got [ %s ]'% (tokenTypes+[t.type]))
return null return null
static func tab(indentLevel : int , input : String,newLine : bool = true)->String: static func tab(indentLevel : int , input : String,newLine : bool = true)->String:
return ("%*s| %s%s"% [indentLevel*2,"",input,("" if !newLine else "\n")]) return ('%*s| %s%s'% [indentLevel*2,'',input,('' if !newLine else '\n')])
func tokens()->Array: func tokens()->Array:
return _tokens return _tokens
@ -70,21 +69,21 @@ class ParseNode:
tags = [] tags = []
func tree_string(indentLevel : int)->String: func tree_string(indentLevel : int)->String:
return "NotImplemented" return 'NotImplemented'
func tags_to_string(indentLevel : int)->String: func tags_to_string(indentLevel : int)->String:
return "%s" % "TAGS<tags_to_string>NOTIMPLEMENTED" return '%s' % 'TAGS<tags_to_string>NOTIMPLEMENTED'
func get_node_parent()->WolNode: func get_node_parent()->WolNode:
var node = self var node = self
while node != null: while node != null:
if node.has_method("wol_node"): if node.has_method('wol_node'):
return node as WolNode return node as WolNode
node = node.parent node = node.parent
return null return null
func tab(indentLevel : int , input : String,newLine : bool = true)->String: func tab(indentLevel : int , input : String,newLine : bool = true)->String:
return ("%*s| %s%s"% [indentLevel*2,"",input,("" if !newLine else "\n")]) return ('%*s| %s%s'% [indentLevel*2,'',input,('' if !newLine else '\n')])
func set_parent(parent): func set_parent(parent):
@ -103,7 +102,7 @@ class WolNode extends ParseNode:
self.name = name self.name = name
while (parser.tokens().size() > 0 && while (parser.tokens().size() > 0 &&
!parser.next_symbol_is([WolGlobals.TokenType.Dedent,WolGlobals.TokenType.EndOfInput])): !parser.next_symbol_is([Constants.TokenType.Dedent,Constants.TokenType.EndOfInput])):
statements.append(Statement.new(self,parser)) statements.append(Statement.new(self,parser))
#print(statements.size()) #print(statements.size())
@ -117,9 +116,9 @@ class WolNode extends ParseNode:
for statement in statements: for statement in statements:
info.append(statement.tree_string(indentLevel +1)) info.append(statement.tree_string(indentLevel +1))
#print("printing TREEEEEEEEEEEEE") #print('printing TREEEEEEEEEEEEE')
return info.join("") return info.join('')
class Header extends ParseNode: class Header extends ParseNode:
@ -127,7 +126,7 @@ class Header extends ParseNode:
class Statement extends ParseNode: class Statement extends ParseNode:
var Type = WolGlobals.StatementTypes var Type = Constants.StatementTypes
var type : int var type : int
var block : Block var block : Block
@ -158,18 +157,18 @@ class Statement extends ParseNode:
elif CustomCommand.can_parse(parser): elif CustomCommand.can_parse(parser):
customCommand = CustomCommand.new(self,parser) customCommand = CustomCommand.new(self,parser)
type = Type.CustomCommand type = Type.CustomCommand
elif parser.next_symbol_is([WolGlobals.TokenType.Text]): elif parser.next_symbol_is([Constants.TokenType.Text]):
line = parser.expect_symbol([WolGlobals.TokenType.Text]).value line = parser.expect_symbol([Constants.TokenType.Text]).value
type = Type.Line type = Type.Line
else: else:
printerr("expected a statement but got %s instead. (probably an inbalanced if statement)" % parser.tokens().front()._to_string()) printerr('expected a statement but got %s instead. (probably an inbalanced if statement)' % parser.tokens().front()._to_string())
var tags : Array = [] var tags : Array = []
while parser.next_symbol_is([WolGlobals.TokenType.TagMarker]): while parser.next_symbol_is([Constants.TokenType.TagMarker]):
parser.expect_symbol([WolGlobals.TokenType.TagMarker]) parser.expect_symbol([Constants.TokenType.TagMarker])
var tag : String = parser.expect_symbol([WolGlobals.TokenType.Identifier]).value var tag : String = parser.expect_symbol([Constants.TokenType.Identifier]).value
tags.append(tag) tags.append(tag)
if(tags.size()>0): if(tags.size()>0):
@ -192,13 +191,13 @@ class Statement extends ParseNode:
Type.CustomCommand: Type.CustomCommand:
info.append(customCommand.tree_string(indentLevel)) info.append(customCommand.tree_string(indentLevel))
Type.Line: Type.Line:
info.append(tab(indentLevel,"Line: %s"%line)) info.append(tab(indentLevel,'Line: %s'%line))
_: _:
printerr("cannot print statement") printerr('cannot print statement')
#print("statement --") #print('statement --')
return info.join("") return info.join('')
@ -213,20 +212,20 @@ class CustomCommand extends ParseNode:
var clientCommand : String var clientCommand : String
func _init(parent:ParseNode,parser).(parent,parser): func _init(parent:ParseNode,parser).(parent,parser):
parser.expect_symbol([WolGlobals.TokenType.BeginCommand]) parser.expect_symbol([Constants.TokenType.BeginCommand])
var commandTokens = [] var commandTokens = []
commandTokens.append(parser.expect_symbol()) commandTokens.append(parser.expect_symbol())
while !parser.next_symbol_is([WolGlobals.TokenType.EndCommand]): while !parser.next_symbol_is([Constants.TokenType.EndCommand]):
commandTokens.append(parser.expect_symbol()) commandTokens.append(parser.expect_symbol())
parser.expect_symbol([WolGlobals.TokenType.EndCommand]) parser.expect_symbol([Constants.TokenType.EndCommand])
#if first token is identifier and second is leftt parenthesis #if first token is identifier and second is leftt parenthesis
#evaluate as function #evaluate as function
if (commandTokens.size() > 1 && commandTokens[0].type == WolGlobals.TokenType.Identifier if (commandTokens.size() > 1 && commandTokens[0].type == Constants.TokenType.Identifier
&& commandTokens[1].type == WolGlobals.TokenType.LeftParen): && commandTokens[1].type == Constants.TokenType.LeftParen):
var p = get_script().new(commandTokens,parser.library) var p = get_script().new(commandTokens,parser.library)
var expression : ExpressionNode = ExpressionNode.parse(self,p) var expression : ExpressionNode = ExpressionNode.parse(self,p)
type = Type.Expression type = Type.Expression
@ -239,14 +238,14 @@ class CustomCommand extends ParseNode:
func tree_string(indentLevel : int)->String: func tree_string(indentLevel : int)->String:
match type: match type:
Type.Expression: Type.Expression:
return tab(indentLevel,"Expression: %s"% expression.tree_string(indentLevel+1)) return tab(indentLevel,'Expression: %s'% expression.tree_string(indentLevel+1))
Type.ClientCommand: Type.ClientCommand:
return tab(indentLevel,"Command: %s"%clientCommand) return tab(indentLevel,'Command: %s'%clientCommand)
return "" return ''
static func can_parse(parser)->bool: static func can_parse(parser)->bool:
return (parser.next_symbols_are([WolGlobals.TokenType.BeginCommand,WolGlobals.TokenType.Text]) return (parser.next_symbols_are([Constants.TokenType.BeginCommand,Constants.TokenType.Text])
|| parser.next_symbols_are([WolGlobals.TokenType.BeginCommand,WolGlobals.TokenType.Identifier])) || parser.next_symbols_are([Constants.TokenType.BeginCommand,Constants.TokenType.Identifier]))
@ -264,7 +263,7 @@ class ShortcutOptionGroup extends ParseNode:
var sIndex : int = 1 var sIndex : int = 1
options.append(ShortCutOption.new(sIndex, self, parser)) options.append(ShortCutOption.new(sIndex, self, parser))
sIndex+=1 sIndex+=1
while parser.next_symbol_is([WolGlobals.TokenType.ShortcutOption]): while parser.next_symbol_is([Constants.TokenType.ShortcutOption]):
options.append(ShortCutOption.new(sIndex, self, parser)) options.append(ShortCutOption.new(sIndex, self, parser))
sIndex+=1 sIndex+=1
@ -272,17 +271,17 @@ class ShortcutOptionGroup extends ParseNode:
func tree_string(indentLevel : int)->String: func tree_string(indentLevel : int)->String:
var info : PoolStringArray = [] var info : PoolStringArray = []
info.append(tab(indentLevel,"Shortcut Option Group{")) info.append(tab(indentLevel,'Shortcut Option Group{'))
for option in options: for option in options:
info.append(option.tree_string(indentLevel+1)) info.append(option.tree_string(indentLevel+1))
info.append(tab(indentLevel,"}")) info.append(tab(indentLevel,'}'))
return info.join("") return info.join('')
static func can_parse(parser)->bool: static func can_parse(parser)->bool:
return parser.next_symbol_is([WolGlobals.TokenType.ShortcutOption]) return parser.next_symbol_is([Constants.TokenType.ShortcutOption])
pass pass
class ShortCutOption extends ParseNode: class ShortCutOption extends ParseNode:
@ -292,50 +291,50 @@ class ShortCutOption extends ParseNode:
var node : WolNode var node : WolNode
func _init(index:int, parent:ParseNode, parser).(parent,parser): func _init(index:int, parent:ParseNode, parser).(parent,parser):
parser.expect_symbol([WolGlobals.TokenType.ShortcutOption]) parser.expect_symbol([Constants.TokenType.ShortcutOption])
label = parser.expect_symbol([WolGlobals.TokenType.Text]).value label = parser.expect_symbol([Constants.TokenType.Text]).value
# parse the conditional << if $x >> when it exists # parse the conditional << if $x >> when it exists
var tags : Array = []#string var tags : Array = []#string
while( parser.next_symbols_are([WolGlobals.TokenType.BeginCommand,WolGlobals.TokenType.IfToken]) while( parser.next_symbols_are([Constants.TokenType.BeginCommand,Constants.TokenType.IfToken])
|| parser.next_symbol_is([WolGlobals.TokenType.TagMarker])): || parser.next_symbol_is([Constants.TokenType.TagMarker])):
if parser.next_symbols_are([WolGlobals.TokenType.BeginCommand, WolGlobals.TokenType.IfToken]): if parser.next_symbols_are([Constants.TokenType.BeginCommand, Constants.TokenType.IfToken]):
parser.expect_symbol([WolGlobals.TokenType.BeginCommand]) parser.expect_symbol([Constants.TokenType.BeginCommand])
parser.expect_symbol([WolGlobals.TokenType.IfToken]) parser.expect_symbol([Constants.TokenType.IfToken])
condition = ExpressionNode.parse(self,parser) condition = ExpressionNode.parse(self,parser)
parser.expect_symbol([WolGlobals.TokenType.EndCommand]) parser.expect_symbol([Constants.TokenType.EndCommand])
elif parser.next_symbol_is([WolGlobals.TokenType.TagMarker]): elif parser.next_symbol_is([Constants.TokenType.TagMarker]):
parser.expect_symbol([WolGlobals.TokenType.TagMarker]) parser.expect_symbol([Constants.TokenType.TagMarker])
var tag : String = parser.expect_symbol([WolGlobals.TokenType.Identifier]).value; var tag : String = parser.expect_symbol([Constants.TokenType.Identifier]).value;
tags.append(tag) tags.append(tag)
self.tags = tags self.tags = tags
# parse remaining statements # parse remaining statements
if parser.next_symbol_is([WolGlobals.TokenType.Indent]): if parser.next_symbol_is([Constants.TokenType.Indent]):
parser.expect_symbol([WolGlobals.TokenType.Indent]) parser.expect_symbol([Constants.TokenType.Indent])
node = WolNode.new("%s.%s" %[self.get_node_parent().name ,index], self,parser) node = WolNode.new('%s.%s' %[self.get_node_parent().name ,index], self,parser)
parser.expect_symbol([WolGlobals.TokenType.Dedent]) parser.expect_symbol([Constants.TokenType.Dedent])
func tree_string(indentLevel : int)->String: func tree_string(indentLevel : int)->String:
var info : PoolStringArray = [] var info : PoolStringArray = []
info.append(tab(indentLevel,"Option \"%s\""%label)) info.append(tab(indentLevel,'Option \'%s\''%label))
if condition != null : if condition != null :
info.append(tab(indentLevel+1,"(when:")) info.append(tab(indentLevel+1,'(when:'))
info.append(condition.tree_string(indentLevel+2)) info.append(condition.tree_string(indentLevel+2))
info.append(tab(indentLevel+1,"),")) info.append(tab(indentLevel+1,'),'))
if node != null: if node != null:
info.append(tab(indentLevel, "{")) info.append(tab(indentLevel, '{'))
info.append(node.tree_string(indentLevel + 1)); info.append(node.tree_string(indentLevel + 1));
info.append(tab(indentLevel, "}")); info.append(tab(indentLevel, '}'));
return info.join("") return info.join('')
@ -346,31 +345,31 @@ class Block extends ParseNode:
func _init(parent:ParseNode, parser).(parent,parser): func _init(parent:ParseNode, parser).(parent,parser):
#read indent #read indent
parser.expect_symbol([WolGlobals.TokenType.Indent]) parser.expect_symbol([Constants.TokenType.Indent])
#keep reading statements until we hit a dedent #keep reading statements until we hit a dedent
while !parser.next_symbol_is([WolGlobals.TokenType.Dedent]): while !parser.next_symbol_is([Constants.TokenType.Dedent]):
#parse all statements including nested blocks #parse all statements including nested blocks
statements.append(Statement.new(self,parser)) statements.append(Statement.new(self,parser))
#clean up dedent #clean up dedent
parser.expect_symbol([WolGlobals.TokenType.Dedent]) parser.expect_symbol([Constants.TokenType.Dedent])
func tree_string(indentLevel : int)->String: func tree_string(indentLevel : int)->String:
var info : PoolStringArray = [] var info : PoolStringArray = []
info.append(tab(indentLevel,"Block {")) info.append(tab(indentLevel,'Block {'))
for statement in statements: for statement in statements:
info.append(statement.tree_string(indentLevel+1)) info.append(statement.tree_string(indentLevel+1))
info.append(tab(indentLevel,"}")) info.append(tab(indentLevel,'}'))
return info.join("") return info.join('')
static func can_parse(parser)->bool: static func can_parse(parser)->bool:
return parser.next_symbol_is([WolGlobals.TokenType.Indent]) return parser.next_symbol_is([Constants.TokenType.Indent])
#Option Statements are links to other nodes #Option Statements are links to other nodes
class OptionStatement extends ParseNode: class OptionStatement extends ParseNode:
@ -383,29 +382,29 @@ class OptionStatement extends ParseNode:
var strings : Array = []#string var strings : Array = []#string
#parse [[LABEL #parse [[LABEL
parser.expect_symbol([WolGlobals.TokenType.OptionStart]) parser.expect_symbol([Constants.TokenType.OptionStart])
strings.append(parser.expect_symbol([WolGlobals.TokenType.Text]).value) strings.append(parser.expect_symbol([Constants.TokenType.Text]).value)
#if there is a | get the next string #if there is a | get the next string
if parser.next_symbol_is([WolGlobals.TokenType.OptionDelimit]): if parser.next_symbol_is([Constants.TokenType.OptionDelimit]):
parser.expect_symbol([WolGlobals.TokenType.OptionDelimit]) parser.expect_symbol([Constants.TokenType.OptionDelimit])
var t = parser.expect_symbol([WolGlobals.TokenType.Text,WolGlobals.TokenType.Identifier]) var t = parser.expect_symbol([Constants.TokenType.Text,Constants.TokenType.Identifier])
#print("Token %s"%t.value) #print('Token %s'%t.value)
strings.append(t.value as String) strings.append(t.value as String)
label = strings[0] if strings.size() > 1 else "" label = strings[0] if strings.size() > 1 else ''
destination = strings[1] if strings.size() > 1 else strings[0] destination = strings[1] if strings.size() > 1 else strings[0]
parser.expect_symbol([WolGlobals.TokenType.OptionEnd]) parser.expect_symbol([Constants.TokenType.OptionEnd])
func tree_string(indentLevel : int)->String: func tree_string(indentLevel : int)->String:
if label != null: if label != null:
return tab(indentLevel,"Option: %s -> %s"%[label,destination]) return tab(indentLevel,'Option: %s -> %s'%[label,destination])
else: else:
return tab(indentLevel,"Option: -> %s"%destination) return tab(indentLevel,'Option: -> %s'%destination)
static func can_parse(parser)->bool: static func can_parse(parser)->bool:
return parser.next_symbol_is([WolGlobals.TokenType.OptionStart]) return parser.next_symbol_is([Constants.TokenType.OptionStart])
class IfStatement extends ParseNode: class IfStatement extends ParseNode:
@ -416,80 +415,80 @@ class IfStatement extends ParseNode:
#<<if Expression>> #<<if Expression>>
var prime : Clause = Clause.new() var prime : Clause = Clause.new()
parser.expect_symbol([WolGlobals.TokenType.BeginCommand]) parser.expect_symbol([Constants.TokenType.BeginCommand])
parser.expect_symbol([WolGlobals.TokenType.IfToken]) parser.expect_symbol([Constants.TokenType.IfToken])
prime.expression = ExpressionNode.parse(self,parser) prime.expression = ExpressionNode.parse(self,parser)
parser.expect_symbol([WolGlobals.TokenType.EndCommand]) parser.expect_symbol([Constants.TokenType.EndCommand])
#read statements until 'endif' or 'else' or 'else if' #read statements until 'endif' or 'else' or 'else if'
var statements : Array = []#statement var statements : Array = []#statement
while (!parser.next_symbols_are([WolGlobals.TokenType.BeginCommand, WolGlobals.TokenType.EndIf]) while (!parser.next_symbols_are([Constants.TokenType.BeginCommand, Constants.TokenType.EndIf])
&& !parser.next_symbols_are([WolGlobals.TokenType.BeginCommand, WolGlobals.TokenType.ElseToken]) && !parser.next_symbols_are([Constants.TokenType.BeginCommand, Constants.TokenType.ElseToken])
&& !parser.next_symbols_are([WolGlobals.TokenType.BeginCommand, WolGlobals.TokenType.ElseIf])): && !parser.next_symbols_are([Constants.TokenType.BeginCommand, Constants.TokenType.ElseIf])):
statements.append(Statement.new(self,parser)) statements.append(Statement.new(self,parser))
#ignore dedent #ignore dedent
while parser.next_symbol_is([WolGlobals.TokenType.Dedent]): while parser.next_symbol_is([Constants.TokenType.Dedent]):
parser.expect_symbol([WolGlobals.TokenType.Dedent]) parser.expect_symbol([Constants.TokenType.Dedent])
prime.statements = statements prime.statements = statements
clauses.append(prime) clauses.append(prime)
#handle all else if #handle all else if
while parser.next_symbols_are([WolGlobals.TokenType.BeginCommand,WolGlobals.TokenType.ElseIf]): while parser.next_symbols_are([Constants.TokenType.BeginCommand,Constants.TokenType.ElseIf]):
var clauseElif : Clause = Clause.new() var clauseElif : Clause = Clause.new()
#parse condition syntax #parse condition syntax
parser.expect_symbol([WolGlobals.TokenType.BeginCommand]) parser.expect_symbol([Constants.TokenType.BeginCommand])
parser.expect_symbol([WolGlobals.TokenType.ElseIf]) parser.expect_symbol([Constants.TokenType.ElseIf])
clauseElif.expression = ExpressionNode.parse(self,parser) clauseElif.expression = ExpressionNode.parse(self,parser)
parser.expect_symbol([WolGlobals.TokenType.EndCommand]) parser.expect_symbol([Constants.TokenType.EndCommand])
var elifStatements : Array = []#statement var elifStatements : Array = []#statement
while (!parser.next_symbols_are([WolGlobals.TokenType.BeginCommand, WolGlobals.TokenType.EndIf]) while (!parser.next_symbols_are([Constants.TokenType.BeginCommand, Constants.TokenType.EndIf])
&& !parser.next_symbols_are([WolGlobals.TokenType.BeginCommand, WolGlobals.TokenType.ElseToken]) && !parser.next_symbols_are([Constants.TokenType.BeginCommand, Constants.TokenType.ElseToken])
&& !parser.next_symbols_are([WolGlobals.TokenType.BeginCommand, WolGlobals.TokenType.ElseIf])): && !parser.next_symbols_are([Constants.TokenType.BeginCommand, Constants.TokenType.ElseIf])):
elifStatements.append(Statement.new(self,parser)) elifStatements.append(Statement.new(self,parser))
#ignore dedent #ignore dedent
while parser.next_symbol_is([WolGlobals.TokenType.Dedent]): while parser.next_symbol_is([Constants.TokenType.Dedent]):
parser.expect_symbol([WolGlobals.TokenType.Dedent]) parser.expect_symbol([Constants.TokenType.Dedent])
clauseElif.statements = statements clauseElif.statements = statements
clauses.append(clauseElif) clauses.append(clauseElif)
#handle else if exists #handle else if exists
if (parser.next_symbols_are([WolGlobals.TokenType.BeginCommand, if (parser.next_symbols_are([Constants.TokenType.BeginCommand,
WolGlobals.TokenType.ElseToken,WolGlobals.TokenType.EndCommand])): Constants.TokenType.ElseToken,Constants.TokenType.EndCommand])):
#expect no expression - just <<else>> #expect no expression - just <<else>>
parser.expect_symbol([WolGlobals.TokenType.BeginCommand]) parser.expect_symbol([Constants.TokenType.BeginCommand])
parser.expect_symbol([WolGlobals.TokenType.ElseToken]) parser.expect_symbol([Constants.TokenType.ElseToken])
parser.expect_symbol([WolGlobals.TokenType.EndCommand]) parser.expect_symbol([Constants.TokenType.EndCommand])
#parse until hit endif #parse until hit endif
var clauseElse : Clause = Clause.new() var clauseElse : Clause = Clause.new()
var elStatements : Array = []#statement var elStatements : Array = []#statement
while !parser.next_symbols_are([WolGlobals.TokenType.BeginCommand,WolGlobals.TokenType.EndIf]): while !parser.next_symbols_are([Constants.TokenType.BeginCommand,Constants.TokenType.EndIf]):
elStatements.append(Statement.new(self,parser)) elStatements.append(Statement.new(self,parser))
clauseElse.statements = elStatements clauseElse.statements = elStatements
clauses.append(clauseElse) clauses.append(clauseElse)
#ignore dedent #ignore dedent
while parser.next_symbol_is([WolGlobals.TokenType.Dedent]): while parser.next_symbol_is([Constants.TokenType.Dedent]):
parser.expect_symbol([WolGlobals.TokenType.Dedent]) parser.expect_symbol([Constants.TokenType.Dedent])
#finish #finish
parser.expect_symbol([WolGlobals.TokenType.BeginCommand]) parser.expect_symbol([Constants.TokenType.BeginCommand])
parser.expect_symbol([WolGlobals.TokenType.EndIf]) parser.expect_symbol([Constants.TokenType.EndIf])
parser.expect_symbol([WolGlobals.TokenType.EndCommand]) parser.expect_symbol([Constants.TokenType.EndCommand])
func tree_string(indentLevel : int)->String: func tree_string(indentLevel : int)->String:
@ -498,55 +497,55 @@ class IfStatement extends ParseNode:
for clause in clauses: for clause in clauses:
if first: if first:
info.append(tab(indentLevel,"if:")) info.append(tab(indentLevel,'if:'))
elif clause.expression!=null: elif clause.expression!=null:
info.append(tab(indentLevel,"Else If")) info.append(tab(indentLevel,'Else If'))
else: else:
info.append(tab(indentLevel,"Else:")) info.append(tab(indentLevel,'Else:'))
info.append(clause.tree_string(indentLevel +1)) info.append(clause.tree_string(indentLevel +1))
return info.join("") return info.join('')
static func can_parse(parser)->bool: static func can_parse(parser)->bool:
return parser.next_symbols_are([WolGlobals.TokenType.BeginCommand,WolGlobals.TokenType.IfToken]) return parser.next_symbols_are([Constants.TokenType.BeginCommand,Constants.TokenType.IfToken])
pass pass
class ValueNode extends ParseNode: class ValueNode extends ParseNode:
const Value = preload("res://addons/Wol/core/value.gd") const Value = preload('res://addons/Wol/core/value.gd')
const Lexer = preload("res://addons/Wol/core/compiler/lexer.gd") const Lexer = preload('res://addons/Wol/core/compiler/lexer.gd')
var value : Value var value : Value
func _init(parent:ParseNode, parser, token: Lexer.Token = null).(parent,parser): func _init(parent:ParseNode, parser, token: Lexer.Token = null).(parent,parser):
var t : Lexer.Token = token var t : Lexer.Token = token
if t == null : if t == null :
parser.expect_symbol([WolGlobals.TokenType.Number, parser.expect_symbol([Constants.TokenType.Number,
WolGlobals.TokenType.Variable,WolGlobals.TokenType.Str]) Constants.TokenType.Variable,Constants.TokenType.Str])
use_token(t) use_token(t)
#store value depending on type #store value depending on type
func use_token(t:Lexer.Token): func use_token(t:Lexer.Token):
match t.type: match t.type:
WolGlobals.TokenType.Number: Constants.TokenType.Number:
value = Value.new(float(t.value)) value = Value.new(float(t.value))
WolGlobals.TokenType.Str: Constants.TokenType.Str:
value = Value.new(t.value) value = Value.new(t.value)
WolGlobals.TokenType.FalseToken: Constants.TokenType.FalseToken:
value = Value.new(false) value = Value.new(false)
WolGlobals.TokenType.TrueToken: Constants.TokenType.TrueToken:
value = Value.new(true) value = Value.new(true)
WolGlobals.TokenType.Variable: Constants.TokenType.Variable:
value = Value.new(null) value = Value.new(null)
value.type = WolGlobals.ValueType.Variable value.type = Constants.ValueType.Variable
value.variable = t.value value.variable = t.value
WolGlobals.TokenType.NullToken: Constants.TokenType.NullToken:
value = Value.new(null) value = Value.new(null)
_: _:
printerr("%s, Invalid token type" % t.name) printerr('%s, Invalid token type' % t.name)
func tree_string(indentLevel : int)->String: func tree_string(indentLevel : int)->String:
return tab(indentLevel, "%s"%value.value()) return tab(indentLevel, '%s'%value.value())
#Expressions encompass a wide range of things like: #Expressions encompass a wide range of things like:
@ -560,31 +559,31 @@ class ExpressionNode extends ParseNode:
var function : String var function : String
var params : Array = []#ExpressionNode var params : Array = []#ExpressionNode
func _init(parent:ParseNode,parser,value:ValueNode,function:String="",params:Array=[]).(parent,parser): func _init(parent:ParseNode,parser,value:ValueNode,function:String='',params:Array=[]).(parent,parser):
#no function - means value #no function - means value
if value!=null: if value!=null:
self.type = WolGlobals.ExpressionType.Value self.type = Constants.ExpressionType.Value
self.value = value self.value = value
else:#function else:#function
self.type = WolGlobals.ExpressionType.FunctionCall self.type = Constants.ExpressionType.FunctionCall
self.function = function self.function = function
self.params = params self.params = params
func tree_string(indentLevel : int)->String: func tree_string(indentLevel : int)->String:
var info : PoolStringArray = [] var info : PoolStringArray = []
match type: match type:
WolGlobals.ExpressionType.Value: Constants.ExpressionType.Value:
return value.tree_string(indentLevel) return value.tree_string(indentLevel)
WolGlobals.ExpressionType.FunctionCall: Constants.ExpressionType.FunctionCall:
info.append(tab(indentLevel,"Func[%s - params(%s)]:{"%[function,params.size()])) info.append(tab(indentLevel,'Func[%s - params(%s)]:{'%[function,params.size()]))
for param in params: for param in params:
#print("----> %s paramSize:%s"%[(function) , params.size()]) #print('----> %s paramSize:%s'%[(function) , params.size()])
info.append(param.tree_string(indentLevel+1)) info.append(param.tree_string(indentLevel+1))
info.append(tab(indentLevel,"}")) info.append(tab(indentLevel,'}'))
return info.join("") return info.join('')
#using Djikstra's shunting-yard algorithm to convert #using Djikstra's shunting-yard algorithm to convert
#stream of expresions into postfix notaion, then #stream of expresions into postfix notaion, then
@ -599,16 +598,16 @@ class ExpressionNode extends ParseNode:
var funcStack : Array = []#token var funcStack : Array = []#token
var validTypes : Array = [ var validTypes : Array = [
WolGlobals.TokenType.Number, Constants.TokenType.Number,
WolGlobals.TokenType.Variable, Constants.TokenType.Variable,
WolGlobals.TokenType.Str, Constants.TokenType.Str,
WolGlobals.TokenType.LeftParen, Constants.TokenType.LeftParen,
WolGlobals.TokenType.RightParen, Constants.TokenType.RightParen,
WolGlobals.TokenType.Identifier, Constants.TokenType.Identifier,
WolGlobals.TokenType.Comma, Constants.TokenType.Comma,
WolGlobals.TokenType.TrueToken, Constants.TokenType.TrueToken,
WolGlobals.TokenType.FalseToken, Constants.TokenType.FalseToken,
WolGlobals.TokenType.NullToken Constants.TokenType.NullToken
] ]
validTypes+=Operator.op_types() validTypes+=Operator.op_types()
validTypes.invert() validTypes.invert()
@ -619,38 +618,38 @@ class ExpressionNode extends ParseNode:
while parser.tokens().size() > 0 && parser.next_symbol_is(validTypes): while parser.tokens().size() > 0 && parser.next_symbol_is(validTypes):
var next = parser.expect_symbol(validTypes) #lexer.Token var next = parser.expect_symbol(validTypes) #lexer.Token
if( next.type == WolGlobals.TokenType.Variable || if( next.type == Constants.TokenType.Variable ||
next.type == WolGlobals.TokenType.Number || next.type == Constants.TokenType.Number ||
next.type == WolGlobals.TokenType.Str || next.type == Constants.TokenType.Str ||
next.type == WolGlobals.TokenType.TrueToken || next.type == Constants.TokenType.TrueToken ||
next.type == WolGlobals.TokenType.FalseToken || next.type == Constants.TokenType.FalseToken ||
next.type == WolGlobals.TokenType.NullToken ): next.type == Constants.TokenType.NullToken ):
#output primitives #output primitives
rpn.append(next) rpn.append(next)
elif next.type == WolGlobals.TokenType.Identifier: elif next.type == Constants.TokenType.Identifier:
opStack.push_back(next) opStack.push_back(next)
funcStack.push_back(next) funcStack.push_back(next)
#next token is parent - left #next token is parent - left
next = parser.expect_symbol([WolGlobals.TokenType.LeftParen]) next = parser.expect_symbol([Constants.TokenType.LeftParen])
opStack.push_back(next) opStack.push_back(next)
elif next.type == WolGlobals.TokenType.Comma: elif next.type == Constants.TokenType.Comma:
#resolve sub expression before moving on #resolve sub expression before moving on
while opStack.back().type != WolGlobals.TokenType.LeftParen: while opStack.back().type != Constants.TokenType.LeftParen:
var p = opStack.pop_back() var p = opStack.pop_back()
if p == null: if p == null:
printerr("unbalanced parenthesis %s " % next.name) printerr('unbalanced parenthesis %s ' % next.name)
break break
rpn.append(p) rpn.append(p)
#next token in opStack left paren #next token in opStack left paren
# next parser token not allowed to be right paren or comma # next parser token not allowed to be right paren or comma
if parser.next_symbol_is([WolGlobals.TokenType.RightParen, if parser.next_symbol_is([Constants.TokenType.RightParen,
WolGlobals.TokenType.Comma]): Constants.TokenType.Comma]):
printerr("Expected Expression : %s" % parser.tokens().front().name) printerr('Expected Expression : %s' % parser.tokens().front().name)
#find the closest function on stack #find the closest function on stack
#increment parameters #increment parameters
@ -668,17 +667,17 @@ class ExpressionNode extends ParseNode:
#is only unary when the last token was a left paren, #is only unary when the last token was a left paren,
#an operator, or its the first token. #an operator, or its the first token.
if (next.type == WolGlobals.TokenType.Minus): if (next.type == Constants.TokenType.Minus):
if (last == null || if (last == null ||
last.type == WolGlobals.TokenType.LeftParen || last.type == Constants.TokenType.LeftParen ||
Operator.is_op(last.type)): Operator.is_op(last.type)):
#unary minus #unary minus
next.type = WolGlobals.TokenType.UnaryMinus next.type = Constants.TokenType.UnaryMinus
#cannot assign inside expression #cannot assign inside expression
# x = a is the same as x == a # x = a is the same as x == a
if next.type == WolGlobals.TokenType.EqualToOrAssign: if next.type == Constants.TokenType.EqualToOrAssign:
next.type = WolGlobals.TokenType.EqualTo next.type = Constants.TokenType.EqualTo
#operator precedence #operator precedence
@ -688,25 +687,25 @@ class ExpressionNode extends ParseNode:
opStack.push_back(next) opStack.push_back(next)
elif next.type == WolGlobals.TokenType.LeftParen: elif next.type == Constants.TokenType.LeftParen:
#entered parenthesis sub expression #entered parenthesis sub expression
opStack.push_back(next) opStack.push_back(next)
elif next.type == WolGlobals.TokenType.RightParen: elif next.type == Constants.TokenType.RightParen:
#leaving sub expression #leaving sub expression
# resolve order of operations # resolve order of operations
while opStack.back().type != WolGlobals.TokenType.LeftParen: while opStack.back().type != Constants.TokenType.LeftParen:
rpn.append(opStack.pop_back()) rpn.append(opStack.pop_back())
if opStack.back() == null: if opStack.back() == null:
printerr("Unbalanced parenthasis #RightParen. Parser.ExpressionNode") printerr('Unbalanced parenthasis #RightParen. Parser.ExpressionNode')
opStack.pop_back() opStack.pop_back()
if opStack.back().type == WolGlobals.TokenType.Identifier: if opStack.back().type == Constants.TokenType.Identifier:
#function call #function call
#last token == left paren this == no params #last token == left paren this == no params
#else #else
#we have more than 1 param #we have more than 1 param
if last.type != WolGlobals.TokenType.LeftParen: if last.type != Constants.TokenType.LeftParen:
funcStack.back().paramCount+=1 funcStack.back().paramCount+=1
rpn.append(opStack.pop_back()) rpn.append(opStack.pop_back())
@ -721,7 +720,7 @@ class ExpressionNode extends ParseNode:
#if rpn is empty then this is not expression #if rpn is empty then this is not expression
if rpn.size() == 0: if rpn.size() == 0:
printerr("Error parsing expression: Expression not found!") printerr('Error parsing expression: Expression not found!')
#build expression tree #build expression tree
var first = rpn.front() var first = rpn.front()
@ -735,7 +734,7 @@ class ExpressionNode extends ParseNode:
var info : OperatorInfo = Operator.op_info(next.type) var info : OperatorInfo = Operator.op_info(next.type)
if evalStack.size() < info.arguments: if evalStack.size() < info.arguments:
printerr("Error parsing : Not enough arguments for %s [ got %s expected - was %s]"%[WolGlobals.token_type_name(next.type),evalStack.size(),info.arguments]) printerr('Error parsing : Not enough arguments for %s [ got %s expected - was %s]'%[Constants.token_type_name(next.type),evalStack.size(),info.arguments])
var params : Array = []#ExpressionNode var params : Array = []#ExpressionNode
for i in range(info.arguments): for i in range(info.arguments):
@ -749,7 +748,7 @@ class ExpressionNode extends ParseNode:
evalStack.append(expression) evalStack.append(expression)
elif next.type == WolGlobals.TokenType.Identifier: elif next.type == Constants.TokenType.Identifier:
#function call #function call
var function : String = next.value var function : String = next.value
@ -773,7 +772,7 @@ class ExpressionNode extends ParseNode:
#we should have a single root expression left #we should have a single root expression left
#if more then we failed ---- NANI #if more then we failed ---- NANI
if evalStack.size() != 1: if evalStack.size() != 1:
printerr("[%s] Error parsing expression (stack did not reduce correctly )"%first.name) printerr('[%s] Error parsing expression (stack did not reduce correctly )'%first.name)
@ -783,10 +782,10 @@ class ExpressionNode extends ParseNode:
# return false # return false
static func get_func_name(type)->String: static func get_func_name(type)->String:
var string : String = "" var string : String = ''
for key in WolGlobals.TokenType.keys(): for key in Constants.TokenType.keys():
if WolGlobals.TokenType[key] == type: if Constants.TokenType[key] == type:
return key return key
return string return string
@ -795,7 +794,7 @@ class ExpressionNode extends ParseNode:
return false return false
if !Operator.is_op(type): if !Operator.is_op(type):
printerr("Unable to parse expression!") printerr('Unable to parse expression!')
var second = operatorStack.back().type var second = operatorStack.back().type
@ -822,35 +821,35 @@ class Assignment extends ParseNode:
var operation var operation
func _init(parent:ParseNode,parser).(parent,parser): func _init(parent:ParseNode,parser).(parent,parser):
parser.expect_symbol([WolGlobals.TokenType.BeginCommand]) parser.expect_symbol([Constants.TokenType.BeginCommand])
parser.expect_symbol([WolGlobals.TokenType.Set]) parser.expect_symbol([Constants.TokenType.Set])
destination = parser.expect_symbol([WolGlobals.TokenType.Variable]).value destination = parser.expect_symbol([Constants.TokenType.Variable]).value
operation = parser.expect_symbol(Assignment.valid_ops()).type operation = parser.expect_symbol(Assignment.valid_ops()).type
value = ExpressionNode.parse(self,parser) value = ExpressionNode.parse(self,parser)
parser.expect_symbol([WolGlobals.TokenType.EndCommand]) parser.expect_symbol([Constants.TokenType.EndCommand])
func tree_string(indentLevel : int)->String: func tree_string(indentLevel : int)->String:
var info : PoolStringArray = [] var info : PoolStringArray = []
info.append(tab(indentLevel,"set:")) info.append(tab(indentLevel,'set:'))
info.append(tab(indentLevel+1,destination)) info.append(tab(indentLevel+1,destination))
info.append(tab(indentLevel+1,WolGlobals.token_type_name(operation))) info.append(tab(indentLevel+1,Constants.token_type_name(operation)))
info.append(value.tree_string(indentLevel+1)) info.append(value.tree_string(indentLevel+1))
return info.join("") return info.join('')
static func can_parse(parser)->bool: static func can_parse(parser)->bool:
return parser.next_symbols_are([ return parser.next_symbols_are([
WolGlobals.TokenType.BeginCommand, Constants.TokenType.BeginCommand,
WolGlobals.TokenType.Set Constants.TokenType.Set
]) ])
static func valid_ops()->Array: static func valid_ops()->Array:
return [ return [
WolGlobals.TokenType.EqualToOrAssign, Constants.TokenType.EqualToOrAssign,
WolGlobals.TokenType.AddAssign, Constants.TokenType.AddAssign,
WolGlobals.TokenType.MinusAssign, Constants.TokenType.MinusAssign,
WolGlobals.TokenType.DivideAssign, Constants.TokenType.DivideAssign,
WolGlobals.TokenType.MultiplyAssign Constants.TokenType.MultiplyAssign
] ]
class Operator extends ParseNode: class Operator extends ParseNode:
@ -867,15 +866,15 @@ class Operator extends ParseNode:
func tree_string(indentLevel : int)->String: func tree_string(indentLevel : int)->String:
var info : PoolStringArray = [] var info : PoolStringArray = []
info.append(tab(indentLevel,opType)) info.append(tab(indentLevel,opType))
return info.join("") return info.join('')
static func op_info(op)->OperatorInfo: static func op_info(op)->OperatorInfo:
if !Operator.is_op(op) : if !Operator.is_op(op) :
printerr("%s is not a valid operator" % op.name) printerr('%s is not a valid operator' % op.name)
#determine associativity and operands #determine associativity and operands
# each operand has # each operand has
var TokenType = WolGlobals.TokenType var TokenType = Constants.TokenType
match op: match op:
TokenType.Not, TokenType.UnaryMinus: TokenType.Not, TokenType.UnaryMinus:
@ -895,7 +894,7 @@ class Operator extends ParseNode:
TokenType.Xor: TokenType.Xor:
return OperatorInfo.new(Associativity.Left,2,2) return OperatorInfo.new(Associativity.Left,2,2)
_: _:
printerr("Unknown operator: %s" % op.name) printerr('Unknown operator: %s' % op.name)
return null return null
static func is_op(type)->bool: static func is_op(type)->bool:
@ -903,27 +902,27 @@ class Operator extends ParseNode:
static func op_types()->Array: static func op_types()->Array:
return [ return [
WolGlobals.TokenType.Not, Constants.TokenType.Not,
WolGlobals.TokenType.UnaryMinus, Constants.TokenType.UnaryMinus,
WolGlobals.TokenType.Add, Constants.TokenType.Add,
WolGlobals.TokenType.Minus, Constants.TokenType.Minus,
WolGlobals.TokenType.Divide, Constants.TokenType.Divide,
WolGlobals.TokenType.Multiply, Constants.TokenType.Multiply,
WolGlobals.TokenType.Modulo, Constants.TokenType.Modulo,
WolGlobals.TokenType.EqualToOrAssign, Constants.TokenType.EqualToOrAssign,
WolGlobals.TokenType.EqualTo, Constants.TokenType.EqualTo,
WolGlobals.TokenType.GreaterThan, Constants.TokenType.GreaterThan,
WolGlobals.TokenType.GreaterThanOrEqualTo, Constants.TokenType.GreaterThanOrEqualTo,
WolGlobals.TokenType.LessThan, Constants.TokenType.LessThan,
WolGlobals.TokenType.LessThanOrEqualTo, Constants.TokenType.LessThanOrEqualTo,
WolGlobals.TokenType.NotEqualTo, Constants.TokenType.NotEqualTo,
WolGlobals.TokenType.And, Constants.TokenType.And,
WolGlobals.TokenType.Or, Constants.TokenType.Or,
WolGlobals.TokenType.Xor Constants.TokenType.Xor
] ]
@ -950,12 +949,12 @@ class Clause:
var info : PoolStringArray = [] var info : PoolStringArray = []
if expression!=null: if expression!=null:
info.append(expression.tree_string(indentLevel)) info.append(expression.tree_string(indentLevel))
info.append(tab(indentLevel,"{")) info.append(tab(indentLevel,'{'))
for statement in statements: for statement in statements:
info.append(statement.tree_string(indentLevel+1)) info.append(statement.tree_string(indentLevel+1))
info.append(tab(indentLevel,"}")) info.append(tab(indentLevel,'}'))
return info.join("") return info.join('')
func tab(indentLevel : int , input : String,newLine : bool = true)->String: func tab(indentLevel : int , input : String,newLine : bool = true)->String:
return ("%*s| %s%s"% [indentLevel*2,"",input,("" if !newLine else "\n")]) return ('%*s| %s%s'% [indentLevel*2,'',input,('' if !newLine else '\n')])

View file

@ -1,4 +1,5 @@
extends Node extends Object
class_name Constants
enum ExecutionState { enum ExecutionState {
Stopped, Stopped,
@ -189,7 +190,7 @@ func token_name(type)->String:
return key return key
return string return string
func bytecode_name(bytecode): static func bytecode_name(bytecode):
return [ return [
'Label', 'Label',
'JumpTo', 'JumpTo',

View file

@ -1,12 +1,13 @@
extends Node extends Node
const DEFAULT_START = "Start" const DEFAULT_START = 'Start'
const FMF_PLACEHOLDE = "<VALUE PLACEHOLDER>" const FMF_PLACEHOLDE = '<VALUE PLACEHOLDER>'
const StandardLibrary = preload("res://addons/Wol/core/libraries/standard.gd") const Constants = preload('res://addons/Wol/core/constants.gd')
const VirtualMachine = preload("res://addons/Wol/core/virtual_machine.gd") const StandardLibrary = preload('res://addons/Wol/core/libraries/standard.gd')
const WolLibrary = preload("res://addons/Wol/core/library.gd") const VirtualMachine = preload('res://addons/Wol/core/virtual_machine.gd')
const Value = preload("res://addons/Wol/core/value.gd") const WolLibrary = preload('res://addons/Wol/core/library.gd')
const Value = preload('res://addons/Wol/core/value.gd')
var _variableStorage var _variableStorage
@ -26,8 +27,8 @@ func _init(variableStorage):
_variableStorage = variableStorage _variableStorage = variableStorage
_vm = VirtualMachine.new(self) _vm = VirtualMachine.new(self)
library = WolLibrary.new() library = WolLibrary.new()
_debugLog = funcref(self, "dlog") _debugLog = funcref(self, 'dlog')
_errLog = funcref(self, "elog") _errLog = funcref(self, 'elog')
executionComplete = false executionComplete = false
# import the standard library # import the standard library
@ -35,20 +36,20 @@ func _init(variableStorage):
library.import_library(StandardLibrary.new())#FIX library.import_library(StandardLibrary.new())#FIX
#add a function to lib that checks if node is visited #add a function to lib that checks if node is visited
library.register_function("visited", -1, funcref(self, "is_node_visited"), true) library.register_function('visited', -1, funcref(self, 'is_node_visited'), true)
#add function to lib that gets the node visit count #add function to lib that gets the node visit count
library.register_function("visit_count", -1, funcref(self, "node_visit_count"), true) library.register_function('visit_count', -1, funcref(self, 'node_visit_count'), true)
func dlog(message:String): func dlog(message:String):
print("YARN_DEBUG : %s" % message) print('YARN_DEBUG : %s' % message)
func elog(message:String): func elog(message:String):
print("YARN_ERROR : %s" % message) print('YARN_ERROR : %s' % message)
func is_active(): func is_active():
return get_exec_state() != WolGlobals.ExecutionState.Stopped return get_exec_state() != Constants.ExecutionState.Stopped
#gets the current execution state of the virtual machine #gets the current execution state of the virtual machine
func get_exec_state(): func get_exec_state():
@ -61,7 +62,7 @@ func set_node(name:String = DEFAULT_START):
_vm.set_node(name) _vm.set_node(name)
func resume(): func resume():
if _vm.executionState == WolGlobals.ExecutionState.Running: if _vm.executionState == Constants.ExecutionState.Running:
print('BLOCKED') print('BLOCKED')
return return
_vm.resume() _vm.resume()
@ -80,13 +81,13 @@ func current_node():
func get_node_id(name): func get_node_id(name):
if _program.nodes.size() == 0: if _program.nodes.size() == 0:
_errLog.call_func("No nodes loaded") _errLog.call_func('No nodes loaded')
return "" return ''
if _program.nodes.has(name): if _program.nodes.has(name):
return "id:"+name return 'id:'+name
else: else:
_errLog.call_func("No node named [%s] exists" % name) _errLog.call_func('No node named [%s] exists' % name)
return "" return ''
func unloadAll(clear_visited:bool = true): func unloadAll(clear_visited:bool = true):
if clear_visited : if clear_visited :
@ -122,7 +123,7 @@ func node_visit_count(node = _vm.current_node_name()):
visitCount = _visitedNodeCount[node] visitCount = _visitedNodeCount[node]
print("visit count for %s is %d" % [node, visitCount]) print('visit count for %s is %d' % [node, visitCount])
return visitCount return visitCount

View file

@ -1,6 +1,7 @@
extends Object extends Object
const FunctionInfo = preload("res://addons/Wol/core/function_info.gd") const FunctionInfo = preload("res://addons/Wol/core/function_info.gd")
const Constants = preload('res://addons/Wol/core/constants.gd')
var functions : Dictionary = {}# String , FunctionInfo var functions : Dictionary = {}# String , FunctionInfo
@ -12,7 +13,7 @@ func get_function(name:String)->FunctionInfo:
return null return null
func import_library(other)->void: func import_library(other)->void:
WolGlobals.merge_dir(functions,other.functions) Constants.merge_dir(functions,other.functions)
func register_function(name: String, paramCount: int, function: FuncRef, returnsValue: bool): func register_function(name: String, paramCount: int, function: FuncRef, returnsValue: bool):
var functionInfo: FunctionInfo = FunctionInfo.new(name, paramCount, function, returnsValue) var functionInfo: FunctionInfo = FunctionInfo.new(name, paramCount, function, returnsValue)

View file

@ -1,6 +1,8 @@
extends Object extends Object
class_name WolProgram class_name WolProgram
const Constants = preload('res://addons/Wol/core/constants.gd')
var name = '' var name = ''
var strings = {} var strings = {}
var nodes = {} var nodes = {}
@ -120,5 +122,5 @@ class Instruction:
return "InstructionInformation:NotImplemented" return "InstructionInformation:NotImplemented"
func _to_string(): func _to_string():
return WolGlobals.bytecode_name(operation) + ':' + operands as String return Constants.bytecode_name(operation) + ':' + operands as String

View file

@ -1,22 +1,21 @@
extends Object extends Object
const WolGlobals = preload("res://addons/Wol/autoloads/execution_states.gd") const Constants = preload('res://addons/Wol/core/constants.gd')
const NULL_STRING : String = "null" const NULL_STRING = 'null'
const FALSE_STRING : String= "false" const FALSE_STRING = 'false'
const TRUE_STRING : String = "true" const TRUE_STRING = 'true'
const NANI : String = "NaN" const NANI = 'NaN'
var type : int = WolGlobals.ValueType.Nullean
var number : float = 0
var string : String = ""
var variable : String = ""
var boolean : bool = false
var type = Constants.ValueType.Nullean
var number = 0
var string = ''
var variable = ''
var boolean = false
func _init(value = NANI): func _init(value = NANI):
if typeof(value) == TYPE_OBJECT && value.get_script() == self.get_script(): if typeof(value) == TYPE_OBJECT && value.get_script() == self.get_script():
if value.type == WolGlobals.ValueType.Variable: if value.type == Constants.ValueType.Variable:
self.type = value.type self.type = value.type
self.variable = value.variable self.variable = value.variable
else: else:
@ -24,62 +23,62 @@ func _init(value = NANI):
func value(): func value():
match type: match type:
WolGlobals.ValueType.Number: Constants.ValueType.Number:
return number return number
WolGlobals.ValueType.Str: Constants.ValueType.Str:
return string return string
WolGlobals.ValueType.Boolean: Constants.ValueType.Boolean:
return boolean return boolean
WolGlobals.ValueType.Variable: Constants.ValueType.Variable:
return variable return variable
return null return null
func as_bool(): func as_bool():
match type: match type:
WolGlobals.ValueType.Number: Constants.ValueType.Number:
return number != 0 return number != 0
WolGlobals.ValueType.Str: Constants.ValueType.Str:
return !string.empty() return !string.empty()
WolGlobals.ValueType.Boolean: Constants.ValueType.Boolean:
return boolean return boolean
return false return false
func as_string(): func as_string():
return "%s" % value() return '%s' % value()
func as_number(): func as_number():
match type: match type:
WolGlobals.ValueType.Number: Constants.ValueType.Number:
return number return number
WolGlobals.ValueType.Str: Constants.ValueType.Str:
return float(string) return float(string)
WolGlobals.ValueType.Boolean: Constants.ValueType.Boolean:
return 0.0 if !boolean else 1.0 return 0.0 if !boolean else 1.0
return .0 return .0
func set_value(value): func set_value(value):
if value == null || (typeof(value) == TYPE_STRING && value == NANI): if value == null || (typeof(value) == TYPE_STRING && value == NANI):
type = WolGlobals.ValueType.Nullean type = Constants.ValueType.Nullean
return return
match typeof(value): match typeof(value):
TYPE_INT,TYPE_REAL: TYPE_INT,TYPE_REAL:
type = WolGlobals.ValueType.Number type = Constants.ValueType.Number
number = value number = value
TYPE_STRING: TYPE_STRING:
type = WolGlobals.ValueType.Str type = Constants.ValueType.Str
string = value string = value
TYPE_BOOL: TYPE_BOOL:
type = WolGlobals.ValueType.Boolean type = Constants.ValueType.Boolean
boolean = value boolean = value
#operations >> #operations >>
#addition #addition
func add(other): func add(other):
if self.type == WolGlobals.ValueType.Str || other.type == WolGlobals.ValueType.Str: if self.type == Constants.ValueType.Str || other.type == Constants.ValueType.Str:
return get_script().new("%s%s"%[self.value(),other.value()]) return get_script().new('%s%s'%[self.value(),other.value()])
if self.type == WolGlobals.ValueType.Number && other.type == WolGlobals.ValueType.Number: if self.type == Constants.ValueType.Number && other.type == Constants.ValueType.Number:
return get_script().new(self.number + other.number) return get_script().new(self.number + other.number)
return null return null
@ -92,60 +91,60 @@ func equals(other)->bool:
#subtract #subtract
func sub(other): func sub(other):
if self.type == WolGlobals.ValueType.Str || other.type == WolGlobals.ValueType.Str: if self.type == Constants.ValueType.Str || other.type == Constants.ValueType.Str:
return get_script().new(str(value()).replace(str(other.value()),"")) return get_script().new(str(value()).replace(str(other.value()),''))
if self.type == WolGlobals.ValueType.Number && other.type == WolGlobals.ValueType.Number: if self.type == Constants.ValueType.Number && other.type == Constants.ValueType.Number:
return get_script().new(self.number - other.number) return get_script().new(self.number - other.number)
return null return null
#multiply #multiply
func mult(other): func mult(other):
if self.type == WolGlobals.ValueType.Number && other.type == WolGlobals.ValueType.Number: if self.type == Constants.ValueType.Number && other.type == Constants.ValueType.Number:
return get_script().new(self.number * other.number) return get_script().new(self.number * other.number)
return null return null
#division #division
func div(other): func div(other):
if self.type == WolGlobals.ValueType.Number && other.type == WolGlobals.ValueType.Number: if self.type == Constants.ValueType.Number && other.type == Constants.ValueType.Number:
return get_script().new(self.number / other.number) return get_script().new(self.number / other.number)
return null return null
#modulus #modulus
func mod(other): func mod(other):
if self.type == WolGlobals.ValueType.Number && other.type == WolGlobals.ValueType.Number: if self.type == Constants.ValueType.Number && other.type == Constants.ValueType.Number:
return get_script().new(self.number % other.number) return get_script().new(self.number % other.number)
return null return null
func negative(): func negative():
if self.type == WolGlobals.ValueType.Number: if self.type == Constants.ValueType.Number:
return get_script().new(-self.number) return get_script().new(-self.number)
return null return null
#greater than other #greater than other
func greater(other)->bool: func greater(other)->bool:
if self.type == WolGlobals.ValueType.Number && other.type == WolGlobals.ValueType.Number: if self.type == Constants.ValueType.Number && other.type == Constants.ValueType.Number:
return self.number > other.number return self.number > other.number
return false return false
#less than other #less than other
func less(other)->bool: func less(other)->bool:
if self.type == WolGlobals.ValueType.Number && other.type == WolGlobals.ValueType.Number: if self.type == Constants.ValueType.Number && other.type == Constants.ValueType.Number:
return self.number < other.number return self.number < other.number
return false return false
#greater than or equal to other #greater than or equal to other
func geq(other)->bool: func geq(other)->bool:
if self.type == WolGlobals.ValueType.Number && other.type == WolGlobals.ValueType.Number: if self.type == Constants.ValueType.Number && other.type == Constants.ValueType.Number:
return self.number > other.number || self.equals(other) return self.number > other.number || self.equals(other)
return false return false
#lesser than or equal to other #lesser than or equal to other
func leq(other)->bool: func leq(other)->bool:
if self.type == WolGlobals.ValueType.Number && other.type == WolGlobals.ValueType.Number: if self.type == Constants.ValueType.Number && other.type == Constants.ValueType.Number:
return self.number < other.number || self.equals(other) return self.number < other.number || self.equals(other)
return false return false
func _to_string(): func _to_string():
return "value(type[%s]: %s)" % [type,value()] return 'value(type[%s]: %s)' % [type,value()]

View file

@ -1,17 +1,17 @@
extends Node extends Node
var WolGlobals = load("res://addons/Wol/autoloads/execution_states.gd") const Constants = preload('res://addons/Wol/core/constants.gd')
var FunctionInfo = load("res://addons/Wol/core/function_info.gd") var FunctionInfo = load('res://addons/Wol/core/function_info.gd')
var Value = load("res://addons/Wol/core/value.gd") var Value = load('res://addons/Wol/core/value.gd')
var WolProgram = load("res://addons/Wol/core/program/program.gd") var WolProgram = load('res://addons/Wol/core/program/program.gd')
var WolNode = load("res://addons/Wol/core/program/wol_node.gd") var WolNode = load('res://addons/Wol/core/program/wol_node.gd')
var Instruction = load("res://addons/Wol/core/program/instruction.gd") var Instruction = load('res://addons/Wol/core/program/instruction.gd')
var Line = load("res://addons/Wol/core/dialogue/line.gd") var Line = load('res://addons/Wol/core/dialogue/line.gd')
var Command = load("res://addons/Wol/core/dialogue/command.gd") var Command = load('res://addons/Wol/core/dialogue/command.gd')
var Option = load("res://addons/Wol/core/dialogue/option.gd") var Option = load('res://addons/Wol/core/dialogue/option.gd')
const EXECUTION_COMPLETE : String = "execution_complete_command" const EXECUTION_COMPLETE : String = 'execution_complete_command'
var NULL_VALUE = Value.new(null) var NULL_VALUE = Value.new(null)
@ -29,7 +29,7 @@ var _state
var _currentNode var _currentNode
var executionState = WolGlobals.ExecutionState.Stopped var executionState = Constants.ExecutionState.Stopped
var string_table = {} var string_table = {}
@ -45,16 +45,16 @@ func set_program(program):
#of that name found #of that name found
func set_node(name:String) -> bool: func set_node(name:String) -> bool:
if _program == null || _program.nodes.size() == 0: if _program == null || _program.nodes.size() == 0:
printerr("Could not load %s : no nodes loaded" % name) printerr('Could not load %s : no nodes loaded' % name)
return false return false
if !_program.nodes.has(name): if !_program.nodes.has(name):
executionState = WolGlobals.ExecutionState.Stopped executionState = Constants.ExecutionState.Stopped
reset() reset()
printerr("No node named %s has been loaded" % name) printerr('No node named %s has been loaded' % name)
return false return false
_dialogue.dlog("Running node %s" % name) _dialogue.dlog('Running node %s' % name)
_currentNode = _program.nodes[name] _currentNode = _program.nodes[name]
reset() reset()
@ -70,11 +70,11 @@ func current_node():
return _currentNode return _currentNode
func pause(): func pause():
executionState = WolGlobals.ExecutionState.Suspended executionState = Constants.ExecutionState.Suspended
#stop exectuion #stop exectuion
func stop(): func stop():
executionState = WolGlobals.ExecutionState.Stopped executionState = Constants.ExecutionState.Stopped
reset() reset()
_currentNode = null _currentNode = null
@ -82,12 +82,12 @@ func stop():
#resume execution if waiting for result #resume execution if waiting for result
#return false if error #return false if error
func set_selected_option(id): func set_selected_option(id):
if executionState != WolGlobals.ExecutionState.WaitingForOption: if executionState != Constants.ExecutionState.WaitingForOption:
printerr("Unable to select option when dialogue not waiting for option") printerr('Unable to select option when dialogue not waiting for option')
return false return false
if id < 0 || id >= _state.currentOptions.size(): if id < 0 || id >= _state.currentOptions.size():
printerr("%d is not a valid option "%id) printerr('%d is not a valid option '%id)
return false return false
var destination = _state.currentOptions[id].value var destination = _state.currentOptions[id].value
@ -95,7 +95,7 @@ func set_selected_option(id):
_state.currentOptions.clear() _state.currentOptions.clear()
#no longer waiting for option #no longer waiting for option
executionState = WolGlobals.ExecutionState.Suspended executionState = Constants.ExecutionState.Suspended
return true return true
@ -108,35 +108,35 @@ func reset():
#continue execution #continue execution
func resume()->bool: func resume()->bool:
if _currentNode == null : if _currentNode == null :
printerr("Cannot run dialogue with no node selected") printerr('Cannot run dialogue with no node selected')
return false return false
if executionState == WolGlobals.ExecutionState.WaitingForOption: if executionState == Constants.ExecutionState.WaitingForOption:
printerr("Cannot run while waiting for option") printerr('Cannot run while waiting for option')
return false return false
if lineHandler == null : if lineHandler == null :
printerr("Cannot run without a lineHandler") printerr('Cannot run without a lineHandler')
return false return false
if optionsHandler == null : if optionsHandler == null :
printerr("Cannot run without an optionsHandler") printerr('Cannot run without an optionsHandler')
return false return false
if commandHandler == null : if commandHandler == null :
printerr("Cannot run without an commandHandler") printerr('Cannot run without an commandHandler')
return false return false
if nodeStartHandler == null : if nodeStartHandler == null :
printerr("Cannot run without a nodeStartHandler") printerr('Cannot run without a nodeStartHandler')
return false return false
if nodeCompleteHandler == null : if nodeCompleteHandler == null :
printerr("Cannot run without an nodeCompleteHandler") printerr('Cannot run without an nodeCompleteHandler')
return false return false
executionState = WolGlobals.ExecutionState.Running executionState = Constants.ExecutionState.Running
#execute instruction until something cool happens #execute instruction until something cool happens
while executionState == WolGlobals.ExecutionState.Running: while executionState == Constants.ExecutionState.Running:
var currentInstruction = _currentNode.instructions[_state.programCounter] var currentInstruction = _currentNode.instructions[_state.programCounter]
run_instruction(currentInstruction) run_instruction(currentInstruction)
@ -144,29 +144,29 @@ func resume()->bool:
if _state.programCounter >= _currentNode.instructions.size(): if _state.programCounter >= _currentNode.instructions.size():
nodeCompleteHandler.call_func(_currentNode.nodeName) nodeCompleteHandler.call_func(_currentNode.nodeName)
executionState = WolGlobals.ExecutionState.Stopped executionState = Constants.ExecutionState.Stopped
reset() reset()
dialogueCompleteHandler.call_func() dialogueCompleteHandler.call_func()
_dialogue.dlog("Run Complete") _dialogue.dlog('Run Complete')
return true return true
func find_label_instruction(label:String)->int: func find_label_instruction(label:String)->int:
if !_currentNode.labels.has(label): if !_currentNode.labels.has(label):
printerr("Unknown label:"+label) printerr('Unknown label:'+label)
return -1 return -1
return _currentNode.labels[label] return _currentNode.labels[label]
func run_instruction(instruction)->bool: func run_instruction(instruction)->bool:
match instruction.operation: match instruction.operation:
WolGlobals.ByteCode.Label: Constants.ByteCode.Label:
pass pass
WolGlobals.ByteCode.JumpTo: Constants.ByteCode.JumpTo:
#jump to named label #jump to named label
_state .programCounter = find_label_instruction(instruction.operands[0].value)-1 _state .programCounter = find_label_instruction(instruction.operands[0].value)-1
WolGlobals.ByteCode.RunLine: Constants.ByteCode.RunLine:
#look up string from string table #look up string from string table
#pass it to client as line #pass it to client as line
var key = instruction.operands[0].value var key = instruction.operands[0].value
@ -181,10 +181,10 @@ func run_instruction(instruction)->bool:
var pause : int = lineHandler.call_func(line) var pause : int = lineHandler.call_func(line)
if pause == WolGlobals.HandlerState.PauseExecution: if pause == Constants.HandlerState.PauseExecution:
executionState = WolGlobals.ExecutionState.Suspended executionState = Constants.ExecutionState.Suspended
WolGlobals.ByteCode.RunCommand: Constants.ByteCode.RunCommand:
var commandText : String = instruction.operands[0].value var commandText : String = instruction.operands[0].value
if instruction.operands.size() > 1: if instruction.operands.size() > 1:
@ -193,40 +193,40 @@ func run_instruction(instruction)->bool:
var command = Command.new(commandText) var command = Command.new(commandText)
var pause = commandHandler.call_func(command) as int var pause = commandHandler.call_func(command) as int
if pause == WolGlobals.HandlerState.PauseExecution: if pause == Constants.HandlerState.PauseExecution:
executionState = WolGlobals.ExecutionState.Suspended executionState = Constants.ExecutionState.Suspended
WolGlobals.ByteCode.PushString: Constants.ByteCode.PushString:
#push String var to stack #push String var to stack
_state.push_value(instruction.operands[0].value) _state.push_value(instruction.operands[0].value)
WolGlobals.ByteCode.PushNumber: Constants.ByteCode.PushNumber:
#push number to stack #push number to stack
_state.push_value(instruction.operands[0].value) _state.push_value(instruction.operands[0].value)
WolGlobals.ByteCode.PushBool: Constants.ByteCode.PushBool:
#push boolean to stack #push boolean to stack
_state.push_value(instruction.operands[0].value) _state.push_value(instruction.operands[0].value)
WolGlobals.ByteCode.PushNull: Constants.ByteCode.PushNull:
#push null t #push null t
_state.push_value(NULL_VALUE) _state.push_value(NULL_VALUE)
WolGlobals.ByteCode.JumpIfFalse: Constants.ByteCode.JumpIfFalse:
#jump to named label if value of stack top is false #jump to named label if value of stack top is false
if !_state.peek_value().as_bool(): if !_state.peek_value().as_bool():
_state.programCounter = find_label_instruction(instruction.operands[0].value)-1 _state.programCounter = find_label_instruction(instruction.operands[0].value)-1
WolGlobals.ByteCode.Jump: Constants.ByteCode.Jump:
#jump to label whose name is on the stack #jump to label whose name is on the stack
var dest : String = _state.peek_value().as_string() var dest : String = _state.peek_value().as_string()
_state.programCounter = find_label_instruction(dest)-1 _state.programCounter = find_label_instruction(dest)-1
WolGlobals.ByteCode.Pop: Constants.ByteCode.Pop:
#pop value from stack #pop value from stack
_state.pop_value() _state.pop_value()
WolGlobals.ByteCode.CallFunc: Constants.ByteCode.CallFunc:
#call function with params on stack #call function with params on stack
#push any return value to stack #push any return value to stack
var functionName : String = instruction.operands[0].value var functionName : String = instruction.operands[0].value
@ -243,7 +243,7 @@ func run_instruction(instruction)->bool:
expectedParamCount = actualParamCount expectedParamCount = actualParamCount
if expectedParamCount != actualParamCount: if expectedParamCount != actualParamCount:
printerr("Function %s expected %d parameters but got %d instead" %[functionName, printerr('Function %s expected %d parameters but got %d instead' %[functionName,
expectedParamCount,actualParamCount]) expectedParamCount,actualParamCount])
return false return false
@ -261,26 +261,26 @@ func run_instruction(instruction)->bool:
if function.returnsValue: if function.returnsValue:
_state.push_value(result) _state.push_value(result)
WolGlobals.ByteCode.PushVariable: Constants.ByteCode.PushVariable:
#get content of variable and push to stack #get content of variable and push to stack
var name : String = instruction.operands[0].value var name : String = instruction.operands[0].value
var loaded = _dialogue._variableStorage.get_value(name) var loaded = _dialogue._variableStorage.get_value(name)
_state.push_value(loaded) _state.push_value(loaded)
WolGlobals.ByteCode.StoreVariable: Constants.ByteCode.StoreVariable:
#store top stack value to variable #store top stack value to variable
var top = _state.peek_value() var top = _state.peek_value()
var destination : String = instruction.operands[0].value var destination : String = instruction.operands[0].value
_dialogue._variableStorage.set_value(destination,top) _dialogue._variableStorage.set_value(destination,top)
WolGlobals.ByteCode.Stop: Constants.ByteCode.Stop:
#stop execution and repost it #stop execution and repost it
nodeCompleteHandler.call_func(_currentNode.nodeName) nodeCompleteHandler.call_func(_currentNode.nodeName)
dialogueCompleteHandler.call_func() dialogueCompleteHandler.call_func()
executionState = WolGlobals.ExecutionState.Stopped executionState = Constants.ExecutionState.Stopped
reset() reset()
WolGlobals.ByteCode.RunNode: Constants.ByteCode.RunNode:
#run a node #run a node
var name : String var name : String
@ -293,10 +293,10 @@ func run_instruction(instruction)->bool:
var pause = nodeCompleteHandler.call_func(_currentNode.nodeName) var pause = nodeCompleteHandler.call_func(_currentNode.nodeName)
set_node(name) set_node(name)
_state.programCounter-=1 _state.programCounter-=1
if pause == WolGlobals.HandlerState.PauseExecution: if pause == Constants.HandlerState.PauseExecution:
executionState = WolGlobals.ExecutionState.Suspended executionState = Constants.ExecutionState.Suspended
WolGlobals.ByteCode.AddOption: Constants.ByteCode.AddOption:
# add an option to current state # add an option to current state
var key = instruction.operands[0].value var key = instruction.operands[0].value
@ -308,10 +308,10 @@ func run_instruction(instruction)->bool:
# line to show and node name # line to show and node name
_state.currentOptions.append(SimpleEntry.new(line,instruction.operands[1].value)) _state.currentOptions.append(SimpleEntry.new(line,instruction.operands[1].value))
WolGlobals.ByteCode.ShowOptions: Constants.ByteCode.ShowOptions:
#show options - stop if none #show options - stop if none
if _state.currentOptions.size() == 0: if _state.currentOptions.size() == 0:
executionState = WolGlobals.ExecutionState.Stopped executionState = Constants.ExecutionState.Stopped
reset() reset()
dialogueCompleteHandler.call_func() dialogueCompleteHandler.call_func()
return false return false
@ -323,7 +323,7 @@ func run_instruction(instruction)->bool:
choices.append(Option.new(option.key, optionIndex, option.value)) choices.append(Option.new(option.key, optionIndex, option.value))
#we cant continue until option chosen #we cant continue until option chosen
executionState = WolGlobals.ExecutionState.WaitingForOption executionState = Constants.ExecutionState.WaitingForOption
#pass the options to the client #pass the options to the client
#delegate for them to call #delegate for them to call
@ -332,15 +332,15 @@ func run_instruction(instruction)->bool:
optionsHandler.call_func(choices) optionsHandler.call_func(choices)
_: _:
#bytecode messed up woopsise #bytecode messed up woopsise
executionState = WolGlobals.ExecutionState.Stopped executionState = Constants.ExecutionState.Stopped
reset() reset()
printerr("Unknown Bytecode %s "%instruction.operation) printerr('Unknown Bytecode %s '%instruction.operation)
return false return false
return true return true
class VmState: class VmState:
var Value = load("res://addons/Wol/core/value.gd") var Value = load('res://addons/Wol/core/value.gd')
var currentNodeName : String var currentNodeName : String
var programCounter : int = 0 var programCounter : int = 0

View file

@ -2,11 +2,6 @@ tool
extends EditorPlugin extends EditorPlugin
func _enter_tree(): func _enter_tree():
add_autoload_singleton(
'WolGlobals',
'res://addons/Wol/autoloads/execution_states.gd'
)
add_custom_type( add_custom_type(
'Wol', 'Wol',
'Node', 'Node',
@ -16,5 +11,4 @@ func _enter_tree():
func _exit_tree(): func _exit_tree():
remove_autoload_singleton('WolGlobals')
remove_custom_type('Wol') remove_custom_type('Wol')

View file

@ -37,7 +37,7 @@ config/icon="res://icon.png"
[autoload] [autoload]
WolGlobals="*res://addons/Wol/autoloads/execution_states.gd" WolGlobals="*res://addons/Wol/core/constants.gd"
[editor_plugins] [editor_plugins]