I realized the difference between a RecType
and a RecValue
.
A RecType
is written:
[a->b|c->d]
A RecValue
is written:
[a:b,c:d]
object mmlangParser extends JavaTokenParsers { | |
override val whiteSpace:Regex = """[\s\n]+""".r | |
var model:Model = Model.id | |
// all mm-ADT languages must be able to accept a string representation of an expression in the language and return an Iterator[Obj] | |
def parse[T <: Obj](input:String,_model:Model = Model.id):Iterator[T] ={ | |
if (null != _model) this.model = _model | |
this.parseAll(expr | emptySpace,input.trim).map{ | |
case itty:Iterator[T] => itty |
// Removed the => evaluate operator. | |
// BEFORE 1 => +2 | |
// NOW 1 + 2 | |
// Evaluation is determined by juxtaposition (reading left to right). | |
// value type (equiv value => type (execution)) | |
// type type (equiv type => type (compilation)) | |
mmlang> 1 | |
==>1 | |
mmlang> +2 |
~/software/mm-adt/vm/jvm bin/mmadt.sh | |
_____ _______ | |
/\ | __ |__ __| | |
_ __ ___ _ __ ___ _____ / \ | | | | | | | |
| '_ ` _ \| '_ ` _ |_____/ /\ \| | | | | | | |
| | | | | | | | | | | / ____ \ |__| | | | | |
|_| |_| |_|_| |_| |_| /_/ \_\____/ |_| | |
mm-adt.org | |
mmlang> true ==> int[plus,[plus,2][mult,7]]<x>[mult,[plus,5]<y>[mult,[plus,<y>]]][is,[gt,<x>]<z>[id]][plus,5][explain] |
object TypeUtil { | |
private type Row = (Int,Inst,OType,OType,Map[String,Obj]) | |
def explain(atype:OType,depth:Int = 0):List[Row] ={ | |
val report = atype.insts().foldLeft(List[Row]())((a,b) => { | |
val temp = a :+ (depth,b._2,b._1.domain(),b._2.apply(b._1).asInstanceOf[OType].range(),Map.empty[String,Obj]) | |
val inner = b._2.args().foldLeft(List[Row]())((x,y) => x ++ (y match { | |
case btype:OType => explain(btype,depth + 1) | |
case _ => Nil | |
})) | |
temp ++ inner |
class IteratorProcessor[S <: Obj,E <: Obj] extends Processor[S,E] { | |
override def apply(domainObj:S,rangeType:TType[E]):Iterator[Traverser[E]] ={ | |
var output:Iterator[Traverser[E]] = domainObj match { | |
case strm:Strm[_] => strm.value().map(x => new I1Traverser[E](x.asInstanceOf[E])) | |
case single:E => Iterator(new I1Traverser[E](single)) | |
} | |
for (tt <- InstUtil.createInstList(Nil,rangeType)) { | |
output = tt._2 match { | |
case _:ReduceInstruction => Iterator(output.map(_.obj()).foldLeft(int(0))((a,b) => a.plus(b.count().asInstanceOf[IntValue])).asInstanceOf[E]).map(x => new I1Traverser[E](x)) // REDUCE INSTRUCTIONS FOLD THEN SPLIT THE TRAVERSER TO ONE |
mmlang> int[plus,2][[is>5] -> true | [is==1] -> [plus,2] | int -> 20 ] | |
==>obj<=int[plus,2][choose,[[is,[gt,5]]->true|[is,[eq,1]]->[plus,2]|int->20]] | |
mmlang> 5 => [plus,2][[is>5] -> true / | |
......> |[is==1] -> [plus,2] / | |
......> |int -> 20 ] | |
==>true |
I realized the difference between a RecType
and a RecValue
.
A RecType
is written:
[a->b|c->d]
A RecValue
is written:
[a:b,c:d]
test("[choose] parsing"){ | |
val chooseInst:Obj = int.plus(int(2)).choose(rec(int.is(int.gt(int(10))) -> int.gt(int(20)),int -> int.plus(int(10)))) | |
assertResult(chooseInst)(parser.parse[IntType]("int[plus,2][choose,[int[is,int[gt,10]]:int[gt,20],int:int[plus,10]]]")) | |
assertResult(chooseInst)(parser.parse[IntType]("int[plus,2][choose,[int[is,int[gt,10]]->int[gt,20] | int->int[plus,10]]]")) | |
assertResult(chooseInst)(parser.parse[IntType]("int[plus,2][int[is,int[gt,10]]->int[gt,20] | int->int[plus,10]]")) | |
assertResult(chooseInst)(parser.parse[IntType]( | |
""" | |
| int[plus,2] | |
| [int[is,int[gt,10]] -> int[gt,20] | |
| |int -> int[plus,10]]""".stripMargin)) |
object mmLangParser extends JavaTokenParsers { | |
def op:Parser[String] = """[a-z]+""".r | |
def expr:Parser[OType] = canonicalType ~ inst ^^ (x => x._1.asInstanceOf[IntType].plus(x._2.arg[IntValue]())) | |
def intValue:Parser[IntValue] = """[0-9]+""".r ^^ (x => int(x.toLong)) | |
def canonicalType:Parser[OType] = (Tokens.int | Tokens.str) ^^ ({ | |
case Tokens.int => int | |
case Tokens.str => str | |
}) | |
def inst:Parser[Inst] = "[" ~ op ~ "," ~ intValue ~ "]" ^^ (x => PlusOp(x._1._2)) |