8 //     amm fun_parser.sc defs.fun  | 
     8 //     amm fun_parser.sc defs.fun  | 
     9 //  | 
     9 //  | 
    10 // this will generate a parse-tree from a list  | 
    10 // this will generate a parse-tree from a list  | 
    11 // of tokens  | 
    11 // of tokens  | 
    12   | 
    12   | 
         | 
    13 //> using toolkit 0.5.0  | 
         | 
    14 // > using file fun_tokens.scala  | 
         | 
    15   | 
         | 
    16   | 
    13 import scala.language.implicitConversions      | 
    17 import scala.language.implicitConversions      | 
    14 import scala.language.reflectiveCalls  | 
    18 import scala.language.reflectiveCalls  | 
    15   | 
    19   | 
    16 import $file.fun_tokens, fun_tokens._   | 
    20   | 
         | 
    21 //import $file.fun_tokens, fun_tokens._   | 
    17   | 
    22   | 
    18   | 
    23   | 
    19 // Parser combinators  | 
    24 // Parser combinators  | 
    20 //    type parameter I needs to be of Seq-type  | 
    25 //    type parameter I needs to be of Seq-type  | 
    21 //  | 
    26 //  | 
    22 type IsSeq[I] = I => Seq[_]  | 
    27 type IsSeq[I] = I => Seq[?]  | 
    23   | 
    28   | 
    24 /*  | 
    29 /*  | 
    25 abstract class Parser[I, T](using is: I => Seq[_])  { | 
    30 abstract class Parser[I, T](using is: I => Seq[_])  { | 
    26   def parse(in: I): Set[(T, I)]    | 
    31   def parse(in: I): Set[(T, I)]    | 
    27   | 
    32   | 
    30         if is(tl).isEmpty) yield hd  | 
    35         if is(tl).isEmpty) yield hd  | 
    31 }  | 
    36 }  | 
    32 */  | 
    37 */  | 
    33   | 
    38   | 
    34   | 
    39   | 
    35 abstract class Parser[I, T](using is: I => Seq[_]) { | 
    40 abstract class Parser[I, T](using is: I => Seq[?]) { | 
    36   def parse(ts: I): Set[(T, I)]  | 
    41   def parse(ts: I): Set[(T, I)]  | 
    37   | 
    42   | 
    38   def parse_single(ts: I) : T =   | 
    43   def parse_single(ts: I) : T =   | 
    39     parse(ts).partition(p => is(p._2).isEmpty) match { | 
    44     parse(ts).partition(p => is(p._2).isEmpty) match { | 
    40       case (good, _) if !good.isEmpty => good.head._1  | 
    45       case (good, _) if !good.isEmpty => good.head._1  | 
    74   def ||(q : => Parser[I, T]) = new AltParser[I, T](p, q)  | 
    79   def ||(q : => Parser[I, T]) = new AltParser[I, T](p, q)  | 
    75   def ~[S] (q : => Parser[I, S]) = new SeqParser[I, T, S](p, q)  | 
    80   def ~[S] (q : => Parser[I, S]) = new SeqParser[I, T, S](p, q)  | 
    76   def map[S](f: => T => S) = new MapParser[I, T, S](p, f)  | 
    81   def map[S](f: => T => S) = new MapParser[I, T, S](p, f)  | 
    77 }  | 
    82 }  | 
    78   | 
    83   | 
    79 def ListParser[I, T, S](p: => Parser[I, T], q: => Parser[I, S])(using is: I => Seq[_]): Parser[I, List[T]] = { | 
    84 def ListParser[I, T, S](p: => Parser[I, T], q: => Parser[I, S])(using is: I => Seq[?]): Parser[I, List[T]] = { | 
    80   (p ~ q ~ ListParser(p, q)).map{ case (x:T) ~ (y:S) ~ (z:List[T]) => x :: z } || | 
    85   (p ~ q ~ ListParser(p, q)).map{ case (x:T) ~ (y:S) ~ (z:List[T]) => x :: z } || | 
    81   (p.map[List[T]]{s => List(s)}) | 
    86   (p.map[List[T]]{s => List(s)}) | 
    82 }  | 
    87 }  | 
    83   | 
    88   | 
    84 case class TokParser(tok: Token) extends Parser[List[Token], Token] { | 
    89 case class TokParser(tok: Token) extends Parser[List[Token], Token] { | 
   182   | 
   187   | 
   183 def parse_tks(tks: List[Token]) : List[Decl] =   | 
   188 def parse_tks(tks: List[Token]) : List[Decl] =   | 
   184   Prog.parse_single(tks)  | 
   189   Prog.parse_single(tks)  | 
   185   | 
   190   | 
   186 //@doc("Parses a file.") | 
   191 //@doc("Parses a file.") | 
   187 @main  | 
   192 //@main  | 
   188 def main(fname: String) : Unit = { | 
   193 def main(fname: String) : Unit = { | 
   189   val tks = tokenise(os.read(os.pwd / fname))  | 
   194   val tks = tokenise(os.read(os.pwd / fname))  | 
   190   println(parse_tks(tks))  | 
   195   println(parse_tks(tks))  | 
   191 }  | 
   196 }  | 
   192   | 
   197   |