zeolite-lang-0.7.0.0: example/parser/parser.0rx
define ParseState {
refines ParseContext<#x>
@value String data
@value Int index
@value Int line
@value Int char
@value ErrorOr<#x> value
@value optional Formatted error
consumeAll (parser,data) {
ParseContext<#y> context <- parser.run(new(data))
if (context.hasAnyError()) {
return context.getValue()
} elif (!context.atEof()) {
return ErrorOr$$error("Parsing did not consume all of the data " + context.getPosition())
} else {
return context.getValue()
}
}
run (parser) {
return parser.run(self)
}
runAndGet (parser) {
ParseContext<#y> context <- parser.run(self)
return context, context.getValue()
}
getValue () {
if (present(error)) {
return ErrorOr$$error(require(error))
} else {
return value
}
}
convertError () {
return ParseState<all>{ data, index, line, char, ErrorOr$$error(getError()), error }
}
setValue (value2) {
if (hasBrokenInput()) {
return convertError()
} else {
return ParseState<#y>{ data, index, line, char, value2, error }
}
}
setBrokenInput (message) {
return ParseState<all>{ data, index, line, char, ErrorOr$$error(message), message }
}
toState () {
return self
}
getPosition () {
return String$builder()
.append("[line: ")
.append(line.formatted())
.append(", char: ")
.append(char.formatted())
.append("]")
.build()
}
atEof () {
return index >= data.readSize()
}
hasAnyError () {
return present(error) || value.isError()
}
hasBrokenInput () {
return present(error)
}
current () {
\ sanityCheck()
return data.readPosition(index)
}
advance () {
\ sanityCheck()
if (data.readPosition(index) == '\n') {
return ParseState<#x>{ data, index+1, line+1, 1, value, error }
} else {
return ParseState<#x>{ data, index+1, line, char+1, value, error }
}
}
@category new (String) -> (ParseState<any>)
new (data) {
return ParseState<any>{ data, 0, 1, 1, ErrorOr$$value<?>(Void$void()), empty }
}
@value getError () -> (Formatted)
getError () {
if (present(error)) {
return require(error)
} else {
return value.getError()
}
}
@value sanityCheck () -> ()
sanityCheck () {
if (hasBrokenInput()) {
\ LazyStream<Formatted>$new()
.append("Error at ")
.append(getPosition())
.append(": ")
.append(getError())
.writeTo(SimpleOutput$error())
}
if (atEof()) {
\ LazyStream<Formatted>$new()
.append("Reached end of input at ")
.append(getPosition())
.writeTo(SimpleOutput$error())
}
}
}