removed the use of globals
This commit is contained in:
parent
14f37f90c8
commit
6c565b0865
|
@ -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)
|
||||||
|
|
|
@ -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(''))
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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')])
|
||||||
|
|
|
@ -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',
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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()]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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')
|
||||||
|
|
|
@ -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]
|
||||||
|
|
||||||
|
|
Reference in a new issue