From f3a59460ef51d57424567af20189e10fa401b94e Mon Sep 17 00:00:00 2001 From: Gleb Koval Date: Wed, 5 Feb 2025 02:12:16 +0000 Subject: [PATCH 1/3] refactor: add position tracking to AST, UnaryOp, BinaryOp --- src/main/wacc/ast.scala | 282 ++++++++++++++++++++++++++-------------- 1 file changed, 184 insertions(+), 98 deletions(-) diff --git a/src/main/wacc/ast.scala b/src/main/wacc/ast.scala index c6e743e..9afd8d9 100644 --- a/src/main/wacc/ast.scala +++ b/src/main/wacc/ast.scala @@ -1,6 +1,9 @@ package wacc -import parsley.generic._ +import parsley.Parsley +import parsley.generic.ErrorBridge +import parsley.position._ +import parsley.syntax.zipped._ import cats.data.NonEmptyList object ast { @@ -14,80 +17,97 @@ object ast { sealed trait Expr6 extends Expr5 // Atoms - case class IntLiter(v: Int) extends Expr6 - object IntLiter extends ParserBridge1[Int, IntLiter] - case class BoolLiter(v: Boolean) extends Expr6 - object BoolLiter extends ParserBridge1[Boolean, BoolLiter] - case class CharLiter(v: Char) extends Expr6 - object CharLiter extends ParserBridge1[Char, CharLiter] - case class StrLiter(v: String) extends Expr6 - object StrLiter extends ParserBridge1[String, StrLiter] - 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: 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] + case class IntLiter(v: Int)(pos: Position) extends Expr6 + object IntLiter extends ParserBridgePos1[Int, IntLiter] + case class BoolLiter(v: Boolean)(pos: Position) extends Expr6 + object BoolLiter extends ParserBridgePos1[Boolean, BoolLiter] + case class CharLiter(v: Char)(pos: Position) extends Expr6 + object CharLiter extends ParserBridgePos1[Char, CharLiter] + case class StrLiter(v: String)(pos: Position) extends Expr6 + object StrLiter extends ParserBridgePos1[String, StrLiter] + case class PairLiter()(pos: Position) extends Expr6 + object PairLiter extends Expr6 with ParserBridgePos0[PairLiter] + case class Ident(v: String)(pos: Position) extends Expr6 with LValue + object Ident extends ParserBridgePos1[String, Ident] + case class ArrayElem(name: Ident, indices: NonEmptyList[Expr])(pos: Position) + extends Expr6 + with LValue + object ArrayElem extends ParserBridgePos2[Ident, NonEmptyList[Expr], ArrayElem] + case class Parens(expr: Expr)(pos: Position) extends Expr6 + object Parens extends ParserBridgePos1[Expr, Parens] // Unary operators - case class Negate(x: Expr6) extends Expr6 - object Negate extends ParserBridge1[Expr6, Negate] - case class Not(x: Expr6) extends Expr6 - object Not extends ParserBridge1[Expr6, Not] - case class Len(x: Expr6) extends Expr6 - object Len extends ParserBridge1[Expr6, Len] - case class Ord(x: Expr6) extends Expr6 - object Ord extends ParserBridge1[Expr6, Ord] - case class Chr(x: Expr6) extends Expr6 - object Chr extends ParserBridge1[Expr6, Chr] + sealed trait UnaryOp extends Expr { + val x: Expr + } + case class Negate(x: Expr6)(pos: Position) extends Expr6 with UnaryOp + object Negate extends ParserBridgePos1[Expr6, Negate] + case class Not(x: Expr6)(pos: Position) extends Expr6 with UnaryOp + object Not extends ParserBridgePos1[Expr6, Not] + case class Len(x: Expr6)(pos: Position) extends Expr6 with UnaryOp + object Len extends ParserBridgePos1[Expr6, Len] + case class Ord(x: Expr6)(pos: Position) extends Expr6 with UnaryOp + object Ord extends ParserBridgePos1[Expr6, Ord] + case class Chr(x: Expr6)(pos: Position) extends Expr6 with UnaryOp + object Chr extends ParserBridgePos1[Expr6, Chr] // Binary operators - case class Add(x: Expr4, y: Expr5) extends Expr4 - object Add extends ParserBridge2[Expr4, Expr5, Add] - case class Sub(x: Expr4, y: Expr5) extends Expr4 - object Sub extends ParserBridge2[Expr4, Expr5, Sub] - case class Mul(x: Expr5, y: Expr6) extends Expr5 - object Mul extends ParserBridge2[Expr5, Expr6, Mul] - case class Div(x: Expr5, y: Expr6) extends Expr5 - object Div extends ParserBridge2[Expr5, Expr6, Div] - case class Mod(x: Expr5, y: Expr6) extends Expr5 - object Mod extends ParserBridge2[Expr5, Expr6, Mod] - case class Greater(x: Expr4, y: Expr4) extends Expr3 - object Greater extends ParserBridge2[Expr4, Expr4, Greater] - case class GreaterEq(x: Expr4, y: Expr4) extends Expr3 - object GreaterEq extends ParserBridge2[Expr4, Expr4, GreaterEq] - case class Less(x: Expr4, y: Expr4) extends Expr3 - object Less extends ParserBridge2[Expr4, Expr4, Less] - case class LessEq(x: Expr4, y: Expr4) extends Expr3 - object LessEq extends ParserBridge2[Expr4, Expr4, LessEq] - case class Eq(x: Expr3, y: Expr3) extends Expr2 - object Eq extends ParserBridge2[Expr3, Expr3, Eq] - case class Neq(x: Expr3, y: Expr3) extends Expr2 - object Neq extends ParserBridge2[Expr3, Expr3, Neq] - case class And(x: Expr2, y: Expr1) extends Expr1 - object And extends ParserBridge2[Expr2, Expr1, And] - case class Or(x: Expr1, y: Expr) extends Expr - object Or extends ParserBridge2[Expr1, Expr, Or] + sealed trait BinaryOp extends Expr { + val x: Expr + val y: Expr + } + case class Add(x: Expr4, y: Expr5)(pos: Position) extends Expr4 with BinaryOp + object Add extends ParserBridgePos2[Expr4, Expr5, Add] + case class Sub(x: Expr4, y: Expr5)(pos: Position) extends Expr4 with BinaryOp + object Sub extends ParserBridgePos2[Expr4, Expr5, Sub] + case class Mul(x: Expr5, y: Expr6)(pos: Position) extends Expr5 with BinaryOp + object Mul extends ParserBridgePos2[Expr5, Expr6, Mul] + case class Div(x: Expr5, y: Expr6)(pos: Position) extends Expr5 with BinaryOp + object Div extends ParserBridgePos2[Expr5, Expr6, Div] + case class Mod(x: Expr5, y: Expr6)(pos: Position) extends Expr5 with BinaryOp + object Mod extends ParserBridgePos2[Expr5, Expr6, Mod] + case class Greater(x: Expr4, y: Expr4)(pos: Position) extends Expr3 with BinaryOp + object Greater extends ParserBridgePos2[Expr4, Expr4, Greater] + case class GreaterEq(x: Expr4, y: Expr4)(pos: Position) extends Expr3 with BinaryOp + object GreaterEq extends ParserBridgePos2[Expr4, Expr4, GreaterEq] + case class Less(x: Expr4, y: Expr4)(pos: Position) extends Expr3 with BinaryOp + object Less extends ParserBridgePos2[Expr4, Expr4, Less] + case class LessEq(x: Expr4, y: Expr4)(pos: Position) extends Expr3 with BinaryOp + object LessEq extends ParserBridgePos2[Expr4, Expr4, LessEq] + case class Eq(x: Expr3, y: Expr3)(pos: Position) extends Expr2 with BinaryOp + object Eq extends ParserBridgePos2[Expr3, Expr3, Eq] + case class Neq(x: Expr3, y: Expr3)(pos: Position) extends Expr2 with BinaryOp + object Neq extends ParserBridgePos2[Expr3, Expr3, Neq] + case class And(x: Expr2, y: Expr1)(pos: Position) extends Expr1 with BinaryOp + object And extends ParserBridgePos2[Expr2, Expr1, And] + case class Or(x: Expr1, y: Expr)(pos: Position) extends Expr with BinaryOp + object Or extends ParserBridgePos2[Expr1, Expr, Or] // Types sealed trait Type sealed trait BaseType extends Type with PairElemType - case object IntType extends BaseType with ParserBridge0[IntType.type] - 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 - object ArrayType extends ParserBridge2[Type, Int, ArrayType] - case class PairType(fst: PairElemType, snd: PairElemType) extends Type - object PairType extends ParserBridge2[PairElemType, PairElemType, PairType] + case class IntType()(pos: Position) extends BaseType + object IntType extends ParserBridgePos0[IntType] + case class BoolType()(pos: Position) extends BaseType + object BoolType extends ParserBridgePos0[BoolType] + case class CharType()(pos: Position) extends BaseType + object CharType extends ParserBridgePos0[CharType] + case class StringType()(pos: Position) extends BaseType + object StringType extends ParserBridgePos0[StringType] + case class ArrayType(elemType: Type, dimensions: Int)(pos: Position) + extends Type + with PairElemType + object ArrayType extends ParserBridgePos2[Type, Int, ArrayType] + case class PairType(fst: PairElemType, snd: PairElemType)(pos: Position) extends Type + object PairType extends ParserBridgePos2[PairElemType, PairElemType, PairType] sealed trait PairElemType - case object UntypedPairType extends PairElemType with ParserBridge0[UntypedPairType.type] + case class UntypedPairType()(pos: Position) extends PairElemType + object UntypedPairType extends ParserBridgePos0[UntypedPairType] // waccadoodledo - case class Program(funcs: List[FuncDecl], main: NonEmptyList[Stmt]) - object Program extends ParserBridge2[List[FuncDecl], NonEmptyList[Stmt], Program] + case class Program(funcs: List[FuncDecl], main: NonEmptyList[Stmt])(pos: Position) + object Program extends ParserBridgePos2[List[FuncDecl], NonEmptyList[Stmt], Program] // Function Definitions case class FuncDecl( @@ -95,49 +115,115 @@ object ast { name: Ident, params: List[Param], body: NonEmptyList[Stmt] - ) - object FuncDecl extends ParserBridge4[Type, Ident, List[Param], NonEmptyList[Stmt], FuncDecl] + )(pos: Position) + object FuncDecl extends ParserBridgePos4[Type, Ident, List[Param], NonEmptyList[Stmt], FuncDecl] - case class Param(paramType: Type, name: Ident) - object Param extends ParserBridge2[Type, Ident, Param] + case class Param(paramType: Type, name: Ident)(pos: Position) + object Param extends ParserBridgePos2[Type, Ident, Param] // Statements sealed trait Stmt - case object Skip extends Stmt with ParserBridge0[Skip.type] - case class VarDecl(varType: Type, name: Ident, value: RValue) extends Stmt - object VarDecl extends ParserBridge3[Type, Ident, RValue, VarDecl] - case class Assign(lhs: LValue, value: RValue) extends Stmt - object Assign extends ParserBridge2[LValue, RValue, Assign] - case class Read(lhs: LValue) extends Stmt - object Read extends ParserBridge1[LValue, Read] - case class Free(expr: Expr) extends Stmt - object Free extends ParserBridge1[Expr, Free] - case class Return(expr: Expr) extends Stmt - object Return extends ParserBridge1[Expr, Return] - case class Exit(expr: Expr) extends Stmt - 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: 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] + case class Skip()(pos: Position) extends Stmt + object Skip extends ParserBridgePos0[Skip] + case class VarDecl(varType: Type, name: Ident, value: RValue)(pos: Position) extends Stmt + object VarDecl extends ParserBridgePos3[Type, Ident, RValue, VarDecl] + case class Assign(lhs: LValue, value: RValue)(pos: Position) extends Stmt + object Assign extends ParserBridgePos2[LValue, RValue, Assign] + case class Read(lhs: LValue)(pos: Position) extends Stmt + object Read extends ParserBridgePos1[LValue, Read] + case class Free(expr: Expr)(pos: Position) extends Stmt + object Free extends ParserBridgePos1[Expr, Free] + case class Return(expr: Expr)(pos: Position) extends Stmt + object Return extends ParserBridgePos1[Expr, Return] + case class Exit(expr: Expr)(pos: Position) extends Stmt + object Exit extends ParserBridgePos1[Expr, Exit] + case class Print(expr: Expr, newline: Boolean)(pos: Position) extends Stmt + object Print extends ParserBridgePos2[Expr, Boolean, Print] + case class If(cond: Expr, thenStmt: NonEmptyList[Stmt], elseStmt: NonEmptyList[Stmt])( + pos: Position + ) extends Stmt + object If extends ParserBridgePos3[Expr, NonEmptyList[Stmt], NonEmptyList[Stmt], If] + case class While(cond: Expr, body: NonEmptyList[Stmt])(pos: Position) extends Stmt + object While extends ParserBridgePos2[Expr, NonEmptyList[Stmt], While] + case class Block(stmt: NonEmptyList[Stmt])(pos: Position) extends Stmt + object Block extends ParserBridgePos1[NonEmptyList[Stmt], Block] sealed trait LValue sealed trait RValue - case class ArrayLiter(elems: List[Expr]) extends RValue - object ArrayLiter extends ParserBridge1[List[Expr], ArrayLiter] - case class NewPair(fst: Expr, snd: Expr) extends RValue - object NewPair extends ParserBridge2[Expr, Expr, NewPair] - case class Call(name: Ident, args: List[Expr]) extends RValue - object Call extends ParserBridge2[Ident, List[Expr], Call] + case class ArrayLiter(elems: List[Expr])(pos: Position) extends RValue + object ArrayLiter extends ParserBridgePos1[List[Expr], ArrayLiter] + case class NewPair(fst: Expr, snd: Expr)(pos: Position) extends RValue + object NewPair extends ParserBridgePos2[Expr, Expr, NewPair] + case class Call(name: Ident, args: List[Expr])(pos: Position) extends RValue + object Call extends ParserBridgePos2[Ident, List[Expr], Call] sealed trait PairElem extends LValue with RValue - case class Fst(elem: LValue) extends PairElem - object Fst extends ParserBridge1[LValue, Fst] - case class Snd(elem: LValue) extends PairElem - object Snd extends ParserBridge1[LValue, Snd] + case class Fst(elem: LValue)(pos: Position) extends PairElem + object Fst extends ParserBridgePos1[LValue, Fst] + case class Snd(elem: LValue)(pos: Position) extends PairElem + object Snd extends ParserBridgePos1[LValue, Snd] + + // Parser bridges + case class Position(line: Int, column: Int, offset: Int, width: Int) + + private def applyCon[A, B]( + con: ((Int, Int), Int, Int) => A => B + )(ops: Parsley[A]): Parsley[B] = + (pos, offset, withWidth(ops)).zipped.map { (pos, off, res) => + con(pos, off, res._2)(res._1) + } + + trait ParserSingletonBridgePos[+A] extends ErrorBridge { + protected def con(pos: (Int, Int), offset: Int, width: Int): A + def from(op: Parsley[?]): Parsley[A] = error((pos, offset, withWidth(op)).zipped.map { + (pos, off, res) => con(pos, off, res._2) + }) + final def <#(op: Parsley[?]): Parsley[A] = from(op) + } + + trait ParserBridgePos0[+A] extends ParserSingletonBridgePos[A] { + def apply()(pos: Position): A + + override final def con(pos: (Int, Int), offset: Int, width: Int): A = + apply()(Position(pos._1, pos._2, offset, width)) + } + + trait ParserBridgePos1[-A, +B] extends ParserSingletonBridgePos[A => B] { + def apply(a: A)(pos: Position): B + def apply(a: Parsley[A]): Parsley[B] = error((pos, offset, withWidth(a)).zipped.map { + (pos, off, res) => con(pos, off, res._2)(res._1) + }) + + override final def con(pos: (Int, Int), offset: Int, width: Int): A => B = + apply(_)(Position(pos._1, pos._2, offset, width)) + } + + trait ParserBridgePos2[-A, -B, +C] extends ParserSingletonBridgePos[((A, B)) => C] { + def apply(a: A, b: B)(pos: Position): C + def apply(a: Parsley[A], b: Parsley[B]): Parsley[C] = error(applyCon(con)((a, b).zipped)) + + override final def con(pos: (Int, Int), offset: Int, width: Int): ((A, B)) => C = + apply(_, _)(Position(pos._1, pos._2, offset, width)) + } + + trait ParserBridgePos3[-A, -B, -C, +D] extends ParserSingletonBridgePos[((A, B, C)) => D] { + def apply(a: A, b: B, c: C)(pos: Position): D + def apply(a: Parsley[A], b: Parsley[B], c: Parsley[C]): Parsley[D] = error( + applyCon(con)((a, b, c).zipped) + ) + + override final def con(pos: (Int, Int), offset: Int, width: Int): ((A, B, C)) => D = + apply(_, _, _)(Position(pos._1, pos._2, offset, width)) + } + + trait ParserBridgePos4[-A, -B, -C, -D, +E] extends ParserSingletonBridgePos[((A, B, C, D)) => E] { + def apply(a: A, b: B, c: C, d: D)(pos: Position): E + def apply(a: Parsley[A], b: Parsley[B], c: Parsley[C], d: Parsley[D]): Parsley[E] = error( + applyCon(con)((a, b, c, d).zipped) + ) + + override final def con(pos: (Int, Int), offset: Int, width: Int): ((A, B, C, D)) => E = + apply(_, _, _, _)(Position(pos._1, pos._2, offset, width)) + } } From 5fffd01a6f4cc74dc7d463de084d1ad684be1033 Mon Sep 17 00:00:00 2001 From: Gleb Koval Date: Wed, 5 Feb 2025 04:47:43 +0000 Subject: [PATCH 2/3] fix: make parser use only parsley parser bridge apply --- src/main/wacc/ast.scala | 76 ++++++++++++++++++++------------------ src/main/wacc/parser.scala | 22 +++++------ 2 files changed, 51 insertions(+), 47 deletions(-) diff --git a/src/main/wacc/ast.scala b/src/main/wacc/ast.scala index 9afd8d9..e4a9128 100644 --- a/src/main/wacc/ast.scala +++ b/src/main/wacc/ast.scala @@ -2,6 +2,7 @@ package wacc import parsley.Parsley import parsley.generic.ErrorBridge +import parsley.ap._ import parsley.position._ import parsley.syntax.zipped._ import cats.data.NonEmptyList @@ -32,7 +33,10 @@ object ast { case class ArrayElem(name: Ident, indices: NonEmptyList[Expr])(pos: Position) extends Expr6 with LValue - object ArrayElem extends ParserBridgePos2[Ident, NonEmptyList[Expr], ArrayElem] + object ArrayElem extends ParserBridgePos1[NonEmptyList[Expr], Ident => ArrayElem] { + def apply(a: NonEmptyList[Expr])(pos: Position): Ident => ArrayElem = + name => ArrayElem(name, a)(pos) + } case class Parens(expr: Expr)(pos: Position) extends Expr6 object Parens extends ParserBridgePos1[Expr, Parens] @@ -97,7 +101,9 @@ object ast { case class ArrayType(elemType: Type, dimensions: Int)(pos: Position) extends Type with PairElemType - object ArrayType extends ParserBridgePos2[Type, Int, ArrayType] + object ArrayType extends ParserBridgePos1[Int, Type => ArrayType] { + def apply(a: Int)(pos: Position): Type => ArrayType = elemType => ArrayType(elemType, a)(pos) + } case class PairType(fst: PairElemType, snd: PairElemType)(pos: Position) extends Type object PairType extends ParserBridgePos2[PairElemType, PairElemType, PairType] @@ -116,7 +122,17 @@ object ast { params: List[Param], body: NonEmptyList[Stmt] )(pos: Position) - object FuncDecl extends ParserBridgePos4[Type, Ident, List[Param], NonEmptyList[Stmt], FuncDecl] + object FuncDecl + extends ParserBridgePos2[ + List[Param], + NonEmptyList[Stmt], + ((Type, Ident)) => FuncDecl + ] { + def apply(params: List[Param], body: NonEmptyList[Stmt])( + pos: Position + ): ((Type, Ident)) => FuncDecl = + (returnType, name) => FuncDecl(returnType, name, params, body)(pos) + } case class Param(paramType: Type, name: Ident)(pos: Position) object Param extends ParserBridgePos2[Type, Ident, Param] @@ -165,65 +181,53 @@ object ast { object Snd extends ParserBridgePos1[LValue, Snd] // Parser bridges - case class Position(line: Int, column: Int, offset: Int, width: Int) + case class Position(line: Int, column: Int, offset: Int) private def applyCon[A, B]( con: ((Int, Int), Int, Int) => A => B - )(ops: Parsley[A]): Parsley[B] = + )(ops: => Parsley[A]): Parsley[B] = (pos, offset, withWidth(ops)).zipped.map { (pos, off, res) => con(pos, off, res._2)(res._1) } trait ParserSingletonBridgePos[+A] extends ErrorBridge { - protected def con(pos: (Int, Int), offset: Int, width: Int): A - def from(op: Parsley[?]): Parsley[A] = error((pos, offset, withWidth(op)).zipped.map { - (pos, off, res) => con(pos, off, res._2) - }) - final def <#(op: Parsley[?]): Parsley[A] = from(op) + protected def con(pos: (Int, Int), offset: Int): A + infix def from(op: Parsley[?]): Parsley[A] = error((pos, offset).zipped(con) <~ op) + final def <#(op: Parsley[?]): Parsley[A] = this from op } trait ParserBridgePos0[+A] extends ParserSingletonBridgePos[A] { def apply()(pos: Position): A - override final def con(pos: (Int, Int), offset: Int, width: Int): A = - apply()(Position(pos._1, pos._2, offset, width)) + override final def con(pos: (Int, Int), offset: Int): A = + apply()(Position(pos._1, pos._2, offset)) } trait ParserBridgePos1[-A, +B] extends ParserSingletonBridgePos[A => B] { def apply(a: A)(pos: Position): B - def apply(a: Parsley[A]): Parsley[B] = error((pos, offset, withWidth(a)).zipped.map { - (pos, off, res) => con(pos, off, res._2)(res._1) - }) + def apply(a: Parsley[A]): Parsley[B] = error(ap1((pos, offset).zipped(con), a)) - override final def con(pos: (Int, Int), offset: Int, width: Int): A => B = - apply(_)(Position(pos._1, pos._2, offset, width)) + override final def con(pos: (Int, Int), offset: Int): A => B = + this.apply(_)(Position(pos._1, pos._2, offset)) } - trait ParserBridgePos2[-A, -B, +C] extends ParserSingletonBridgePos[((A, B)) => C] { + trait ParserBridgePos2[-A, -B, +C] extends ParserSingletonBridgePos[(A, B) => C] { def apply(a: A, b: B)(pos: Position): C - def apply(a: Parsley[A], b: Parsley[B]): Parsley[C] = error(applyCon(con)((a, b).zipped)) + def apply(a: Parsley[A], b: => Parsley[B]): Parsley[C] = error( + ap2((pos, offset).zipped(con), a, b) + ) - override final def con(pos: (Int, Int), offset: Int, width: Int): ((A, B)) => C = - apply(_, _)(Position(pos._1, pos._2, offset, width)) + override final def con(pos: (Int, Int), offset: Int): (A, B) => C = + apply(_, _)(Position(pos._1, pos._2, offset)) } - trait ParserBridgePos3[-A, -B, -C, +D] extends ParserSingletonBridgePos[((A, B, C)) => D] { + trait ParserBridgePos3[-A, -B, -C, +D] extends ParserSingletonBridgePos[(A, B, C) => D] { def apply(a: A, b: B, c: C)(pos: Position): D - def apply(a: Parsley[A], b: Parsley[B], c: Parsley[C]): Parsley[D] = error( - applyCon(con)((a, b, c).zipped) + def apply(a: Parsley[A], b: => Parsley[B], c: => Parsley[C]): Parsley[D] = error( + ap3((pos, offset).zipped(con), a, b, c) ) - override final def con(pos: (Int, Int), offset: Int, width: Int): ((A, B, C)) => D = - apply(_, _, _)(Position(pos._1, pos._2, offset, width)) - } - - trait ParserBridgePos4[-A, -B, -C, -D, +E] extends ParserSingletonBridgePos[((A, B, C, D)) => E] { - def apply(a: A, b: B, c: C, d: D)(pos: Position): E - def apply(a: Parsley[A], b: Parsley[B], c: Parsley[C], d: Parsley[D]): Parsley[E] = error( - applyCon(con)((a, b, c, d).zipped) - ) - - override final def con(pos: (Int, Int), offset: Int, width: Int): ((A, B, C, D)) => E = - apply(_, _, _, _)(Position(pos._1, pos._2, offset, width)) + override final def con(pos: (Int, Int), offset: Int): (A, B, C) => D = + apply(_, _, _)(Position(pos._1, pos._2, offset)) } } diff --git a/src/main/wacc/parser.scala b/src/main/wacc/parser.scala index 84ee093..c4e2a7f 100644 --- a/src/main/wacc/parser.scala +++ b/src/main/wacc/parser.scala @@ -53,10 +53,7 @@ object parser { private val `` = Ident(ident) private lazy val `` = `` <**> (`` identity) - private val `` = - some("[" ~> `` <~ "]") map { indices => - ArrayElem((_: Ident), indices) - } + private val `` = ArrayElem(some("[" ~> `` <~ "]")) // Types private lazy val ``: Parsley[Type] = @@ -64,7 +61,7 @@ object parser { private val `` = (IntType from "int") | (BoolType from "bool") | (CharType from "char") | (StringType from "string") private lazy val `` = - countSome("[" ~> "]") map { cnt => ArrayType((_: Type), cnt) } + ArrayType(countSome("[" ~> "]")) private val `` = "pair" private val ``: Parsley[PairType] = PairType( "(" ~> `` <~ ",", @@ -72,7 +69,9 @@ object parser { ) private lazy val `` = (`` <**> (`` identity)) | - `` ~> ((`` <**> ``) UntypedPairType) + ((UntypedPairType from ``) <**> + ((`` <**> ``) + .map(arr => (_: UntypedPairType) => arr) identity)) // Statements private lazy val `` = Program( @@ -80,11 +79,12 @@ object parser { `` <~ "end" ) private lazy val `` = - (sepBy(``, ",") <~ ")" <~ "is" <~> ``.guardAgainst { - case stmts if !stmts.isReturning => Seq("All functions must end in a returning statement") - } <~ "end") map { (params, stmt) => - (FuncDecl((_: Type), (_: Ident), params, stmt)).tupled - } + FuncDecl( + sepBy(``, ",") <~ ")" <~ "is", + ``.guardAgainst { + case stmts if !stmts.isReturning => Seq("All functions must end in a returning statement") + } <~ "end" + ) private lazy val `` = Param(``, ``) private lazy val ``: Parsley[NonEmptyList[Stmt]] = sepBy1(``, ";") From 539403fd36892c03fbe8b1e5165f8c81b6db7705 Mon Sep 17 00:00:00 2001 From: Gleb Koval Date: Wed, 5 Feb 2025 04:49:05 +0000 Subject: [PATCH 3/3] fix: remove unused applyCon from AST --- src/main/wacc/ast.scala | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/main/wacc/ast.scala b/src/main/wacc/ast.scala index e4a9128..0076006 100644 --- a/src/main/wacc/ast.scala +++ b/src/main/wacc/ast.scala @@ -183,13 +183,6 @@ object ast { // Parser bridges case class Position(line: Int, column: Int, offset: Int) - private def applyCon[A, B]( - con: ((Int, Int), Int, Int) => A => B - )(ops: => Parsley[A]): Parsley[B] = - (pos, offset, withWidth(ops)).zipped.map { (pos, off, res) => - con(pos, off, res._2)(res._1) - } - trait ParserSingletonBridgePos[+A] extends ErrorBridge { protected def con(pos: (Int, Int), offset: Int): A infix def from(op: Parsley[?]): Parsley[A] = error((pos, offset).zipped(con) <~ op)