//
// Copyright (c) 2006, Brian Frank and Andy Frank
// Licensed under the Academic Free License version 3.0
//
// History:
// 26 Dec 05 Brian Frank Creation
// 20 Aug 06 Brian Frank Ported from Java to Fan
//
**
** FCodePrinter prints a human readable syntax for fcode
**
class FCodePrinter : FConst
{
//////////////////////////////////////////////////////////////////////////
// Constructor
//////////////////////////////////////////////////////////////////////////
new make(FPod pod, OutStream out := Env.cur.out)
{
this.pod = pod
this.out = out
}
//////////////////////////////////////////////////////////////////////////
// Print
//////////////////////////////////////////////////////////////////////////
Void code(Buf buf)
{
try
{
this.buf = buf.seek(0)
while (true)
{
op := buf.read
if (op == null) break
this.op(FOp.vals[op])
}
}
catch (Err e)
{
e.trace
}
out.flush
this.buf = null
}
Void op(FOp op)
{
print(" " + buf.pos.minus(1).toStr.justr(3) + ": " + op.name.justl(19) + " ")
if (op == FOp.Switch) printSwitch
else switch (op.arg)
{
case FOpArg.None: print
case FOpArg.Int: i := buf.readU2; print(pod.integer(i).toStr + index(i))
case FOpArg.Float: i := buf.readU2; print(pod.float(i).toStr + index(i))
case FOpArg.Decimal: i := buf.readU2; print(pod.decimal(i).toStr + index(i))
case FOpArg.Str: i := buf.readU2; print(pod.str(i).toStr + index(i))
case FOpArg.Duration: i := buf.readU2; print(pod.duration(i).toStr + index(i))
case FOpArg.Uri: i := buf.readU2; print(pod.uri(i).toStr + index(i))
case FOpArg.Register: i := buf.readU2; print(i)
case FOpArg.TypeRef: i := buf.readU2; print(pod.typeRefStr(i) + index(i))
case FOpArg.FieldRef: i := buf.readU2; print(pod.fieldRefStr(i) + index(i))
case FOpArg.MethodRef: i := buf.readU2; print(pod.methodRefStr(i) + index(i))
case FOpArg.Jump: i := buf.readU2; print(i)
case FOpArg.TypePair:
i1 := buf.readU2
i2 := buf.readU2
print(pod.typeRefStr(i1) + index(i1))
if (op == FOp.Coerce) print(" => "); else print(" <=> ")
print(pod.typeRefStr(i2) + index(i2))
default: throw Err(op.arg.toStr)
}
printLine
}
Void printSwitch()
{
buf.readU2.times |Int i|
{
printLine
print(" " + i + " -> " + buf.readU2)
}
}
//////////////////////////////////////////////////////////////////////////
// Print
//////////////////////////////////////////////////////////////////////////
Str index(Int index)
{
if (showIndex) return "[" + index + "]"
return ""
}
FCodePrinter print(Obj obj := "") { out.print(obj); return this }
FCodePrinter printLine(Obj obj := "") { out.printLine(obj); return this }
//////////////////////////////////////////////////////////////////////////
// Fields
//////////////////////////////////////////////////////////////////////////
FPod pod
OutStream out
Bool showIndex
Buf? buf
}