feat: incomplete initial implementation of assemblyIR
This commit is contained in:
105
src/main/wacc/frontend/lexer.scala
Normal file
105
src/main/wacc/frontend/lexer.scala
Normal file
@@ -0,0 +1,105 @@
|
||||
package wacc
|
||||
|
||||
import parsley.Parsley
|
||||
import parsley.character
|
||||
import parsley.token.{Basic, Lexer}
|
||||
import parsley.token.descriptions.*
|
||||
import parsley.token.errors._
|
||||
|
||||
/** ErrorConfig for producing more informative error messages
|
||||
*/
|
||||
val errConfig = new ErrorConfig {
|
||||
override def labelSymbol = Map(
|
||||
"!=" -> Label("binary operator"),
|
||||
"%" -> Label("binary operator"),
|
||||
"&&" -> Label("binary operator"),
|
||||
"*" -> Label("binary operator"),
|
||||
"/" -> Label("binary operator"),
|
||||
"<" -> Label("binary operator"),
|
||||
"<=" -> Label("binary operator"),
|
||||
"==" -> Label("binary operator"),
|
||||
">" -> Label("binary operator"),
|
||||
">=" -> Label("binary operator"),
|
||||
"||" -> Label("binary operator"),
|
||||
"!" -> Label("unary operator"),
|
||||
"len" -> Label("unary operator"),
|
||||
"ord" -> Label("unary operator"),
|
||||
"chr" -> Label("unary operator"),
|
||||
"bool" -> Label("valid type"),
|
||||
"char" -> Label("valid type"),
|
||||
"int" -> Label("valid type"),
|
||||
"pair" -> Label("valid type"),
|
||||
"string" -> Label("valid type"),
|
||||
"fst" -> Label("pair extraction"),
|
||||
"snd" -> Label("pair extraction"),
|
||||
"false" -> Label("boolean literal"),
|
||||
"true" -> Label("boolean literal"),
|
||||
"=" -> Label("assignment"),
|
||||
"[" -> Label("array index")
|
||||
)
|
||||
}
|
||||
object lexer {
|
||||
|
||||
/** Language description for the WACC lexer
|
||||
*/
|
||||
private val desc = LexicalDesc.plain.copy(
|
||||
nameDesc = NameDesc.plain.copy(
|
||||
identifierStart = Basic(c => c.isLetter || c == '_'),
|
||||
identifierLetter = Basic(c => c.isLetterOrDigit || c == '_')
|
||||
),
|
||||
symbolDesc = SymbolDesc.plain.copy(
|
||||
hardKeywords = Set(
|
||||
"begin", "end", "is", "skip", "if", "then", "else", "fi", "while", "do", "done", "read",
|
||||
"free", "return", "exit", "print", "println", "true", "false", "int", "bool", "char",
|
||||
"string", "pair", "newpair", "fst", "snd", "call", "chr", "ord", "len", "null"
|
||||
),
|
||||
hardOperators = Set(
|
||||
"+", "-", "*", "/", "%", ">", "<", ">=", "<=", "==", "!=", "&&", "||", "!"
|
||||
)
|
||||
),
|
||||
spaceDesc = SpaceDesc.plain.copy(
|
||||
lineCommentStart = "#"
|
||||
),
|
||||
textDesc = TextDesc.plain.copy(
|
||||
graphicCharacter = Basic(c => c >= ' ' && c != '\\' && c != '\'' && c != '"'),
|
||||
escapeSequences = EscapeDesc.plain.copy(
|
||||
literals = Set('\\', '"', '\''),
|
||||
mapping = Map(
|
||||
"0" -> '\u0000',
|
||||
"b" -> '\b',
|
||||
"t" -> '\t',
|
||||
"n" -> '\n',
|
||||
"f" -> '\f',
|
||||
"r" -> '\r'
|
||||
)
|
||||
)
|
||||
),
|
||||
numericDesc = NumericDesc.plain.copy(
|
||||
decimalExponentDesc = ExponentDesc.NoExponents
|
||||
)
|
||||
)
|
||||
|
||||
/** Token definitions for the WACC lexer
|
||||
*/
|
||||
private val lexer = Lexer(desc, errConfig)
|
||||
val ident = lexer.lexeme.names.identifier
|
||||
val integer = lexer.lexeme.integer.decimal32[Int]
|
||||
val negateCheck = lexer.nonlexeme.symbol("-") ~> character.digit
|
||||
val charLit = lexer.lexeme.character.ascii
|
||||
val stringLit = lexer.lexeme.string.ascii
|
||||
val implicits = lexer.lexeme.symbol.implicits
|
||||
|
||||
/** Tokens for producing lexer-backed error messages
|
||||
*/
|
||||
val errTokens = Seq(
|
||||
lexer.nonlexeme.names.identifier.map(v => s"identifier $v"),
|
||||
lexer.nonlexeme.integer.decimal32[Int].map(n => s"integer $n"),
|
||||
lexer.nonlexeme.character.ascii.map(c => s"character literal \'$c\'"),
|
||||
lexer.nonlexeme.string.ascii.map(s => s"string literal \"$s\""),
|
||||
lexer.nonlexeme.symbol("[").as("array literal"),
|
||||
character.whitespace.map(_ => "")
|
||||
) ++ desc.symbolDesc.hardKeywords.map { k =>
|
||||
lexer.nonlexeme.symbol(k).as(s"keyword $k")
|
||||
}
|
||||
def fully[A](p: Parsley[A]): Parsley[A] = lexer.fully(p)
|
||||
}
|
||||
Reference in New Issue
Block a user