diff --git a/.scalafmt.conf b/.scalafmt.conf index a4c5951..3df68b5 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -3,3 +3,4 @@ runner.dialect = scala3 binPack.literalsExclude = [] indent.infix.excludeRegex = "^$" +maxColumn = 100 diff --git a/project.scala b/project.scala index 7a42a9c..e6fb151 100644 --- a/project.scala +++ b/project.scala @@ -3,6 +3,7 @@ // dependencies //> using dep com.github.j-mie6::parsley::5.0.0-M10 +//> using dep com.github.j-mie6::parsley-cats::1.3.0 //> using dep com.lihaoyi::os-lib::0.11.3 //> using dep com.github.scopt::scopt::4.1.0 //> using test.dep org.scalatest::scalatest::3.2.19 diff --git a/src/main/wacc/ast.scala b/src/main/wacc/ast.scala index 4af5b1d..c6e743e 100644 --- a/src/main/wacc/ast.scala +++ b/src/main/wacc/ast.scala @@ -1,6 +1,7 @@ package wacc import parsley.generic._ +import cats.data.NonEmptyList object ast { // Expressions @@ -24,10 +25,8 @@ object ast { case object PairLiter extends Expr6 with ParserBridge0[PairLiter.type] case class Ident(v: String) extends Expr6 with LValue object Ident extends ParserBridge1[String, Ident] - case class ArrayElem(name: Ident, indices: List[Expr]) - extends Expr6 - with LValue - object ArrayElem extends ParserBridge2[Ident, List[Expr], ArrayElem] + case class ArrayElem(name: Ident, indices: NonEmptyList[Expr]) extends Expr6 with LValue + object ArrayElem extends ParserBridge2[Ident, NonEmptyList[Expr], ArrayElem] case class Parens(expr: Expr) extends Expr6 object Parens extends ParserBridge1[Expr, Parens] @@ -78,31 +77,26 @@ object ast { case object BoolType extends BaseType with ParserBridge0[BoolType.type] case object CharType extends BaseType with ParserBridge0[CharType.type] case object StringType extends BaseType with ParserBridge0[StringType.type] - case class ArrayType(elemType: Type, dimensions: Int) - extends Type - with PairElemType + case class ArrayType(elemType: Type, dimensions: Int) extends Type with PairElemType object ArrayType extends ParserBridge2[Type, Int, ArrayType] case class PairType(fst: PairElemType, snd: PairElemType) extends Type object PairType extends ParserBridge2[PairElemType, PairElemType, PairType] sealed trait PairElemType - case object UntypedPairType - extends PairElemType - with ParserBridge0[UntypedPairType.type] + case object UntypedPairType extends PairElemType with ParserBridge0[UntypedPairType.type] // waccadoodledo - case class Program(funcs: List[FuncDecl], main: List[Stmt]) - object Program extends ParserBridge2[List[FuncDecl], List[Stmt], Program] + case class Program(funcs: List[FuncDecl], main: NonEmptyList[Stmt]) + object Program extends ParserBridge2[List[FuncDecl], NonEmptyList[Stmt], Program] // Function Definitions case class FuncDecl( returnType: Type, name: Ident, params: List[Param], - body: List[Stmt] + body: NonEmptyList[Stmt] ) - object FuncDecl - extends ParserBridge4[Type, Ident, List[Param], List[Stmt], FuncDecl] + object FuncDecl extends ParserBridge4[Type, Ident, List[Param], NonEmptyList[Stmt], FuncDecl] case class Param(paramType: Type, name: Ident) object Param extends ParserBridge2[Type, Ident, Param] @@ -124,13 +118,12 @@ object ast { object Exit extends ParserBridge1[Expr, Exit] case class Print(expr: Expr, newline: Boolean) extends Stmt object Print extends ParserBridge2[Expr, Boolean, Print] - case class If(cond: Expr, thenStmt: List[Stmt], elseStmt: List[Stmt]) - extends Stmt - object If extends ParserBridge3[Expr, List[Stmt], List[Stmt], If] - case class While(cond: Expr, body: List[Stmt]) extends Stmt - object While extends ParserBridge2[Expr, List[Stmt], While] - case class Block(stmt: List[Stmt]) extends Stmt - object Block extends ParserBridge1[List[Stmt], Block] + case class If(cond: Expr, thenStmt: NonEmptyList[Stmt], elseStmt: NonEmptyList[Stmt]) extends Stmt + object If extends ParserBridge3[Expr, NonEmptyList[Stmt], NonEmptyList[Stmt], If] + case class While(cond: Expr, body: NonEmptyList[Stmt]) extends Stmt + object While extends ParserBridge2[Expr, NonEmptyList[Stmt], While] + case class Block(stmt: NonEmptyList[Stmt]) extends Stmt + object Block extends ParserBridge1[NonEmptyList[Stmt], Block] sealed trait LValue diff --git a/src/main/wacc/lexer.scala b/src/main/wacc/lexer.scala index abe5cb1..4351294 100644 --- a/src/main/wacc/lexer.scala +++ b/src/main/wacc/lexer.scala @@ -12,22 +12,19 @@ object lexer { ), 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" + "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 != '"'), + graphicCharacter = Basic(c => c >= ' ' && c != '\\' && c != '\'' && c != '"'), escapeSequences = EscapeDesc.plain.copy( literals = Set('\\', '"', '\''), mapping = Map( diff --git a/src/main/wacc/parser.scala b/src/main/wacc/parser.scala index c33cbc8..0d4b03b 100644 --- a/src/main/wacc/parser.scala +++ b/src/main/wacc/parser.scala @@ -2,9 +2,11 @@ package wacc import parsley.Result import parsley.Parsley -import parsley.Parsley.{atomic, many, pure, some} -import parsley.combinator.{countSome, sepBy, sepBy1} +import parsley.Parsley.{atomic, many, pure} +import parsley.combinator.{countSome, sepBy} import parsley.expr.{precedence, SOps, InfixL, InfixN, InfixR, Prefix, Atoms} +import parsley.cats.combinator.{sepBy1, some} +import cats.data.NonEmptyList object parser { import lexer.implicits.implicitSymbol @@ -83,7 +85,7 @@ object parser { `` <~ "end" ) private lazy val `` = Param(``, ``) - private lazy val ``: Parsley[List[Stmt]] = + private lazy val ``: Parsley[NonEmptyList[Stmt]] = sepBy1(``, ";") private lazy val `` = (Skip from atomic("skip")) diff --git a/src/test/wacc/examples.scala b/src/test/wacc/examples.scala index 3afc377..56f6b36 100644 --- a/src/test/wacc/examples.scala +++ b/src/test/wacc/examples.scala @@ -4,10 +4,7 @@ import org.scalatest.{ParallelTestExecution, BeforeAndAfterAll} import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.Inspectors.forEvery -class ParallelExamplesSpec - extends AnyFlatSpec - with BeforeAndAfterAll - with ParallelTestExecution { +class ParallelExamplesSpec extends AnyFlatSpec with BeforeAndAfterAll with ParallelTestExecution { val files = allWaccFiles("wacc-examples/valid").map { p => (p.toString, List(0))