Skip to content

Commit

Permalink
adding translation for if-then-else, some code hoisting for clarity (#…
Browse files Browse the repository at this point in the history
…315)

* adding translation for if-then-else, some code hoisting for clarity

* adding test case and config for it, so it'll run in travis

* ide scraps

* polish on PR per discussion with @mcoblenz on #315
  • Loading branch information
ivoysey committed Apr 6, 2021
1 parent 8de0b51 commit 2fc00da
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 7 deletions.
1 change: 1 addition & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .idea/scala_compiler.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions resources/tests/GanacheTests/IfThenElse.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"gas" : 30000000,
"gasprice" : "0x9184e72a000",
"startingeth" : 5000000,
"numaccts" : 1
}
11 changes: 11 additions & 0 deletions resources/tests/GanacheTests/IfThenElse.obs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
main contract IfThenElse {
int x;
transaction ifthenelse() {
if (true) {
x = 1;
} else {
x = 0;
}
return;
}
}
30 changes: 24 additions & 6 deletions src/main/scala/edu/cmu/cs/obsidian/codegen/CodeGenYul.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import edu.cmu.cs.obsidian.CompilerOptions
import edu.cmu.cs.obsidian.parser._
import edu.cmu.cs.obsidian.Main.{findMainContract, findMainContractName}
import edu.cmu.cs.obsidian.typecheck.ContractType
import edu.cmu.cs.obsidian.codegen.Switch

import scala.collection.immutable.Map

Expand All @@ -18,6 +19,10 @@ object CodeGenYul extends CodeGenerator {
var stateEnumMapping: Map[String, Int] = Map() // map from state name to an enum value
var stateEnumCounter = 0 // counter indicating the next value to assign since we don't knon the total num of states

// some constants hoisted from below to avoid repeated code
val true_lit : Literal = Literal(LiteralKind.boolean, "true", "bool")
val false_lit : Literal = Literal(LiteralKind.boolean, "false", "bool")

def gen(filename: String, srcDir: Path, outputPath: Path, protoDir: Path,
options: CompilerOptions, checkedTable: SymbolTable, transformedTable: SymbolTable): Boolean = {
// extract ast and find main contract
Expand Down Expand Up @@ -250,11 +255,24 @@ object CodeGenYul extends CodeGenerator {
assert(false, "TODO")
Seq()
}

case _ =>
assert(false, "TODO")
case IfThenElse(scrutinee,pos,neg) =>
val scrutinee_yul : Seq[YulStatement] = translateExpr(scrutinee)
if (scrutinee_yul.length > 1){
assert(false,"boolean expression in conditional translates to a sequence of expressons")
Seq()
}
scrutinee_yul.apply(0) match {
case ExpressionStatement(sye) =>
val pos_yul = pos.flatMap(translateStatement)
val neg_yul = neg.flatMap(translateStatement)
Seq(Switch(sye,Seq(Case(true_lit , Block(pos_yul)), Case(false_lit, Block(neg_yul)))))
case e =>
assert(false, "if statement built on non-expression: " + e.toString())
Seq()
}
case x =>
assert(false, "TODO: translateStatement for " + x.toString() + " is unimplemented")
Seq()

}
}

Expand All @@ -268,9 +286,9 @@ object CodeGenYul extends CodeGenerator {
// we compile to int, which is s256 in yul
Seq(ExpressionStatement(Literal(LiteralKind.number,n.toString(),"int")))
case TrueLiteral() =>
Seq(ExpressionStatement(Literal(LiteralKind.boolean, "true", "bool")))
Seq(ExpressionStatement(true_lit))
case FalseLiteral() =>
Seq(ExpressionStatement(Literal(LiteralKind.boolean, "false", "bool")))
Seq(ExpressionStatement(false_lit))
case _ =>
assert(false, "TODO: translation of " + e.toString() + " is not implemented")
Seq() // TODO unimplemented
Expand Down

0 comments on commit 2fc00da

Please sign in to comment.