Code has been added to clipboard!

Solidity Assembly Opcode Example

Example
codegen item: AST -> opcode_stream =
match item {
Block({ items }) ->
  join(codegen(item) for item in items)
  if last generated opcode has continuing control flow:
    POP for all local variables registered at the block (including variables
    introduced by labels)
    warning issued in case the stack height here is not similar to 
    the beginning of the block
Identifier(id) ->
  id is looked up in the syntactic block stack
  the type of id is matched
    Local Variable ->
      DUPi where dif = 1 + stackHeight - stackHeightOfIdentifier(id)
    Label ->
      // reference that will be resolved when the bytecode generation happens
      PUSH< label's bytecode position>
    SubAssembly ->
      PUSH<subassembly data's bytecode position>
FunctionalAssemblyExpression(id ( arguments ) ) ->
  join(codegen(arg) for arguments in arguments.reversed())
  id (which must be an opcode, later on may be a function name)
LocalDefinition(let (id1, ..., idn) := expr) ->
  identifiers id1, ..., idn are registered as locals inside current block at the present stack height
  codegen(expr) - it is asserted that expr would return n items to the stack
FunctionalAssignment((id1, ..., idn) := expr) ->
  id1, ..., idn are looked up in the syntactic block stack, it is asserted that they are variables
  codegen(expr)
  for j = n, ..., dif:
  SWAPi where dif = 1 + stackHeight - stackHeightOfIdentifier(idj)
  POP
Assignment(=: id) ->
  id is looked up in the syntactic block stack, it is asserted that it is a variable
  SWAPi where dif = 1 + stackHeight - stackHeightOfIdentifier(id)
  POP
LabelDefinition(name:) ->
  JUMPDEST
NumberLiteral(num) ->
  PUSH<num interpreted as right-aligned and decimal>
LiteralHex(lit) ->
  PUSH32<lit interpreted as left-aligned and hex>
LiteralString(lit) ->
  PUSH32<lit left-aligned and utf-8 encoded>
SubAssembly(assembly <name> block) ->
  codegen(block) is appended at code's end
dataSize(<name>) ->
  it is asserted that <name> is a subassembly ->
  PUSH32<size of code generated from subassembly <name>>
linkerSymbol(<lit>) ->
  PUSH32<zeros> and append position to linker table
}