-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGemParser.gd
More file actions
144 lines (124 loc) · 3.93 KB
/
Copy pathGemParser.gd
File metadata and controls
144 lines (124 loc) · 3.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
extends Node
var class_rune = load("Rune.gd")
var class_composite = load("Composite_Gem.gd")
var class_main_gem = load("Main_Gem.gd")
var class_efficiency_gem = load("Efficiency_Gem.gd")
var end = ";"
var separator = " "
var abstraction = "\\"
var open = "("
var close = ")"
func _ready():
# Called every time the node is added to the scene.
# Initialization here
pass
func read_gem(expr):
var res = read_expression({},expr)
return res[0]
# Returns an array of two elements. First one is the gem corresponding to the expression,
# the second one is the remnant of the string.
func read_expression(vars,expr):
# Read first token
var res = read_token(vars,expr)
var rest = res[2]
# If it is none, something went very wrong:
if res[0] == "none":
print("EMPTY EXPRESSION!!")
return null
# If it is an abstraction, we know what we are up for.
elif res[0] == "abs":
# Build the main gem.
var rune = res[1][0]
var name = res[1][1]
var main_gem = class_main_gem.new()
main_gem.gem_rune = rune
# Add it to vars
vars[name] = main_gem
# Parse the efficiency
res = read_efficiency(rest)
rest = res[1]
var efficiency = res[0]
var eff_gem = class_efficiency_gem.new()
eff_gem.efficiency = efficiency
# Parse the body
res = read_token(vars,rest)
rest = res[2]
# We assume it will be a subexpression. Anything else would be wrong.
rune.efficiency_gem = eff_gem
rune.body = res[1]
return [rune,rest]
else: # It may be a composite or a single gem.
var first = res[1]
res = read_token(vars,rest)
rest = res[2]
if res[0] == "none": # It was a single gem.
return [first,rest]
else: # Composite
var composite = class_composite.new()
composite.f = first
composite.x = res[1]
return [composite,rest]
# Returns an array of three elements. First one indicates whether there is no next token ("none"),
# it is an abstraction ("abs") or other kind of gem ("other")
# and second one is, in case of an abstraction, an array of two elements: the rune, and the variable name for parsing,
# or otherwise the token (a gem).
# The third one is the remnant of the string.
func read_token(vars,expr):
var first = expr.left(1)
var rest = expr.right(1)
if first == end or first == close or first == separator:
return ["none",null,rest]
# If first is abstraction, then create a rune and return the main gem.
elif first == abstraction:
var var_name = ""
first = rest.left(1)
rest = rest.right(1)
while first != end and first != close and first != separator:
var_name = var_name + first
first = rest.left(1)
rest = rest.right(1)
var rune = class_rune.new()
# No efficiency or body yet.
return ["abs",[rune,var_name],rest]
elif first == open: # Subexpression
var subexpr = read_expression(vars,rest)
var subexpr_rest = subexpr[1]
return ["other",subexpr[0],subexpr_rest.right(1)]
else: # Variable or elemental gem
var id = ""
while (first != end and first != close and first != separator):
id = id + first
first = rest.left(1)
rest = rest.right(1)
# Try to find the id in the variables.
if vars.has(id):
# Then return the main gem.
return ["other",vars[id],rest]
else:
# Else parse the elemental gem and return it.
return ["other",read_elemental_gem(id),rest]
var class_dmg = load("res://Elemental gems/Damage.gd")
var class_repeat = load("res://Elemental gems/Repeat.gd")
func read_elemental_gem(id):
if id.left(3) == "dmg":
var gem = class_dmg.new()
gem.damage = int(id.right(3))
return gem
elif id.left(3) == "rep":
var gem = class_repeat.new()
var args = id.right(3)
var largs = args.split(",")
var freq = largs[0]
var reps = largs[1]
gem.freq = int(freq)
gem.repetitions = int(reps)
return gem
func read_efficiency(expr):
var strn = ""
var first = expr.left(1)
var rest = expr.right(1)
while first != end and first != close and first != separator:
strn = strn + first
first = rest.left(1)
rest = rest.right(1)
return [float(strn),rest]