went through all warnings and corrected them
This commit is contained in:
parent
cda5fe8406
commit
7822c7e6b0
|
@ -3,10 +3,15 @@ extends Node
|
|||
class_name Wol
|
||||
|
||||
signal node_started(node)
|
||||
signal node_finished(node)
|
||||
|
||||
# NOTE: Warning is ignored because they get call_deferred
|
||||
# warning-ignore:unused_signal
|
||||
signal line(line)
|
||||
# warning-ignore:unused_signal
|
||||
signal options(options)
|
||||
# warning-ignore:unused_signal
|
||||
signal command(command)
|
||||
signal node_completed(node)
|
||||
|
||||
signal started
|
||||
signal finished
|
||||
|
@ -62,14 +67,12 @@ func init_dialogue():
|
|||
dialogue.set_program(program)
|
||||
|
||||
func set_path(_path):
|
||||
if not Engine.editor_hint:
|
||||
var file = File.new()
|
||||
file.open(_path, File.READ)
|
||||
var source = file.get_as_text()
|
||||
file.close()
|
||||
program = WolCompiler.compile_string(source, _path)
|
||||
path = _path
|
||||
|
||||
if not Engine.editor_hint:
|
||||
var compiler = WolCompiler.new(path)
|
||||
program = compiler.compile()
|
||||
|
||||
func _handle_line(line):
|
||||
call_deferred('emit_signal', 'line', line)
|
||||
if auto_show_options \
|
||||
|
@ -103,7 +106,7 @@ func _handle_node_start(node):
|
|||
dialogue._visitedNodeCount[node] += 1
|
||||
|
||||
func _handle_node_complete(node):
|
||||
emit_signal('node_completed', node)
|
||||
emit_signal('node_finished', node)
|
||||
return Constants.HandlerState.ContinueExecution
|
||||
|
||||
func select_option(id):
|
||||
|
|
|
@ -4,158 +4,152 @@ class_name Compiler
|
|||
const Constants = preload('res://addons/Wol/core/constants.gd')
|
||||
const Lexer = preload('res://addons/Wol/core/compiler/lexer.gd')
|
||||
const Program = preload('res://addons/Wol/core/program.gd')
|
||||
const Parser = preload('res://addons/Wol/core/compiler/parser.gd')
|
||||
|
||||
#patterns
|
||||
const INVALIDTITLENAME = '[\\[<>\\]{}\\|:\\s#\\$]'
|
||||
const INVALID_TITLE = '[\\[<>\\]{}\\|:\\s#\\$]'
|
||||
|
||||
#ERROR Codes
|
||||
const NO_ERROR = 0x00
|
||||
const LEXER_FAILURE = 0x01
|
||||
const PARSER_FAILURE = 0x02
|
||||
const INVALID_HEADER = 0x04
|
||||
const DUPLICATE_NODES_IN_PROGRAM = 0x08
|
||||
const ERR_COMPILATION_FAILED = 0x10
|
||||
|
||||
var _errors : int
|
||||
var _last_error : int
|
||||
var source = ''
|
||||
var filename = ''
|
||||
|
||||
#-----Class vars
|
||||
var _current_node : Program.WolNode
|
||||
var _raw_text : bool
|
||||
var _file_name : String
|
||||
var _contains_implicit_string_tags : bool
|
||||
var _label_count : int = 0
|
||||
var _current_node
|
||||
var _contains_implicit_string_tags = false
|
||||
var _label_count = 0
|
||||
|
||||
#<String, Program.Line>
|
||||
var _string_table : Dictionary = {}
|
||||
var _string_count : int = 0
|
||||
#<int, Constants.TokenType>
|
||||
var _tokens : Dictionary = {}
|
||||
var _string_table = {}
|
||||
var _string_count = 0
|
||||
|
||||
static func compile_string(source: String, filename: String):
|
||||
var Parser = load('res://addons/Wol/core/compiler/parser.gd')
|
||||
var Compiler = load('res://addons/Wol/core/compiler/compiler.gd')
|
||||
func _init(_filename, _source = null):
|
||||
filename = _filename
|
||||
|
||||
var compiler = Compiler.new()
|
||||
compiler._file_name = filename
|
||||
if not _filename and _source:
|
||||
self.source = _source
|
||||
else:
|
||||
var file = File.new()
|
||||
file.open(_filename, File.READ)
|
||||
self.source = file.get_as_text()
|
||||
file.close()
|
||||
|
||||
#--------------Nodes
|
||||
var header_sep : RegEx = RegEx.new()
|
||||
func compile():
|
||||
var header_sep = RegEx.new()
|
||||
var header_property = RegEx.new()
|
||||
header_sep.compile('---(\r\n|\r|\n)')
|
||||
var header_property : RegEx = RegEx.new()
|
||||
header_property.compile('(?<field>.*): *(?<value>.*)')
|
||||
|
||||
assert(not not header_sep.search(source), 'No headers found')
|
||||
assert(header_sep.search(source), 'No headers found!')
|
||||
|
||||
var line_number: int = 0
|
||||
|
||||
var source_lines : Array = source.split('\n',false)
|
||||
for i in range(source_lines.size()):
|
||||
source_lines[i] = source_lines[i].strip_edges(false,true)
|
||||
var line_number = 0
|
||||
|
||||
var parsed_nodes : Array = []
|
||||
var source_lines = source.split('\n', false)
|
||||
for i in range(source_lines.size()):
|
||||
source_lines[i] = source_lines[i].strip_edges(false, true)
|
||||
|
||||
var parsed_nodes = []
|
||||
|
||||
while line_number < source_lines.size():
|
||||
|
||||
var title : String
|
||||
var body : String
|
||||
var title = ''
|
||||
var body = ''
|
||||
|
||||
#get title
|
||||
# Parse header
|
||||
while true:
|
||||
var line : String = source_lines[line_number]
|
||||
line_number+=1
|
||||
var line = source_lines[line_number]
|
||||
line_number += 1
|
||||
|
||||
if !line.empty():
|
||||
if not line.empty():
|
||||
var result = header_property.search(line)
|
||||
if result != null :
|
||||
var field : String = result.get_string('field')
|
||||
var value : String = result.get_string('value')
|
||||
if result != null:
|
||||
var field = result.get_string('field')
|
||||
var value = result.get_string('value')
|
||||
|
||||
if field == 'title':
|
||||
assert(not ' ' in value, 'No space allowed in title "%s", correct to "%s"' % [value, value.replace(' ','')])
|
||||
title = value
|
||||
var regex = RegEx.new()
|
||||
regex.compile(INVALID_TITLE)
|
||||
assert(not regex.search(value), 'Invalid characters in title "%s", correct to "%s"' % [value, regex.sub(value, '', true)])
|
||||
|
||||
if(line_number >= source_lines.size() || source_lines[line_number] == '---'):
|
||||
title = value
|
||||
# TODO: Implement position, color and tags
|
||||
|
||||
if line_number >= source_lines.size() or line == '---':
|
||||
break
|
||||
|
||||
|
||||
line_number+=1
|
||||
line_number += 1
|
||||
|
||||
#past header
|
||||
var body_lines : PoolStringArray = []
|
||||
# past header
|
||||
var body_lines = []
|
||||
|
||||
while line_number < source_lines.size() and source_lines[line_number]!='===':
|
||||
while line_number < source_lines.size() and source_lines[line_number] != '===':
|
||||
body_lines.append(source_lines[line_number])
|
||||
line_number+=1
|
||||
line_number += 1
|
||||
|
||||
line_number+=1
|
||||
line_number += 1
|
||||
|
||||
body = body_lines.join('\n')
|
||||
var lexer = Lexer.new()
|
||||
var tokens = lexer.tokenize(body, title, filename)
|
||||
body = PoolStringArray(body_lines).join('\n')
|
||||
|
||||
var parser = Parser.new(tokens, title)
|
||||
var lexer = Lexer.new(filename, title, body)
|
||||
var tokens = lexer.tokenize()
|
||||
|
||||
var parser = Parser.new(title, tokens)
|
||||
var parser_node = parser.parse_node()
|
||||
|
||||
parser_node.name = title
|
||||
# parser_node.tags = title
|
||||
parsed_nodes.append(parser_node)
|
||||
while line_number < source_lines.size() && source_lines[line_number].empty():
|
||||
line_number+=1
|
||||
|
||||
#--- End parsing nodes---
|
||||
while line_number < source_lines.size() and source_lines[line_number].empty():
|
||||
line_number += 1
|
||||
|
||||
var program = Program.new()
|
||||
|
||||
#compile nodes
|
||||
for node in parsed_nodes:
|
||||
compiler.compile_node(program, node)
|
||||
compile_node(program, node)
|
||||
|
||||
for key in compiler._string_table:
|
||||
program.strings[key] = compiler._string_table[key]
|
||||
for key in _string_table:
|
||||
program.strings[key] = _string_table[key]
|
||||
|
||||
return program
|
||||
|
||||
func compile_node(program, parsed_node):
|
||||
if program.nodes.has(parsed_node.name):
|
||||
emit_error(DUPLICATE_NODES_IN_PROGRAM)
|
||||
printerr('Duplicate node in program: %s' % parsed_node.name)
|
||||
assert(not program.nodes.has(parsed_node.name), 'Duplicate node in program: %s' % parsed_node.name)
|
||||
|
||||
var node_compiled = Program.WolNode.new()
|
||||
|
||||
node_compiled.name = parsed_node.name
|
||||
node_compiled.tags = parsed_node.tags
|
||||
|
||||
if parsed_node.source != null and not parsed_node.source.empty():
|
||||
node_compiled.source_id = register_string(
|
||||
parsed_node.source,
|
||||
parsed_node.name,
|
||||
'line:' + parsed_node.name,
|
||||
0,
|
||||
[]
|
||||
)
|
||||
else:
|
||||
var node_compiled = Program.WolNode.new()
|
||||
var start_label = register_label()
|
||||
emit(Constants.ByteCode.Label,node_compiled,[Program.Operand.new(start_label)])
|
||||
|
||||
node_compiled.name = parsed_node.name
|
||||
node_compiled.tags = parsed_node.tags
|
||||
for statement in parsed_node.statements:
|
||||
generate_statement(node_compiled, statement)
|
||||
|
||||
var dangling_options = false
|
||||
for instruction in node_compiled.instructions:
|
||||
if instruction.operation == Constants.ByteCode.AddOption:
|
||||
dangling_options = true
|
||||
if instruction.operation == Constants.ByteCode.ShowOptions:
|
||||
dangling_options = false
|
||||
|
||||
#raw text
|
||||
if parsed_node.source != null && !parsed_node.source.empty():
|
||||
node_compiled.source_id = register_string(parsed_node.source,parsed_node.name,
|
||||
'line:'+parsed_node.name, 0, [])
|
||||
if dangling_options:
|
||||
emit(Constants.ByteCode.ShowOptions, node_compiled)
|
||||
emit(Constants.ByteCode.RunNode, node_compiled)
|
||||
else:
|
||||
#compile node
|
||||
var start_label : String = register_label()
|
||||
emit(Constants.ByteCode.Label,node_compiled,[Program.Operand.new(start_label)])
|
||||
emit(Constants.ByteCode.Stop, node_compiled)
|
||||
|
||||
for statement in parsed_node.statements:
|
||||
generate_statement(node_compiled,statement)
|
||||
|
||||
|
||||
#add options
|
||||
#todo: add parser flag
|
||||
|
||||
var dangling_options = false
|
||||
for instruction in node_compiled.instructions :
|
||||
if instruction.operation == Constants.ByteCode.AddOption:
|
||||
dangling_options = true
|
||||
if instruction.operation == Constants.ByteCode.ShowOptions:
|
||||
dangling_options = false
|
||||
|
||||
if dangling_options:
|
||||
emit(Constants.ByteCode.ShowOptions, node_compiled)
|
||||
emit(Constants.ByteCode.RunNode, node_compiled)
|
||||
else:
|
||||
emit(Constants.ByteCode.Stop, node_compiled)
|
||||
|
||||
|
||||
program.nodes[node_compiled.name] = node_compiled
|
||||
program.nodes[node_compiled.name] = node_compiled
|
||||
|
||||
func register_string(text:String,node_name:String,id:String='',line_number:int=-1,tags:Array=[])->String:
|
||||
var line_id_used : String
|
||||
|
@ -163,7 +157,7 @@ func register_string(text:String,node_name:String,id:String='',line_number:int=-
|
|||
var implicit : bool
|
||||
|
||||
if id.empty():
|
||||
line_id_used = '%s-%s-%d' % [self._file_name,node_name,self._string_count]
|
||||
line_id_used = '%s-%s-%d' % [self.filename,node_name,self._string_count]
|
||||
self._string_count+=1
|
||||
|
||||
#use this when we generate implicit tags
|
||||
|
@ -176,7 +170,7 @@ func register_string(text:String,node_name:String,id:String='',line_number:int=-
|
|||
line_id_used = id
|
||||
implicit = false
|
||||
|
||||
var string_info = Program.Line.new(text,node_name,line_number,_file_name,implicit,tags)
|
||||
var string_info = Program.Line.new(text,node_name,line_number,filename,implicit,tags)
|
||||
#add to string table and return id
|
||||
self._string_table[line_id_used] = string_info
|
||||
|
||||
|
@ -202,18 +196,11 @@ func emit(bytecode, node = _current_node, operands = []):
|
|||
node.labels[instruction.operands[0].value] = node.instructions.size()-1
|
||||
|
||||
|
||||
func get_string_tokens()->Array:
|
||||
return []
|
||||
|
||||
#compile header
|
||||
func generate_header():
|
||||
pass
|
||||
|
||||
#compile instructions for statements
|
||||
#this will walk through all child branches
|
||||
#of the parse tree
|
||||
func generate_statement(node,statement):
|
||||
# print('generating statement')
|
||||
|
||||
match statement.type:
|
||||
Constants.StatementTypes.CustomCommand:
|
||||
generate_custom_command(node,statement.custom_command)
|
||||
|
@ -230,8 +217,7 @@ func generate_statement(node,statement):
|
|||
Constants.StatementTypes.Line:
|
||||
generate_line(node,statement,statement.line)
|
||||
_:
|
||||
emit_error(ERR_COMPILATION_FAILED)
|
||||
printerr('illegal statement type [%s]- could not generate code' % statement.type)
|
||||
assert(false, 'Illegal statement type [%s]. Could not generate code.' % statement.type)
|
||||
|
||||
#compile instructions for custom commands
|
||||
func generate_custom_command(node,command):
|
||||
|
@ -306,7 +292,6 @@ func generate_shortcut_group(node,shortcut_group):
|
|||
emit(Constants.ByteCode.Pop,node)
|
||||
|
||||
|
||||
|
||||
#compile instructions for block
|
||||
#blocks are just groups of statements
|
||||
func generate_block(node,statements:Array=[]):
|
||||
|
@ -347,7 +332,7 @@ func generate_option(node,option):
|
|||
# print('generating option')
|
||||
var destination : String = option.destination
|
||||
|
||||
if option.label == null || option.label.empty():
|
||||
if option.label == null or option.label.empty():
|
||||
#jump to another node
|
||||
emit(Constants.ByteCode.RunNode,node,[Program.Operand.new(destination)])
|
||||
else :
|
||||
|
@ -401,7 +386,7 @@ func generate_assignment(node,assignment):
|
|||
#compile expression instructions
|
||||
func generate_expression(node,expression):
|
||||
# print('generating expression')
|
||||
#expression = value || func call
|
||||
#expression = value or func call
|
||||
match expression.type:
|
||||
Constants.ExpressionType.Value:
|
||||
generate_value(node,expression.value)
|
||||
|
@ -438,22 +423,6 @@ func generate_value(node,value):
|
|||
_:
|
||||
printerr('Unrecognized valuenode type: %s' % value.value.type)
|
||||
|
||||
#get the error flags
|
||||
func get_errors()->int:
|
||||
return _errors
|
||||
|
||||
#get the last error code reported
|
||||
func get_last_error()->int:
|
||||
return _last_error
|
||||
|
||||
func clear_errors()->void:
|
||||
_errors = NO_ERROR
|
||||
_last_error = NO_ERROR
|
||||
|
||||
func emit_error(error : int)->void:
|
||||
_last_error = error
|
||||
_errors |= _last_error
|
||||
|
||||
static func print_tokens(tokens:Array=[]):
|
||||
var list : PoolStringArray = []
|
||||
list.append('\n')
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
extends Object
|
||||
class_name Lexer
|
||||
|
||||
const Constants = preload('res://addons/Wol/core/constants.gd')
|
||||
|
||||
|
@ -23,16 +24,22 @@ var WHITESPACE : String = '\\s*'
|
|||
|
||||
var _states : Dictionary = {}
|
||||
var _defaultState : LexerState
|
||||
|
||||
var _currentState : LexerState
|
||||
|
||||
var _indentStack : Array = []
|
||||
var _shouldTrackIndent : bool = false
|
||||
|
||||
var filename = ''
|
||||
var title = ''
|
||||
var text = ''
|
||||
|
||||
func _init():
|
||||
func _init(_filename, _title, _text):
|
||||
create_states()
|
||||
|
||||
filename = _filename
|
||||
title = _title
|
||||
text = _text
|
||||
|
||||
func create_states():
|
||||
var patterns : Dictionary = {}
|
||||
patterns[Constants.TokenType.Text] = ['.*', 'any text']
|
||||
|
@ -43,7 +50,7 @@ func create_states():
|
|||
patterns[Constants.TokenType.LeftParen] = ['\\(', 'left parenthesis (']
|
||||
patterns[Constants.TokenType.RightParen] = ['\\)', 'right parenthesis )']
|
||||
patterns[Constants.TokenType.EqualTo] = ['(==|is(?!\\w)|eq(?!\\w))', '"=", "is" or "eq"']
|
||||
patterns[Constants.TokenType.EqualToOrAssign] = ['(=|to(?!\\w))', 'equal to "=" or assign "="']
|
||||
patterns[Constants.TokenType.EqualToOrAssign] = ['(=|to(?!\\w))', '"=" or "to"']
|
||||
patterns[Constants.TokenType.NotEqualTo] = ['(\\!=|neq(?!\\w))', '"!=" or "neq"']
|
||||
patterns[Constants.TokenType.GreaterThanOrEqualTo] = ['(\\>=|gte(?!\\w))', '">=" or "gte"']
|
||||
patterns[Constants.TokenType.GreaterThan] = ['(\\>|gt(?!\\w))', '">" or "gt"']
|
||||
|
@ -81,9 +88,9 @@ func create_states():
|
|||
patterns[Constants.TokenType.ShortcutOption] = ['\\-\\>\\s*', '"->"']
|
||||
|
||||
#compound states
|
||||
var shortcut_option : String= SHORTCUT + DASH + OPTION
|
||||
var shortcut_option : String = SHORTCUT + DASH + OPTION
|
||||
var shortcut_option_tag : String = shortcut_option + DASH + TAG
|
||||
var command_or_expression : String= COMMAND + DASH + OR + DASH + EXPRESSION
|
||||
var command_or_expression : String = COMMAND + DASH + OR + DASH + EXPRESSION
|
||||
var link_destination : String = LINK + DASH + DESTINATION
|
||||
|
||||
_states = {}
|
||||
|
@ -91,7 +98,7 @@ func create_states():
|
|||
_states[BASE] = LexerState.new(patterns)
|
||||
_states[BASE].add_transition(Constants.TokenType.BeginCommand,COMMAND,true)
|
||||
_states[BASE].add_transition(Constants.TokenType.OptionStart,LINK,true)
|
||||
_states[BASE].add_transition(Constants.TokenType.ShortcutOption,shortcut_option)
|
||||
_states[BASE].add_transition(Constants.TokenType.ShortcutOption, shortcut_option)
|
||||
_states[BASE].add_transition(Constants.TokenType.TagMarker,TAG,true)
|
||||
_states[BASE].add_text_rule(Constants.TokenType.Text)
|
||||
|
||||
|
@ -112,7 +119,7 @@ func create_states():
|
|||
_states[COMMAND].add_transition(Constants.TokenType.ElseToken)
|
||||
_states[COMMAND].add_transition(Constants.TokenType.ElseIf,EXPRESSION)
|
||||
_states[COMMAND].add_transition(Constants.TokenType.EndIf)
|
||||
_states[COMMAND].add_transition(Constants.TokenType.Set,ASSIGNMENT)
|
||||
_states[COMMAND].add_transition(Constants.TokenType.Set, ASSIGNMENT)
|
||||
_states[COMMAND].add_transition(Constants.TokenType.EndCommand,BASE,true)
|
||||
_states[COMMAND].add_transition(Constants.TokenType.Identifier,command_or_expression)
|
||||
_states[COMMAND].add_text_rule(Constants.TokenType.Text)
|
||||
|
@ -173,9 +180,9 @@ func create_states():
|
|||
for stateKey in _states.keys():
|
||||
_states[stateKey].stateName = stateKey
|
||||
|
||||
func tokenize(text, title, filename):
|
||||
func tokenize():
|
||||
_indentStack.clear()
|
||||
_indentStack.push_front(IntBoolPair.new(0,false))
|
||||
_indentStack.push_front(IntBoolPair.new(0, false))
|
||||
_shouldTrackIndent = false
|
||||
|
||||
var tokens : Array = []
|
||||
|
@ -188,7 +195,7 @@ func tokenize(text, title, filename):
|
|||
var line_number : int = 1
|
||||
|
||||
for line in lines:
|
||||
tokens += tokenize_line(line, line_number, title, filename)
|
||||
tokens += tokenize_line(line, line_number)
|
||||
line_number += 1
|
||||
|
||||
var endOfInput = Token.new(
|
||||
|
@ -201,14 +208,14 @@ func tokenize(text, title, filename):
|
|||
|
||||
return tokens
|
||||
|
||||
func tokenize_line(line, line_number, title, filename):
|
||||
func tokenize_line(line, line_number):
|
||||
var tokenStack : Array = []
|
||||
|
||||
var freshLine = line.replace('\t',' ').replace('\r','')
|
||||
|
||||
#record indentation
|
||||
var indentation = line_indentation(line)
|
||||
var prevIndentation : IntBoolPair = _indentStack.front()
|
||||
var prevIndentation = _indentStack.front()
|
||||
|
||||
if _shouldTrackIndent && indentation > prevIndentation.key:
|
||||
#we add an indenation token to record indent level
|
||||
|
@ -259,7 +266,7 @@ func tokenize_line(line, line_number, title, filename):
|
|||
|
||||
var tokenText : String
|
||||
|
||||
if rule.tokenType == Constants.TokenType.Text:
|
||||
if rule.token_type == Constants.TokenType.Text:
|
||||
#if this is text then we back up to the most recent
|
||||
#delimiting token and treat everything from there as text.
|
||||
|
||||
|
@ -289,29 +296,29 @@ func tokenize_line(line, line_number, title, filename):
|
|||
column += tokenText.length()
|
||||
|
||||
#pre-proccess string
|
||||
if rule.tokenType == Constants.TokenType.Str:
|
||||
if rule.token_type == Constants.TokenType.Str:
|
||||
tokenText = tokenText.substr(1, tokenText.length() - 2)
|
||||
tokenText = tokenText.replace('\\\\', '\\')
|
||||
tokenText = tokenText.replace('\\\'','\'')
|
||||
|
||||
var token = Token.new(
|
||||
rule.tokenType,
|
||||
rule.token_type,
|
||||
_currentState,
|
||||
filename,
|
||||
line_number,
|
||||
column,
|
||||
tokenText
|
||||
)
|
||||
token.delimitsText = rule.delimitsText
|
||||
token.delimits_text = rule.delimits_text
|
||||
|
||||
tokenStack.push_front(token)
|
||||
|
||||
if rule.enterState != null and rule.enterState.length() > 0:
|
||||
if not _states.has(rule.enterState):
|
||||
printerr('State[%s] not known - line(%s) col(%s)' % [rule.enterState, line_number, column])
|
||||
if rule.enter_state != null and rule.enter_state.length() > 0:
|
||||
if not _states.has(rule.enter_state):
|
||||
printerr('State[%s] not known - line(%s) col(%s)' % [rule.enter_state, line_number, column])
|
||||
return []
|
||||
|
||||
enter_state(_states[rule.enterState])
|
||||
enter_state(_states[rule.enter_state])
|
||||
|
||||
if _shouldTrackIndent:
|
||||
if _indentStack.front().key < indentation:
|
||||
|
@ -323,7 +330,7 @@ func tokenize_line(line, line_number, title, filename):
|
|||
if not matched:
|
||||
var rules = []
|
||||
for rule in _currentState.rules:
|
||||
rules.append('"%s" (%s)' % [Constants.token_type_name(rule.tokenType), rule.human_readable_identifier])
|
||||
rules.append('"%s" (%s)' % [Constants.token_type_name(rule.token_type), rule.human_readable_identifier])
|
||||
|
||||
var error_data = [
|
||||
PoolStringArray(rules).join(', ') if rules.size() == 1 else PoolStringArray(rules.slice(0, rules.size() - 2)).join(', ') + ' or %s' % rules[-1],
|
||||
|
@ -368,17 +375,17 @@ class Token:
|
|||
var column = -1
|
||||
var text = ''
|
||||
|
||||
var delimitsText = false
|
||||
var delimits_text = false
|
||||
var paramCount = -1
|
||||
var lexerState = ''
|
||||
|
||||
func _init(type, state, filename, line_number = -1, column = -1, value = ''):
|
||||
self.type = type
|
||||
self.lexerState = state.stateName
|
||||
self.filename = filename
|
||||
self.line_number = line_number
|
||||
self.column = column
|
||||
self.value = value
|
||||
func _init(_type, _state, _filename, _line_number = -1, _column = -1, _value = ''):
|
||||
type = _type
|
||||
lexerState = _state.stateName
|
||||
filename = _filename
|
||||
line_number = _line_number
|
||||
column = _column
|
||||
value = _value
|
||||
|
||||
func _to_string():
|
||||
return '%s (%s) at %s:%s (state: %s)' % [Constants.token_type_name(type),value,line_number,column,lexerState]
|
||||
|
@ -390,8 +397,8 @@ class LexerState:
|
|||
var rules : Array = []
|
||||
var track_indent : bool = false
|
||||
|
||||
func _init(patterns):
|
||||
self.patterns = patterns
|
||||
func _init(_patterns):
|
||||
patterns = _patterns
|
||||
|
||||
func add_transition(type : int, state : String = '',delimitText : bool = false)->Rule:
|
||||
var pattern = '\\G%s' % patterns[type][0]
|
||||
|
@ -407,48 +414,49 @@ class LexerState:
|
|||
|
||||
var delimiters:Array = []
|
||||
for rule in rules:
|
||||
if rule.delimitsText:
|
||||
if rule.delimits_text:
|
||||
delimiters.append('%s' % rule.regex.get_pattern().substr(2))
|
||||
|
||||
var pattern = '\\G((?!%s).)*' % [PoolStringArray(delimiters).join('|')]
|
||||
var rule : Rule = add_transition(type,state)
|
||||
rule.regex = RegEx.new()
|
||||
rule.regex.compile(pattern)
|
||||
rule.isTextRule = true
|
||||
rule.is_text_rule = true
|
||||
return rule
|
||||
|
||||
func contains_text_rule()->bool:
|
||||
for rule in rules:
|
||||
if rule.isTextRule:
|
||||
if rule.is_text_rule:
|
||||
return true
|
||||
return false
|
||||
|
||||
|
||||
class Rule:
|
||||
var regex : RegEx
|
||||
|
||||
var enterState : String
|
||||
var tokenType : int
|
||||
var isTextRule : bool
|
||||
var delimitsText : bool
|
||||
var enter_state : String
|
||||
var token_type : int
|
||||
var is_text_rule : bool
|
||||
var delimits_text : bool
|
||||
var human_readable_identifier = ''
|
||||
|
||||
func _init(type : int , regex : String, human_readable_identifier, enterState : String, delimitsText:bool):
|
||||
self.tokenType = type
|
||||
self.regex = RegEx.new()
|
||||
self.regex.compile(regex)
|
||||
self.human_readable_identifier = human_readable_identifier
|
||||
self.enterState = enterState
|
||||
self.delimitsText = delimitsText
|
||||
func _init(_type, _regex, _human_readable_identifier, _enter_state, _delimits_text):
|
||||
token_type = _type
|
||||
|
||||
regex = RegEx.new()
|
||||
regex.compile(_regex)
|
||||
|
||||
human_readable_identifier = _human_readable_identifier
|
||||
enter_state = _enter_state
|
||||
delimits_text = _delimits_text
|
||||
|
||||
func _to_string():
|
||||
return '[Rule : %s (%s) - %s]' % [Constants.token_type_name(tokenType), human_readable_identifier, regex]
|
||||
return '[Rule : %s (%s) - %s]' % [Constants.token_type_name(token_type), human_readable_identifier, regex]
|
||||
|
||||
class IntBoolPair:
|
||||
var key : int
|
||||
var value : bool
|
||||
var key = -1
|
||||
var value = false
|
||||
|
||||
func _init(key:int,value:bool):
|
||||
self.key = key
|
||||
self.value = value
|
||||
func _init(_key, _value):
|
||||
key = _key
|
||||
value = _value
|
||||
|
||||
|
|
|
@ -3,12 +3,12 @@ extends Object
|
|||
const Constants = preload('res://addons/Wol/core/constants.gd')
|
||||
const Lexer = preload('res://addons/Wol/core/compiler/lexer.gd')
|
||||
|
||||
var _tokens = []
|
||||
var tokens = []
|
||||
var title = ''
|
||||
|
||||
func _init(tokens, title):
|
||||
self._tokens = tokens
|
||||
self.title = title
|
||||
func _init(_title, _tokens):
|
||||
title = _title
|
||||
tokens = _tokens
|
||||
|
||||
enum Associativity {
|
||||
Left,
|
||||
|
@ -20,7 +20,7 @@ func parse_node():
|
|||
return WolNode.new('Start', null, self)
|
||||
|
||||
func next_symbol_is(valid_types):
|
||||
var type = self._tokens.front().type
|
||||
var type = self.tokens.front().type
|
||||
for valid_type in valid_types:
|
||||
if type == valid_type:
|
||||
return true
|
||||
|
@ -28,14 +28,14 @@ func next_symbol_is(valid_types):
|
|||
|
||||
# NOTE:0 look ahead for `<<` and `else`
|
||||
func next_symbols_are(valid_types):
|
||||
var temporary = [] + _tokens
|
||||
var temporary = [] + tokens
|
||||
for type in valid_types:
|
||||
if temporary.pop_front().type != type:
|
||||
return false
|
||||
return true
|
||||
|
||||
func expect_symbol(token_types = []):
|
||||
var token = _tokens.pop_front() as Lexer.Token
|
||||
var token = tokens.pop_front() as Lexer.Token
|
||||
|
||||
if token_types.size() == 0:
|
||||
if token.type == Constants.TokenType.EndOfInput:
|
||||
|
@ -51,7 +51,6 @@ func expect_symbol(token_types = []):
|
|||
for type in token_types:
|
||||
token_names.append(Constants.token_type_name(type))
|
||||
|
||||
|
||||
var error_guess = '\n'
|
||||
|
||||
if Constants.token_type_name(token.type) == 'Identifier' \
|
||||
|
@ -74,9 +73,6 @@ func expect_symbol(token_types = []):
|
|||
static func tab(indent_level, input, newline = true):
|
||||
return '%*s| %s%s' % [indent_level * 2, '', input, '' if not newline else '\n']
|
||||
|
||||
func tokens():
|
||||
return _tokens
|
||||
|
||||
class ParseNode:
|
||||
var name = ''
|
||||
|
||||
|
@ -84,21 +80,22 @@ class ParseNode:
|
|||
var line_number = -1
|
||||
var tags = []
|
||||
|
||||
func _init(parent, parser):
|
||||
self.parent = parent
|
||||
func _init(_parent, _parser):
|
||||
parent = _parent
|
||||
|
||||
var tokens = parser.tokens() as Array
|
||||
var tokens = _parser.tokens as Array
|
||||
if tokens.size() > 0:
|
||||
line_number = tokens.front().line_number
|
||||
else:
|
||||
line_number = -1
|
||||
|
||||
tags = []
|
||||
|
||||
func tree_string(indent_level):
|
||||
func tree_string(_indent_level):
|
||||
return 'Not_implemented'
|
||||
|
||||
func tags_to_string(indent_level):
|
||||
return '%s' % 'TAGS<tags_to_string>NOTIMPLEMENTED'
|
||||
func tags_to_string(_indent_level):
|
||||
return 'TAGS<tags_to_string>NOTIMPLEMENTED'
|
||||
|
||||
func get_node_parent():
|
||||
var node = self
|
||||
|
@ -111,10 +108,6 @@ class ParseNode:
|
|||
func tab(indent_level, input, newline = true):
|
||||
return '%*s| %s%s' % [ indent_level * 2, '', input, '' if !newline else '\n']
|
||||
|
||||
func set_parent(parent):
|
||||
self.parent = parent
|
||||
|
||||
#this is a Wol Node - contains all the text
|
||||
class WolNode extends ParseNode:
|
||||
var source = ''
|
||||
|
||||
|
@ -123,7 +116,7 @@ class WolNode extends ParseNode:
|
|||
|
||||
func _init(name, parent, parser).(parent, parser):
|
||||
self.name = name
|
||||
while parser.tokens().size() > 0 \
|
||||
while parser.tokens.size() > 0 \
|
||||
and not parser.next_symbol_is([Constants.TokenType.Dedent, Constants.TokenType.EndOfInput]):
|
||||
statements.append(Statement.new(self, parser))
|
||||
|
||||
|
@ -180,7 +173,7 @@ class Statement extends ParseNode:
|
|||
type = Type.Line
|
||||
|
||||
else:
|
||||
printerr('Expected a statement but got %s instead. (probably an imbalanced if statement)' % parser.tokens().front()._to_string())
|
||||
printerr('Expected a statement but got %s instead. (probably an imbalanced if statement)' % parser.tokens.front()._to_string())
|
||||
|
||||
var tags = []
|
||||
|
||||
|
@ -242,9 +235,8 @@ class CustomCommand extends ParseNode:
|
|||
if (command_tokens.size() > 1 && command_tokens[0].type == Constants.TokenType.Identifier
|
||||
&& command_tokens[1].type == Constants.TokenType.LeftParen):
|
||||
var p = get_script().new(command_tokens, parser.library)
|
||||
var expression = ExpressionNode.parse(self, p)
|
||||
expression = ExpressionNode.parse(self, p)
|
||||
type = Type.Expression
|
||||
self.expression = expression
|
||||
else:
|
||||
#otherwise evaluuate command
|
||||
type = Type.ClientCommand
|
||||
|
@ -548,50 +540,43 @@ class ValueNode extends ParseNode:
|
|||
func tree_string(indent_level):
|
||||
return tab(indent_level, '%s' % value.value())
|
||||
|
||||
|
||||
#Expressions encompass a wide range of things like:
|
||||
# math (1 + 2 - 5 * 3 / 10 % 2)
|
||||
# Identifiers
|
||||
# Values
|
||||
class ExpressionNode extends ParseNode:
|
||||
var type
|
||||
var value
|
||||
var function
|
||||
var params = []#ExpressionNode
|
||||
var parameters = []
|
||||
|
||||
func _init(parent, parser, value, function = '', params = []).(parent, parser):
|
||||
func _init(parent, parser, _value, _function = '', _parameters = []).(parent, parser):
|
||||
|
||||
#no function - means value
|
||||
if value != null:
|
||||
self.type = Constants.ExpressionType.Value
|
||||
self.value = value
|
||||
else:#function
|
||||
|
||||
self.type = Constants.ExpressionType.FunctionCall
|
||||
self.function = function
|
||||
self.params = params
|
||||
if _value != null:
|
||||
type = Constants.ExpressionType.Value
|
||||
value = _value
|
||||
else:
|
||||
type = Constants.ExpressionType.FunctionCall
|
||||
function = _function
|
||||
parameters = _parameters
|
||||
|
||||
func tree_string(indent_level):
|
||||
var info = []
|
||||
match type:
|
||||
Constants.ExpressionType.Value:
|
||||
return value.tree_string(indent_level)
|
||||
|
||||
Constants.ExpressionType.FunctionCall:
|
||||
info.append(tab(indent_level,'Func[%s - params(%s)]:{'%[function, params.size()]))
|
||||
for param in params:
|
||||
info.append(tab(indent_level,'Func[%s - parameters(%s)]:{'%[function, parameters.size()]))
|
||||
for param in parameters:
|
||||
info.append(param.tree_string(indent_level+1))
|
||||
info.append(tab(indent_level,'}'))
|
||||
|
||||
return info.join('')
|
||||
|
||||
#using Djikstra's shunting-yard algorithm to convert
|
||||
#stream of expresions into postfix notaion, then
|
||||
#build a tree of expressions
|
||||
# using Djikstra's shunting-yard algorithm to convert stream of expresions into postfix notation,
|
||||
# & then build a tree of expressions
|
||||
static func parse(parent, parser):
|
||||
var rpn = []
|
||||
var op_stack = []
|
||||
|
||||
#track params
|
||||
#track parameters
|
||||
var func_stack = []
|
||||
|
||||
var valid_types = [
|
||||
|
@ -612,7 +597,7 @@ class ExpressionNode extends ParseNode:
|
|||
var last
|
||||
|
||||
#read expression content
|
||||
while parser.tokens().size() > 0 && parser.next_symbol_is(valid_types):
|
||||
while parser.tokens.size() > 0 && parser.next_symbol_is(valid_types):
|
||||
var next = parser.expect_symbol(valid_types)
|
||||
|
||||
if next.type == Constants.TokenType.Variable \
|
||||
|
@ -646,7 +631,7 @@ class ExpressionNode extends ParseNode:
|
|||
# next parser token not allowed to be right paren or comma
|
||||
if parser.next_symbol_is([Constants.TokenType.RightParen,
|
||||
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
|
||||
#increment parameters
|
||||
|
@ -698,7 +683,7 @@ class ExpressionNode extends ParseNode:
|
|||
op_stack.pop_back()
|
||||
if op_stack.back().type == Constants.TokenType.Identifier:
|
||||
#function call
|
||||
#last token == left paren this == no params
|
||||
#last token == left paren this == no parameters
|
||||
#else
|
||||
#we have more than 1 param
|
||||
if last.type != Constants.TokenType.LeftParen:
|
||||
|
@ -731,36 +716,35 @@ class ExpressionNode extends ParseNode:
|
|||
if eval_stack.size() < info.arguments:
|
||||
printerr('Error parsing : Not enough arguments for %s [ got %s expected - was %s]'%[Constants.token_type_name(next.type), eval_stack.size(), info.arguments])
|
||||
|
||||
var params = []#ExpressionNode
|
||||
for i in range(info.arguments):
|
||||
params.append(eval_stack.pop_back())
|
||||
var function_parameters = []
|
||||
for _i in range(info.arguments):
|
||||
function_parameters.append(eval_stack.pop_back())
|
||||
|
||||
params.invert()
|
||||
function_parameters.invert()
|
||||
|
||||
var function = get_func_name(next.type)
|
||||
|
||||
var expression = ExpressionNode.new(parent, parser, null, function, params)
|
||||
var function_name = get_func_name(next.type)
|
||||
var expression = ExpressionNode.new(parent, parser, null, function_name, function_parameters)
|
||||
|
||||
eval_stack.append(expression)
|
||||
|
||||
# A function call
|
||||
elif next.type == Constants.TokenType.Identifier:
|
||||
#function call
|
||||
var function_name = next.value
|
||||
|
||||
var function = next.value
|
||||
|
||||
var params = []#ExpressionNode
|
||||
for i in range(next.param_count):
|
||||
|
||||
params.append(eval_stack.pop_back())
|
||||
var function_parameters = []
|
||||
for _i in range(next.param_count):
|
||||
function_parameters.append(eval_stack.pop_back())
|
||||
|
||||
params.invert()
|
||||
function_parameters.invert()
|
||||
|
||||
var expression = ExpressionNode.new(parent, parser, null, function, params)
|
||||
var expression = ExpressionNode.new(parent, parser, null, function_name, function_parameters)
|
||||
|
||||
eval_stack.append(expression)
|
||||
else: #raw value
|
||||
var value = ValueNode.new(parent, parser, next)
|
||||
var expression = ExpressionNode.new(parent, parser, value)
|
||||
|
||||
# A raw value
|
||||
else:
|
||||
var raw_value = ValueNode.new(parent, parser, next)
|
||||
var expression = ExpressionNode.new(parent, parser, raw_value)
|
||||
eval_stack.append(expression)
|
||||
|
||||
|
||||
|
@ -769,45 +753,39 @@ class ExpressionNode extends ParseNode:
|
|||
if eval_stack.size() != 1:
|
||||
printerr('[%s] Error parsing expression (stack did not reduce correctly )' % first.name)
|
||||
|
||||
|
||||
|
||||
return eval_stack.pop_back()
|
||||
|
||||
static func get_func_name(type):
|
||||
static func get_func_name(_type):
|
||||
var string = ''
|
||||
|
||||
for key in Constants.TokenType.keys():
|
||||
if Constants.TokenType[key] == type:
|
||||
if Constants.TokenType[key] == _type:
|
||||
return key
|
||||
return string
|
||||
|
||||
static func is_apply_precedence(type, operator_stack):
|
||||
static func is_apply_precedence(_type, operator_stack):
|
||||
if operator_stack.size() == 0:
|
||||
return false
|
||||
|
||||
if not Operator.is_op(type):
|
||||
printerr('Unable to parse expression!')
|
||||
if not Operator.is_op(_type):
|
||||
assert(false, 'Unable to parse expression!')
|
||||
|
||||
var second = operator_stack.back().type
|
||||
|
||||
if not Operator.is_op(second):
|
||||
return false
|
||||
|
||||
var first_info = Operator.op_info(type)
|
||||
var first_info = Operator.op_info(_type)
|
||||
var second_info = Operator.op_info(second)
|
||||
|
||||
if (first_info.associativity == Associativity.Left &&
|
||||
first_info.precedence <= second_info.precedence):
|
||||
return true
|
||||
|
||||
if (first_info.associativity == Associativity.Right &&
|
||||
first_info.precedence < second_info.precedence):
|
||||
return true
|
||||
|
||||
return false
|
||||
return \
|
||||
(first_info.associativity == Associativity.Left \
|
||||
and first_info.precedence <= second_info.precedence) \
|
||||
or \
|
||||
(first_info.associativity == Associativity.Right \
|
||||
and first_info.precedence < second_info.precedence)
|
||||
|
||||
class Assignment extends ParseNode:
|
||||
|
||||
var destination
|
||||
var value
|
||||
var operation
|
||||
|
@ -845,15 +823,13 @@ class Assignment extends ParseNode:
|
|||
]
|
||||
|
||||
class Operator extends ParseNode:
|
||||
|
||||
var op_type
|
||||
|
||||
func _init(parent, parser, op_type=null).(parent, parser):
|
||||
|
||||
if op_type == null :
|
||||
self.op_type = parser.expect_symbol(Operator.op_types()).type
|
||||
func _init(parent, parser, _op_type = null).(parent, parser):
|
||||
if _op_type == null :
|
||||
op_type = parser.expect_symbol(Operator.op_types()).type
|
||||
else:
|
||||
self.op_type = op_type
|
||||
op_type = _op_type
|
||||
|
||||
func tree_string(indent_level):
|
||||
var info = []
|
||||
|
@ -923,18 +899,18 @@ class OperatorInfo:
|
|||
var precedence = -1
|
||||
var arguments = -1
|
||||
|
||||
func _init(associativity, precedence, arguments):
|
||||
self.associativity = associativity
|
||||
self.precedence = precedence
|
||||
self.arguments = arguments
|
||||
func _init(_associativity, _precedence, _arguments):
|
||||
associativity = _associativity
|
||||
precedence = _precedence
|
||||
arguments = _arguments
|
||||
|
||||
class Clause:
|
||||
var expression
|
||||
var statements = [] #Statement
|
||||
|
||||
func _init(expression = null, statements = []):
|
||||
self.expression = expression
|
||||
self.statements = statements
|
||||
func _init(_expression = null, _statements = []):
|
||||
expression = _expression
|
||||
statements = _statements
|
||||
|
||||
func tree_string(indent_level):
|
||||
var info = []
|
||||
|
|
|
@ -49,6 +49,7 @@ func set_node(name = DEFAULT_START):
|
|||
_vm.set_node(name)
|
||||
|
||||
func start():
|
||||
print('got here')
|
||||
if _vm.executionState == Constants.ExecutionState.Stopped:
|
||||
_vm.resume()
|
||||
|
||||
|
|
|
@ -1,39 +1,35 @@
|
|||
extends Object
|
||||
var Value : GDScript = load("res://addons/Wol/core/value.gd")
|
||||
|
||||
#name of the function
|
||||
var name : String
|
||||
var name = ''
|
||||
# NOTE: -1 means variable arguments
|
||||
var parameter_count = 0
|
||||
var function
|
||||
var returns_value = false
|
||||
|
||||
#param count of this function
|
||||
# -1 means variable arguments
|
||||
var paramCount : int = 0
|
||||
#function implementation
|
||||
var function : FuncRef
|
||||
var returnsValue : bool = false
|
||||
func _init(_name, _parameter_count, _function = null, _returns_value = false):
|
||||
name = _name
|
||||
parameter_count = _parameter_count
|
||||
function = _function
|
||||
returns_value = _returns_value
|
||||
|
||||
func _init(name: String, paramCount: int, function: FuncRef = null, returnsValue: bool = false):
|
||||
self.name = name
|
||||
self.paramCount = paramCount
|
||||
self.function = function
|
||||
self.returnsValue = returnsValue
|
||||
|
||||
func invoke(params = []):
|
||||
func invoke(parameters = []):
|
||||
var length = 0
|
||||
if params != null:
|
||||
length = params.size()
|
||||
if parameters != null:
|
||||
length = parameters.size()
|
||||
|
||||
if check_param_count(length):
|
||||
if returnsValue:
|
||||
if returns_value:
|
||||
if length > 0:
|
||||
return Value.new(function.call_funcv(params))
|
||||
return Value.new(function.call_funcv(parameters))
|
||||
else:
|
||||
return Value.new(function.call_func())
|
||||
else:
|
||||
if length > 0:
|
||||
function.call_funcv(params)
|
||||
function.call_funcv(parameters)
|
||||
else :
|
||||
function.call_func()
|
||||
return null
|
||||
|
||||
func check_param_count(paramCount: int):
|
||||
return self.paramCount == paramCount || self.paramCount == -1
|
||||
func check_param_count(_parameter_count):
|
||||
return parameter_count == _parameter_count or parameter_count == -1
|
||||
|
|
|
@ -15,28 +15,28 @@ class Line:
|
|||
var implicit = false
|
||||
var meta = []
|
||||
|
||||
func _init(text, node_name, line_number, file_name, implicit, meta):
|
||||
self.text = text
|
||||
self.node_name = node_name
|
||||
self.file_name = file_name
|
||||
self.implicit = implicit
|
||||
self.meta = meta
|
||||
func _init(_text, _node_name, _line_number, _file_name, _implicit, _meta):
|
||||
text = _text
|
||||
node_name = _node_name
|
||||
file_name = _file_name
|
||||
implicit = _implicit
|
||||
meta = _meta
|
||||
|
||||
class Option:
|
||||
var line
|
||||
var id = -1
|
||||
var destination = ''
|
||||
|
||||
func _init(line, id, destination):
|
||||
self.line = line
|
||||
self.id = id
|
||||
self.destination = destination
|
||||
func _init(_line, _id, _destination):
|
||||
line = _line
|
||||
id = _id
|
||||
destination = _destination
|
||||
|
||||
class Command:
|
||||
var command = ''
|
||||
|
||||
func _init(command):
|
||||
self.command = command
|
||||
func _init(_command):
|
||||
command = _command
|
||||
|
||||
class WolNode:
|
||||
var name = ''
|
||||
|
@ -55,15 +55,15 @@ class WolNode:
|
|||
source_id = other.source_id
|
||||
|
||||
func equals(other):
|
||||
if other.get_script() != self.get_script():
|
||||
if other.get_script() != get_script():
|
||||
return false
|
||||
if other.name != self.name:
|
||||
if other.name != name:
|
||||
return false
|
||||
if other.instructions != self.instructions:
|
||||
if other.instructions != instructions:
|
||||
return false
|
||||
if other.label != self.label:
|
||||
if other.labels != labels:
|
||||
return false
|
||||
if other.sourceId != self.sourceId:
|
||||
if other.source_id != source_id:
|
||||
return false
|
||||
return true
|
||||
|
||||
|
@ -82,33 +82,33 @@ class Operand:
|
|||
var value
|
||||
var type
|
||||
|
||||
func _init(value):
|
||||
if typeof(value) == TYPE_OBJECT and value.get_script() == self.get_script():
|
||||
set_value(value.value)
|
||||
func _init(_value):
|
||||
if typeof(_value) == TYPE_OBJECT and _value.get_script() == get_script():
|
||||
set_value(_value.value)
|
||||
else:
|
||||
set_value(value)
|
||||
set_value(_value)
|
||||
|
||||
func set_value(value):
|
||||
match typeof(value):
|
||||
func set_value(_value):
|
||||
match typeof(_value):
|
||||
TYPE_REAL,TYPE_INT:
|
||||
set_number(value)
|
||||
set_number(_value)
|
||||
TYPE_BOOL:
|
||||
set_boolean(value)
|
||||
set_boolean(_value)
|
||||
TYPE_STRING:
|
||||
set_string(value)
|
||||
set_string(_value)
|
||||
|
||||
func set_boolean(value):
|
||||
_value(value)
|
||||
func set_boolean(_value):
|
||||
value = _value
|
||||
type = ValueType.BooleanValue
|
||||
return self
|
||||
|
||||
func set_string(value):
|
||||
_value(value)
|
||||
func set_string(_value):
|
||||
value = _value
|
||||
type = ValueType.StringValue
|
||||
return self
|
||||
|
||||
func set_number(value):
|
||||
_value(value)
|
||||
func set_number(_value):
|
||||
value = _value
|
||||
type = ValueType.FloatValue
|
||||
return self
|
||||
|
||||
|
@ -122,9 +122,6 @@ class Operand:
|
|||
func _to_string():
|
||||
return "Operand[%s:%s]" % [type, value]
|
||||
|
||||
func _value(value):
|
||||
self.value = value
|
||||
|
||||
class Instruction:
|
||||
var operation = -1
|
||||
var operands = []
|
||||
|
@ -134,9 +131,6 @@ class Instruction:
|
|||
self.operation = other.operation
|
||||
self.operands += other.operands
|
||||
|
||||
func dump(program, library):
|
||||
return "InstructionInformation:NotImplemented"
|
||||
|
||||
func _to_string():
|
||||
return Constants.bytecode_name(operation) + ':' + operands as String
|
||||
|
||||
|
|
|
@ -219,27 +219,27 @@ func run_instruction(instruction)->bool:
|
|||
|
||||
var function = _dialogue.library.get_function(functionName)
|
||||
|
||||
var expectedParamCount : int = function.paramCount
|
||||
var actualParamCount : int = _state.pop_value().as_number()
|
||||
var expected_parameter_count : int = function.paramCount
|
||||
var actual_parameter_count : int = _state.pop_value().as_number()
|
||||
|
||||
#if function takes in -1 params disregard
|
||||
#expect the compiler to have placed the number of params
|
||||
#at the top of the stack
|
||||
if expectedParamCount == -1:
|
||||
expectedParamCount = actualParamCount
|
||||
if expected_parameter_count == -1:
|
||||
expected_parameter_count = actual_parameter_count
|
||||
|
||||
if expectedParamCount != actualParamCount:
|
||||
if expected_parameter_count != actual_parameter_count:
|
||||
printerr('Function %s expected %d parameters but got %d instead' %[functionName,
|
||||
expectedParamCount,actualParamCount])
|
||||
expected_parameter_count,actual_parameter_count])
|
||||
return false
|
||||
|
||||
var result
|
||||
|
||||
if actualParamCount == 0:
|
||||
if actual_parameter_count == 0:
|
||||
result = function.invoke()
|
||||
else:
|
||||
var params : Array = []#value
|
||||
for i in range(actualParamCount):
|
||||
for _i in range(actual_parameter_count):
|
||||
params.push_front(_state.pop_value())
|
||||
|
||||
result = function.invoke(params)
|
||||
|
@ -352,6 +352,6 @@ class SimpleEntry:
|
|||
var key
|
||||
var value
|
||||
|
||||
func _init(key, value):
|
||||
self.key = key
|
||||
self.value = value
|
||||
func _init(_key, _value):
|
||||
key = _key
|
||||
value = _value
|
||||
|
|
|
@ -20,6 +20,11 @@ _global_script_classes=[ {
|
|||
"path": "res://addons/Wol/core/constants.gd"
|
||||
}, {
|
||||
"base": "Object",
|
||||
"class": "Lexer",
|
||||
"language": "GDScript",
|
||||
"path": "res://addons/Wol/core/compiler/lexer.gd"
|
||||
}, {
|
||||
"base": "Object",
|
||||
"class": "Program",
|
||||
"language": "GDScript",
|
||||
"path": "res://addons/Wol/core/program.gd"
|
||||
|
@ -32,6 +37,7 @@ _global_script_classes=[ {
|
|||
_global_script_class_icons={
|
||||
"Compiler": "",
|
||||
"Constants": "",
|
||||
"Lexer": "",
|
||||
"Program": "",
|
||||
"Wol": ""
|
||||
}
|
||||
|
@ -42,6 +48,12 @@ config/name="Wol"
|
|||
run/main_scene="res://Dialogue.tscn"
|
||||
config/icon="res://icon.png"
|
||||
|
||||
[debug]
|
||||
|
||||
gdscript/warnings/treat_warnings_as_errors=true
|
||||
gdscript/warnings/exclude_addons=false
|
||||
gdscript/warnings/return_value_discarded=false
|
||||
|
||||
[editor_plugins]
|
||||
|
||||
enabled=PoolStringArray( "res://addons/Wol/plugin.cfg" )
|
||||
|
|
Reference in a new issue