51 lines
1.4 KiB
Crystal
51 lines
1.4 KiB
Crystal
|
|
||
|
require "../prompt"
|
||
|
|
||
|
class StringParser
|
||
|
def parse(current : String) : Prompt
|
||
|
prompt = Prompt.new
|
||
|
remaining = read_string(prompt.zones, current)
|
||
|
prompt.prelude_zone.content << remaining
|
||
|
|
||
|
prompt.system_zone.content.reverse!
|
||
|
prompt.past_zone.content.reverse!
|
||
|
prompt.present_zone.content.reverse!
|
||
|
prompt.future_zone.content.reverse!
|
||
|
|
||
|
return prompt
|
||
|
end
|
||
|
|
||
|
def read_string(zone_list : Array(Zone), current : String)
|
||
|
# puts "== read_string(current=#{current})"
|
||
|
|
||
|
pos = current.index("@@")
|
||
|
|
||
|
## If there is no remaining @@, then return current
|
||
|
if pos.nil?
|
||
|
# puts "-- no remaining @@, returning"
|
||
|
return current
|
||
|
end
|
||
|
|
||
|
## If @@ is not at position 0, then parse its content first and return remains
|
||
|
if pos > 0
|
||
|
return current[0..(pos-1)] + read_string(zone_list, current[pos..])
|
||
|
end
|
||
|
|
||
|
## If @@ is at position 0, try detecting tag
|
||
|
zone = zone_list.find { |zone| current.starts_with?("@@" + zone.tag) }
|
||
|
|
||
|
## When there is not recognizable tag, skip fake tag and parse
|
||
|
if zone.nil?
|
||
|
# puts "-- no recognizable tag, returning as is"
|
||
|
return "@@" + read_string(zone_list, current[2..])
|
||
|
end
|
||
|
|
||
|
## Handle recognized tag, skip tag & parse & add remains
|
||
|
# puts "-- found tag #{zone.tag}"
|
||
|
remaining = read_string(zone_list, current[(2+zone.tag.size)..])
|
||
|
zone.content << remaining
|
||
|
return ""
|
||
|
end
|
||
|
end
|
||
|
|