mirror of
https://github.com/KarolS/millfork.git
synced 2025-08-15 04:27:21 +00:00
Allow for comments at the end of the file (fixes #15)
This commit is contained in:
@@ -5,6 +5,19 @@ package millfork
|
|||||||
*/
|
*/
|
||||||
case class SeparatedList[T, S](head: T, tail: List[(S, T)]) {
|
case class SeparatedList[T, S](head: T, tail: List[(S, T)]) {
|
||||||
|
|
||||||
|
def exists(predicate: T => Boolean): Boolean = {
|
||||||
|
predicate(head) || tail.exists(x => predicate(x._2))
|
||||||
|
}
|
||||||
|
|
||||||
|
def count(predicate: T => Boolean): Int = {
|
||||||
|
val headCount = if (predicate(head)) 1 else 0
|
||||||
|
headCount + tail.count(x => predicate(x._2))
|
||||||
|
}
|
||||||
|
|
||||||
|
def map[R](f: T => R): SeparatedList[R, S] = {
|
||||||
|
SeparatedList(f(head), tail.map(x => x._1 -> f(x._2)))
|
||||||
|
}
|
||||||
|
|
||||||
def toPairList(initialSeparator: S): List[(S, T)] = (initialSeparator -> head) :: tail
|
def toPairList(initialSeparator: S): List[(S, T)] = (initialSeparator -> head) :: tail
|
||||||
|
|
||||||
def size: Int = tail.size + 1
|
def size: Int = tail.size + 1
|
||||||
|
@@ -50,19 +50,21 @@ abstract class MfParser[T](fileId: String, input: String, currentDirectory: Stri
|
|||||||
newPosition
|
newPosition
|
||||||
}
|
}
|
||||||
|
|
||||||
val comment: P[Unit] = P("//" ~/ CharsWhile(c => c != '\n' && c != '\r', min = 0) ~ ("\r\n" | "\r" | "\n"))
|
val comment: P[Unit] = P("//" ~ CharsWhile(c => c != '\n' && c != '\r', min = 0) ~ ("\r\n" | "\r" | "\n"))
|
||||||
|
|
||||||
val semicolon: P[Unit] = P(";" ~/ CharsWhileIn("; \t", min = 0) ~/ position("line break after a semicolon").map(_ => ()) ~/ (comment | "\r\n" | "\r" | "\n").opaque("<line break>"))
|
val semicolon: P[Unit] = P(";" ~ CharsWhileIn("; \t", min = 0) ~ position("line break after a semicolon").map(_ => ()) ~ (comment | "\r\n" | "\r" | "\n").opaque("<line break>"))
|
||||||
|
|
||||||
val semicolonComment: P[Unit] = P(";" ~/ CharsWhile(c => c != '\n' && c != '\r' && c != '{' && c != '}', min = 0) ~/ position("line break instead of braces").map(_ => ()) ~/ ("\r\n" | "\r" | "\n").opaque("<line break>"))
|
val semicolonComment: P[Unit] = P(";" ~ CharsWhile(c => c != '\n' && c != '\r' && c != '{' && c != '}', min = 0) ~ position("line break instead of braces").map(_ => ()) ~ ("\r\n" | "\r" | "\n").opaque("<line break>"))
|
||||||
|
|
||||||
val AWS: P[Unit] = P((CharIn(" \t\n\r") | NoCut(semicolon) | NoCut(comment)).rep(min = 0)).opaque("<any whitespace>")
|
val AWS: P[Unit] = P((CharIn(" \t\n\r") | semicolon | comment).rep(min = 0)).opaque("<any whitespace>")
|
||||||
|
|
||||||
val AWS_asm: P[Unit] = P((CharIn(" \t\n\r") | NoCut(semicolonComment) | NoCut(comment)).rep(min = 0)).opaque("<any whitespace>")
|
val AWS_asm: P[Unit] = P((CharIn(" \t\n\r") | semicolonComment | comment).rep(min = 0)).opaque("<any whitespace>")
|
||||||
|
|
||||||
|
val Before_EOL: P[Unit] = HWS ~ &("\r" | "\n" | ";" | "//").opaque("<line break>")
|
||||||
|
|
||||||
val EOL: P[Unit] = P(HWS ~ ("\r\n" | "\r" | "\n" | semicolon | comment).opaque("<first line break>") ~ AWS).opaque("<line break>")
|
val EOL: P[Unit] = P(HWS ~ ("\r\n" | "\r" | "\n" | semicolon | comment).opaque("<first line break>") ~ AWS).opaque("<line break>")
|
||||||
|
|
||||||
val EOL_asm: P[Unit] = P(HWS ~ ("\r\n" | "\r" | "\n" | comment | semicolonComment).opaque("<first line break>") ~ AWS).opaque("<line break>")
|
val EOL_asm: P[Unit] = P(HWS ~ ("\r\n" | "\r" | "\n" | semicolon | comment).opaque("<first line break>") ~ AWS).opaque("<line break>")
|
||||||
|
|
||||||
val EOLOrComma: P[Unit] = P(HWS ~ ("\r\n" | "\r" | "\n" | "," | semicolon | comment).opaque("<first line break or comma>") ~ AWS).opaque("<line break or comma>")
|
val EOLOrComma: P[Unit] = P(HWS ~ ("\r\n" | "\r" | "\n" | "," | semicolon | comment).opaque("<first line break or comma>") ~ AWS).opaque("<line break or comma>")
|
||||||
|
|
||||||
@@ -155,7 +157,7 @@ abstract class MfParser[T](fileId: String, input: String, currentDirectory: Stri
|
|||||||
p <- position()
|
p <- position()
|
||||||
name <- identifier ~/ HWS ~/ Pass
|
name <- identifier ~/ HWS ~/ Pass
|
||||||
addr <- ("@" ~/ HWS ~/ mfExpression(1, false)).?.opaque("<address>") ~ HWS
|
addr <- ("@" ~/ HWS ~/ mfExpression(1, false)).?.opaque("<address>") ~ HWS
|
||||||
initialValue <- ("=" ~/ HWS ~/ mfExpression(1, false)).? ~ HWS
|
initialValue <- ("=" ~/ HWS ~/ mfExpression(1, false)).? ~/ HWS
|
||||||
alignment = None // TODO
|
alignment = None // TODO
|
||||||
} yield (p, name, addr, initialValue, alignment)
|
} yield (p, name, addr, initialValue, alignment)
|
||||||
|
|
||||||
@@ -165,7 +167,7 @@ abstract class MfParser[T](fileId: String, input: String, currentDirectory: Stri
|
|||||||
flags <- variableFlags ~ HWS
|
flags <- variableFlags ~ HWS
|
||||||
typ <- identifier ~/ SWS
|
typ <- identifier ~/ SWS
|
||||||
vars <- singleVariableDefinition.rep(min = 1, sep = "," ~/ HWS)
|
vars <- singleVariableDefinition.rep(min = 1, sep = "," ~/ HWS)
|
||||||
_ <- &(EOL) ~/ ""
|
_ <- Before_EOL ~/ ""
|
||||||
} yield {
|
} yield {
|
||||||
vars.map { case (p, name, addr, initialValue, alignment) => VariableDeclarationStatement(name, typ,
|
vars.map { case (p, name, addr, initialValue, alignment) => VariableDeclarationStatement(name, typ,
|
||||||
bank,
|
bank,
|
||||||
|
Reference in New Issue
Block a user