Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: IR change to support int of arbitrary length #62

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added examples/cache-call.pdl
Empty file.
46 changes: 46 additions & 0 deletions examples/test.pdl
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
pipe cache(addr: uint<5>, data: int<32>)[dmem: int<32>[5]<a,a>(Queue)]: bool {
//spec_check();
start(dmem);
int<32> sdata <- dmem<a>[addr];
//checkpoint(dmem);
reserve(dmem[addr], W); //stupid to put here, but doing it just for the sake of things
end(dmem);
---
//spec_check();
wdata = data + sdata;
block(dmem[addr]);
dmem[addr] <- wdata;
release(dmem[addr]);
print("ADDR: %d, DATA: %h", addr, wdata);
---
//spec_check();
output(true);
}

pipe cpu(pc: int<32>)[cache1: cache, imem: int<32>[16]<a,a>]: bool {
start(imem);
int<32> insn <- imem[cast(pc, uint<16>)];
end(imem);

call cpu(pc + 1);

start(cache1);
reserve(cache1);
end(cache1);
---
uint<5> addr = cast(insn{36:32}, uint<5>);

block(cache1);
cs <- call cache1(addr, 1<32>);
release(cache1);
---
nextPc = (addr{0:0} == 0) ? pc + 2 : pc + 1;
}
circuit {
ti = memory(int<32>, 16);
td = memory(int<32>, 5);
d = Queue(td);
s = new cache[d];
c = new cpu[s, ti];
call c(0<32>);
}
2 changes: 1 addition & 1 deletion src/main/scala/pipedsl/Interpreter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class Interpreter(val maxIterations: Int) {
}
interp_function(func, newEnv)
}
case ECall(id, name, args) => {
case ECall(id, name, args, _) => {
var newEnv = new immutable.HashMap[Id, Any]()
val moddef = modules(id)
for (index <- 0 until args.length) {
Expand Down
14 changes: 7 additions & 7 deletions src/main/scala/pipedsl/Parser.scala
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class Parser(rflockImpl: String) extends RegexParsers with PackratParsers {
lazy val stringVal: P[EString] =
"\"" ~> "[^\"]*".r <~ "\"" ^^ {n => EString(n)}

private def toInt(n: Int, base: Int, bits: Option[Int], isUnsigned: Boolean): EInt = {
private def toInt(n: String, base: Int, bits: Option[Int], isUnsigned: Boolean): EInt = {
val e = EInt(n, base, if (bits.isDefined) bits.get else -1)
e.typ = bits match {
case Some(b) => Some(TSizedInt(TBitWidthLen(b), SignFactory.ofBool(!isUnsigned)))
Expand All @@ -87,16 +87,16 @@ class Parser(rflockImpl: String) extends RegexParsers with PackratParsers {

// Atoms
lazy val dec: P[EInt] = positioned { "u".? ~ "-?[0-9]+".r ~ angular(posint).? ^^ {
case u ~ n ~ bits => toInt(n.toInt, 10, bits, u.isDefined)
case u ~ n ~ bits => toInt(n, 10, bits, u.isDefined)
}}
lazy val hex: P[EInt] = positioned { "u".? ~ "0x-?[0-9a-fA-F]+".r ~ angular(posint).? ^^ {
case u ~ n ~ bits => toInt(Integer.parseInt(n.substring(2), 16), 16, bits, u.isDefined)
case u ~ n ~ bits => toInt(n.substring(2), 16, bits, u.isDefined)
}}
lazy val octal: P[EInt] = positioned { "u".? ~ "0-?[0-7]+".r ~ angular(posint).? ^^ {
case u ~ n ~ bits => toInt(Integer.parseInt(n.substring(1), 8), 8, bits, u.isDefined)
case u ~ n ~ bits => toInt(n.substring(1), 8, bits, u.isDefined)
}}
lazy val binary: P[EInt] = positioned { "u".? ~ "0b-?[0-1]+".r ~ angular(posint).? ^^ {
case u ~ n ~ bits => toInt(Integer.parseInt(n.substring(2), 2), 2, bits, u.isDefined)
case u ~ n ~ bits => toInt(n.substring(2), 2, bits, u.isDefined)
}}

lazy val num: P[EInt] = binary | hex | octal | dec ^^
Expand Down Expand Up @@ -151,11 +151,11 @@ class Parser(rflockImpl: String) extends RegexParsers with PackratParsers {
}

lazy val methodCall: P[ECall] = positioned {
iden ~ "." ~ iden ~ parens(repsep(expr, ",")) ^^ { case i ~ _ ~ n ~ args => ECall(i, Some(n), args) }
angular("atomic" | "a").? ~ iden ~ "." ~ iden ~ parens(repsep(expr, ",")) ^^ { case a ~ i ~ _ ~ n ~ args => ECall(i, Some(n), args, a.isDefined) }
}

lazy val simpleAtom: P[Expr] = positioned {
"call" ~> iden ~ parens(repsep(expr, ",")) ^^ { case i ~ args => ECall(i, None, args) } |
"call" ~> angular("atomic" | "a").? ~ iden ~ parens(repsep(expr, ",")) ^^ { case a ~ i ~ args => ECall(i, None, args, a.isDefined) } |
not ~ simpleAtom ^^ { case n ~ e => EUop(n, e) } |
neg |
cast |
Expand Down
12 changes: 10 additions & 2 deletions src/main/scala/pipedsl/codegen/bsv/BSVSyntax.scala
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,15 @@ object BSVSyntax {
case TRequestHandle(n, rtyp) => rtyp match {
//These are passed in the modmap rather than the handle map
case pipedsl.common.Syntax.RequestType.Lock if !n.typ.get.isInstanceOf[TMemType] =>
if(n.typ.get.isInstanceOf[TModType]) {
n.typ.get match {
case TModType(_, _, _, Some(n)) => modmap(n)
case _ => throw UnexpectedType(t.pos, "Module type", "A Some(mod name) typ", t)
}
}
else {
modmap(n)
}
case pipedsl.common.Syntax.RequestType.Checkpoint =>
lockIdToCheckId(modmap(n))
//TODO allow this to be specified somewhere
Expand Down Expand Up @@ -156,7 +164,7 @@ object BSVSyntax {
}

def toExpr(e: Expr): BExpr = e match {
case EInt(v, base, bits) => BIntLit(v, base, bits)
case EInt(v, base, bits) => BIntLit(v.toInt, base, bits)
case EBool(v) => BBoolLit(v)
case EString(v) => BStringLit(v)
case eu@EUop(_, _) => translateUOp(eu)
Expand Down Expand Up @@ -191,7 +199,7 @@ object BSVSyntax {
case EInvalid => BInvalid
case EFromMaybe(ex) => BFromMaybe(BDontCare, toExpr(ex))
case EToMaybe(ex) => BTaggedValid(toExpr(ex))
case ECall(mod, method, args) if method.isDefined =>
case ECall(mod, method, args, isAtomic) if method.isDefined =>
//type doesn't matter on the var
BMethodInvoke(BVar(mod.v, BVoid), method.get.v, args.map(a => toExpr(a)))
case _ => throw UnexpectedExpr(e)
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/pipedsl/codegen/bsv/BluespecGeneration.scala
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ object BluespecGeneration {
//TODO better for externs
val interface = if (modMap.contains(mod)) bsInts.getInterface(modMap(mod)) else extMap(mod)
val modName = if (modMap.contains(mod)) bsInts.getModuleName(modMap(mod)) else "mk" + mod.v
val szParams = params.map(p => BUnsizedInt(p.v))
val szParams = params.map(p => BUnsizedInt(p.v.toInt))
(interface, BModule(name = modName, args = mods.map(m => env(m)) ++ szParams))
case CirCall(_, _) => throw UnexpectedExpr(c)
}
Expand Down Expand Up @@ -719,7 +719,7 @@ object BluespecGeneration {
case EApp(_, args) => args.foldLeft(List[BExpr]())((l, a) => {
l ++ getBlockConds(a)
})
case ECall(_, _, args) => args.foldLeft(List[BExpr]())((l, a) => {
case ECall(_, _, args, isAtomic) => args.foldLeft(List[BExpr]())((l, a) => {
l ++ getBlockConds(a)
})
case ECast(_, exp) => getBlockConds(exp)
Expand Down
12 changes: 6 additions & 6 deletions src/main/scala/pipedsl/common/DAGSyntax.scala
Original file line number Diff line number Diff line change
Expand Up @@ -242,17 +242,17 @@ object DAGSyntax {
val intSize = log2(defaultNum)
condVar.typ = Some(TSizedInt(TBitWidthLen(intSize), TUnsigned()))
condVar.id.typ = condVar.typ
var eTernary = ETernary(conds(defaultNum - 1), EInt(defaultNum - 1, bits = intSize), EInt(defaultNum, bits = intSize))
var eTernary = ETernary(conds(defaultNum - 1), EInt((defaultNum - 1).toString, bits = intSize), EInt(defaultNum.toString, bits = intSize))
for(i <- defaultNum-2 to 0 by -1 ) {
eTernary = ETernary(conds(i), EInt(i, bits = intSize), eTernary.copy())
eTernary = ETernary(conds(i), EInt(i.toString, bits = intSize), eTernary.copy())
}
this.addCmd(CAssign(condVar, eTernary))
for (i <- 0 until defaultNum) {
this.addEdgeTo(condStages(i).head, condSend = Some (EBinop(EqOp("=="), condVar, EInt(i, bits = intSize))))
condStages(i).last.addEdgeTo(joinStage, condRecv = Some (EBinop(EqOp("=="), condVar, EInt(i, bits = intSize))))
this.addEdgeTo(condStages(i).head, condSend = Some (EBinop(EqOp("=="), condVar, EInt(i.toString, bits = intSize))))
condStages(i).last.addEdgeTo(joinStage, condRecv = Some (EBinop(EqOp("=="), condVar, EInt(i.toString, bits = intSize))))
}
this.addEdgeTo(defaultStages.head, condSend = Some( EBinop(EqOp("=="), condVar, EInt(defaultNum, bits = intSize))))
defaultStages.last.addEdgeTo(joinStage, condRecv = Some( EBinop(EqOp("=="), condVar, EInt(defaultNum, bits = intSize))))
this.addEdgeTo(defaultStages.head, condSend = Some( EBinop(EqOp("=="), condVar, EInt(defaultNum.toString, bits = intSize))))
defaultStages.last.addEdgeTo(joinStage, condRecv = Some( EBinop(EqOp("=="), condVar, EInt(defaultNum.toString, bits = intSize))))
}

class PMemory(n: Id, t: TMemType) extends Process(n) {
Expand Down
3 changes: 3 additions & 0 deletions src/main/scala/pipedsl/common/Errors.scala
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ object Errors {
case class IllegalLockAcquisition(pos: Position) extends TypeError(
s"Cannot acquire or reserve locks inside multiple branches", pos)

case class RecursiveCallLockAcquisition(pos: Position) extends TypeError(
s"Cannot acquire or reserve locks for recursive calls", pos)

case class IllegalOOOLockRelease(pos: Position) extends TypeError(
s"Cannot release locks inside multiple branches", pos)

Expand Down
10 changes: 5 additions & 5 deletions src/main/scala/pipedsl/common/PrettyPrinter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,10 @@ class PrettyPrinter(output: Option[File]) {
def printExpr(e: Expr): Unit = pline(printExprToString(e))
def printExprToString(e: Expr): String = e match {
case Syntax.EInt(v, base, bits) => (base match {
case 2 => "0b" + v.toBinaryString
case 8 => "0" + v.toOctalString
case 10 => v.toString
case 16 => "0x" + v.toHexString
case 2 => "0b" + v
case 8 => "0" + v
case 10 => v
case 16 => "0x" + v
}) + "<" + bits.toString + ">"
case Syntax.EBool(v) => v.toString
case Syntax.EUop(op, ex) => op.op + "(" + printExprToString(ex) + ")"
Expand All @@ -131,7 +131,7 @@ class PrettyPrinter(output: Option[File]) {
case Syntax.EBitExtract(num, start, end) => printExprToString(num) + "{" + end.toString + ":" + start.toString + "}"
case Syntax.ETernary(cond, tval, fval) => printExprToString(cond) + " ? " + printExprToString(tval) + " : " + printExprToString(fval)
case Syntax.EApp(func, args) => func.v + "(" + args.map(a => printExprToString(a)).mkString(",") + ")"
case Syntax.ECall(id, name, args) => "call " + id + "(" + args.map(a => printExprToString(a)).mkString(",") + ")"
case Syntax.ECall(id, name, args, isAtomic) => "call" + (if(isAtomic) "<atomic> " else " ") + id + "(" + args.map(a => printExprToString(a)).mkString(",") + ")"
case Syntax.EVar(id) => id.v
case Syntax.ECast(ctyp, exp) => "cast(" + printExprToString(exp) + "," + printTypeToString(ctyp) + ")"
case expr: Syntax.CirExpr => expr match {
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/pipedsl/common/Syntax.scala
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ object Syntax {
case class EIsValid(ex: Expr) extends Expr
case class EFromMaybe(ex: Expr) extends Expr
case class EToMaybe(ex: Expr) extends Expr
case class EInt(v: Int, base: Int = 10, bits: Int = 32) extends Expr
case class EInt(v: String, base: Int = 10, bits: Int = 32) extends Expr
case class EString(v: String) extends Expr
case class EBool(v: Boolean) extends Expr
case class EUop(op: UOp, ex: Expr) extends Expr
Expand All @@ -444,7 +444,7 @@ object Syntax {
case class EBitExtract(num: Expr, start: Int, end: Int) extends Expr
case class ETernary(cond: Expr, tval: Expr, fval: Expr) extends Expr
case class EApp(func: Id, args: List[Expr]) extends Expr
case class ECall(mod: Id, method: Option[Id] = None, args: List[Expr]) extends Expr
case class ECall(mod: Id, method: Option[Id] = None, args: List[Expr], isAtomic: Boolean) extends Expr
case class EVar(id: Id) extends Expr
case class ECast(ctyp: Type, exp: Expr) extends Expr
{
Expand Down
16 changes: 8 additions & 8 deletions src/main/scala/pipedsl/common/Utilities.scala
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ object Utilities {
s ++ getUsedVars(a)
})
//functions are also externally defined
case ECall(id, _, args) => args.foldLeft[Set[Id]](Set[Id]())((s, a) => {
case ECall(id, _, args, _) => args.foldLeft[Set[Id]](Set[Id]())((s, a) => {
s ++ getUsedVars(a)
})
case EVar(id) => id.typ = e.typ; Set(id)
Expand Down Expand Up @@ -494,7 +494,7 @@ object Utilities {
{
case FError => e1 match
{
case EInt(v, _, _) => val sign: TSignedNess =
case EInt(v, _, bits) => val sign: TSignedNess =
e1.typ match {
case Some(TSizedInt(_, sign)) => sign match
{
Expand All @@ -504,18 +504,18 @@ object Utilities {
case Some(_) => TSigned()
case None => TSigned() //TODO error
}
e1.typ = Some(TSizedInt(TBitWidthLen(log2(v)), sign))
e1.typ = Some(TSizedInt(TBitWidthLen(bits), sign))
case _ => throw LackOfConstraints(e1)
}
case t => e1.typ = t.toOptionUnsafe
}
e1 match
{
case e@EInt(v, _, _) =>
case e@EInt(v, _, bits) =>
if(e.typ.isEmpty)
e.typ = Some(TSizedInt(TBitWidthLen(log2(v)), TSigned()))
e.typ = Some(TSizedInt(TBitWidthLen(bits), TSigned()))
e.copy(bits = e.typ.get.matchOrError(e.pos, "Int", "TSizedInt")
{case t :TSizedInt => t}.len.getLen).copyMeta(e)
{case t :TSizedInt => t}.len.getLen).copyMeta(e)
case e@EIsValid(ex) => e.copy(ex = typeMapExpr(ex, f_opt)).copyMeta(e)
case e@EFromMaybe(ex) => e.copy(ex = typeMapExpr(ex, f_opt)).copyMeta(e)
case e@EToMaybe(ex) => e.copy(ex = typeMapExpr(ex, f_opt)).copyMeta(e)
Expand All @@ -538,7 +538,7 @@ object Utilities {
fval = typeMapExpr(fval, f_opt)).copyMeta(e)
case e@EApp(func, args) =>
e.copy(func = typeMapId(func, f_opt), args = args.map(typeMapExpr(_, f_opt))).copyMeta(e)
case e@ECall(mod, _, args) =>
case e@ECall(mod, _, args, _) =>
e.copy(mod = typeMapId(mod, f_opt), args = args.map(typeMapExpr(_, f_opt))).copyMeta(e)
case e@EVar(id) =>
e.copy(id = typeMapId(id, f_opt)).copyMeta(e)
Expand Down Expand Up @@ -671,7 +671,7 @@ object Utilities {
case EBitExtract(num, _, _) => getMemReads(num)
case ETernary(cond, tval, fval) => getMemReads(cond) ++ getMemReads(tval) ++ getMemReads(fval)
case EApp(_, args) => args.foldLeft(List[EMemAccess]())((l, a) => l ++ getMemReads(a))
case ECall(_, _, args) => args.foldLeft(List[EMemAccess]())((l, a) => l ++ getMemReads(a))
case ECall(_, _, args, _) => args.foldLeft(List[EMemAccess]())((l, a) => l ++ getMemReads(a))
case ECast(_, exp) => getMemReads(exp)
case _ => List()
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/pipedsl/passes/CanonicalizePass.scala
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,8 @@ class CanonicalizePass() extends CommandPass[Command] with ModulePass[ModuleDef]
(ETernary(ncond, net, nef).setPos(e.pos), CSeq(CSeq(nc, nct).setPos(e.pos), ncf).setPos(e.pos))
case EApp(func, args) => val (nargs, nc) = extractCastVars(args)
(EApp(func, nargs).setPos(e.pos), nc)
case ECall(mod, name, args) => val (nargs, nc) = extractCastVars(args)
(ECall(mod, name, nargs).setPos(e.pos), nc)
case ECall(mod, name, args, isAtomic) => val (nargs, nc) = extractCastVars(args)
(ECall(mod, name, nargs, isAtomic).setPos(e.pos), nc)
case ECast(ctyp, e) => val (ne, nc) = extractCastVars(e)
val ncast = ECast(ctyp, ne)
ncast.typ = Some(ctyp)
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/pipedsl/passes/ConvertAsyncPass.scala
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ class ConvertAsyncPass(modName: Id) extends StagePass[List[PStage]] {
case _ => throw UnexpectedType(mem.pos, "Memory Write Statement", "Memory Type", mem.typ.get)
}
//module calls
case (lhs@EVar(_), call@ECall(_, _, _)) =>
case (lhs@EVar(_), call@ECall(_, _, _, _)) =>
val send = convertCall(call)
val recv = IRecv(send.handle, send.receiver, lhs)
(send, recv)
Expand Down Expand Up @@ -133,7 +133,7 @@ class ConvertAsyncPass(modName: Id) extends StagePass[List[PStage]] {
private def getCalls(stg: PStage): List[ECall] = {
stg.getCmds.foldLeft(List[ECall]())((l, c) => {
c match {
case CExpr(call@ECall(_,_,_)) => l :+ call
case CExpr(call@ECall(_,_,_,_)) => l :+ call
case _ => l
}
})
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/pipedsl/passes/LockOpTranslationPass.scala
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,9 @@ object LockOpTranslationPass extends ProgPass[Prog] with CommandPass[Command] wi
val newapp = EApp(f, newargs).setPos(ea.pos)
newapp.typ = ea.typ
newapp
case ec@ECall(p, name, args) =>
case ec@ECall(p, name, args, isAtomic) =>
val newargs = args.foldLeft(List[Expr]())((args, a) => args :+ modifyMemArg(a, isLhs))
val newcall = ECall(p, name, newargs).setPos(ec.pos)
val newcall = ECall(p, name, newargs, isAtomic).setPos(ec.pos)
newcall.typ = ec.typ
newcall
case eb@EBinop(o, e1, e2) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ object MarkNonRecursiveModulePass extends ModulePass[ModuleDef] with ProgPass[Pr
//no other subexpressions - the Timing Type Checker ensures this
@tailrec
private def hasRecCall(e: Expr, m: Id): Boolean = e match {
case ECall(mod, _, _) => mod == m
case ECall(mod, _, _, _) => mod == m
case ECast(_, exp) => hasRecCall(exp, m)
case _ => false
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/pipedsl/passes/RemoveTimingPass.scala
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,15 @@ object RemoveTimingPass extends CommandPass[Command] with ModulePass[ModuleDef]
newCases :+ cases(index).copy(body = newBody)
}
CSplit(newCases, newDefault)
case CExpr(ECall(id, _, args)) =>
case CExpr(ECall(id, _, args, isAtomic)) =>
val assigns: ListBuffer[Command] = new ListBuffer[Command]()
val newArgs: ListBuffer[Expr] = new ListBuffer[Expr]()
for (index <- args.indices) {
val arg = EVar(Id("__" + id.v + "__" + calls.length + index))
assigns.addOne(CAssign(arg, args(index)))
newArgs.addOne(arg)
}
calls.addOne(CExpr(ECall(id, None, newArgs.toList)))
calls.addOne(CExpr(ECall(id, None, newArgs.toList, isAtomic)))
convertCListToCSeq(assigns, 0)
case _ => c
}
Expand Down
8 changes: 4 additions & 4 deletions src/main/scala/pipedsl/passes/SimplifyRecvPass.scala
Original file line number Diff line number Diff line change
Expand Up @@ -85,24 +85,24 @@ object SimplifyRecvPass extends CommandPass[Command] with ModulePass[ModuleDef]
CRecv(access, rhsAssgn.lhs).setPos(c.pos))
.setPos(c.pos))
.setPos(c.pos)
case (EVar(_), ECall(id, name, args)) =>
case (EVar(_), ECall(id, name, args, isAtomic)) =>
//TODO cleanup and stop copying code
val argAssgns = args.foldLeft[(Command, List[Expr])]((CEmpty(), List()))((cs, a) => {
val argAssn = CAssign(newVar("carg", a.pos, a.typ), a).setPos(a.pos)
(CSeq(cs._1, argAssn).setPos(a.pos), cs._2 :+ argAssn.lhs)
})
CSeq(argAssgns._1, CRecv(lhs, ECall(id, name, argAssgns._2).setPos(c.pos)).setPos(c.pos)).setPos(c.pos)
CSeq(argAssgns._1, CRecv(lhs, ECall(id, name, argAssgns._2, isAtomic).setPos(c.pos)).setPos(c.pos)).setPos(c.pos)
case (l@EVar(_), _) =>
CAssign(l, rhs).setPos(c.pos)
case _ => throw UnexpectedCase(c.pos)
}
//calls also get translated to send statements later
case CExpr(ECall(id, name, args)) =>
case CExpr(ECall(id, name, args, isAtomic)) =>
val argAssgns = args.foldLeft[(Command, List[Expr])]((CEmpty(), List()))((cs, a) => {
val argAssn = CAssign(newVar("carg", a.pos, a.typ), a).setPos(a.pos)
(CSeq(cs._1, argAssn).setPos(a.pos), cs._2 :+ argAssn.lhs)
})
CSeq(argAssgns._1, CExpr(ECall(id, name, argAssgns._2).setPos(c.pos)).setPos(c.pos)).setPos(c.pos)
CSeq(argAssgns._1, CExpr(ECall(id, name, argAssgns._2, isAtomic).setPos(c.pos)).setPos(c.pos)).setPos(c.pos)
case _ => c
}

Expand Down
Loading