stehau
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
module AbSyn
|
||||
|
||||
(* These are the same types as in last week's assignment. *)
|
||||
|
||||
type VALUE = INT of int
|
||||
|
||||
type BINOP = BPLUS | BMINUS | BTIMES
|
||||
|
||||
type RANGEOP = RSUM | RPROD | RMAX | RARGMAX
|
||||
|
||||
type EXP =
|
||||
| CONSTANT of VALUE
|
||||
| VARIABLE of string
|
||||
| OPERATE of BINOP * EXP * EXP
|
||||
| LET_IN of string * EXP * EXP
|
||||
| OVER of RANGEOP * string * EXP * EXP * EXP
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FsLexYacc" Version="10.2.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<FsYacc Include="Parser.fsp">
|
||||
<OtherFlags>-v --module Parser</OtherFlags>
|
||||
</FsYacc>
|
||||
<FsLex Include="Lexer.fsl">
|
||||
<OtherFlags></OtherFlags>
|
||||
</FsLex>
|
||||
<Compile Include="AbSyn.fs" />
|
||||
<Compile Include="Parser.fs" />
|
||||
<Compile Include="Lexer.fs" />
|
||||
<Compile Include="Calculator.fsx" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,27 @@
|
||||
open System.Text
|
||||
open FSharp.Text.Lexing
|
||||
open FSharp.Text.Parsing
|
||||
|
||||
(* Both lex and parse a program. *)
|
||||
let parse (s : string) =
|
||||
Parser.Prog Lexer.Token
|
||||
<| LexBuffer<_>.FromBytes (Encoding.UTF8.GetBytes s)
|
||||
|
||||
(* Continually evaluate user expressions. *)
|
||||
let loop () =
|
||||
let mutable running = true
|
||||
while running do
|
||||
printf "Input an expression: "
|
||||
try
|
||||
let program = System.Console.ReadLine()
|
||||
if program = "exit"
|
||||
then
|
||||
running <- false
|
||||
else
|
||||
printfn "Parse result: %A" (parse program)
|
||||
with
|
||||
| Failure msg -> printfn "%s" msg
|
||||
| :? System.ArgumentNullException ->
|
||||
running <- false
|
||||
|
||||
loop ()
|
||||
@@ -0,0 +1,122 @@
|
||||
# 1 "Lexer.fsl"
|
||||
|
||||
module Lexer
|
||||
|
||||
open System
|
||||
open FSharp.Text.Lexing
|
||||
open System.Text
|
||||
|
||||
let keyword (s : string) =
|
||||
match s with
|
||||
| "let" -> Parser.LET
|
||||
| "in" -> Parser.IN
|
||||
| "sum" -> Parser.SUM
|
||||
| "prod" -> Parser.PROD
|
||||
| "max" -> Parser.MAX
|
||||
| "argmax" -> Parser.ARGMAX
|
||||
| "to" -> Parser.TO
|
||||
| "of" -> Parser.OF
|
||||
| _ -> Parser.VAR s
|
||||
|
||||
# 21 "Lexer.fs"
|
||||
let trans : uint16[] array =
|
||||
[|
|
||||
(* State 0 *)
|
||||
[|12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 1us; 1us; 12us; 12us; 1us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 1us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 4us; 5us; 9us; 7us; 12us; 8us; 12us; 12us; 2us; 3us; 3us; 3us; 3us; 3us; 3us; 3us; 3us; 3us; 12us; 12us; 12us; 6us; 12us; 12us; 12us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 12us; 12us; 12us; 12us; 12us; 12us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 12us; 11us; |];
|
||||
(* State 1 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 16us; 16us; 65535us; 65535us; 16us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 16us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 2 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 3 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 15us; 15us; 15us; 15us; 15us; 15us; 15us; 15us; 15us; 15us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 4 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 5 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 6 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 7 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 8 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 9 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 10 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 65535us; 65535us; 65535us; 65535us; 14us; 65535us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 11 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 12 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 13 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 65535us; 65535us; 65535us; 65535us; 14us; 65535us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 14 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 13us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 15 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 15us; 15us; 15us; 15us; 15us; 15us; 15us; 15us; 15us; 15us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 16 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 16us; 16us; 65535us; 65535us; 16us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 16us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
|]
|
||||
let actions : uint16[] = [|65535us; 0us; 1us; 1us; 2us; 3us; 4us; 5us; 6us; 7us; 8us; 9us; 10us; 8us; 65535us; 1us; 0us; |]
|
||||
let _fslex_tables = FSharp.Text.Lexing.AsciiTables.Create(trans,actions)
|
||||
let rec _fslex_dummy () = _fslex_dummy()
|
||||
// Rule Token
|
||||
and Token lexbuf =
|
||||
match _fslex_tables.Interpret(0,lexbuf) with
|
||||
| 0 -> (
|
||||
# 24 "Lexer.fsl"
|
||||
Token lexbuf
|
||||
# 68 "Lexer.fs"
|
||||
)
|
||||
| 1 -> (
|
||||
# 28 "Lexer.fsl"
|
||||
Parser.INT (int (Encoding.UTF8.GetString lexbuf.Lexeme))
|
||||
# 73 "Lexer.fs"
|
||||
)
|
||||
| 2 -> (
|
||||
# 31 "Lexer.fsl"
|
||||
Parser.LPAR
|
||||
# 78 "Lexer.fs"
|
||||
)
|
||||
| 3 -> (
|
||||
# 32 "Lexer.fsl"
|
||||
Parser.RPAR
|
||||
# 83 "Lexer.fs"
|
||||
)
|
||||
| 4 -> (
|
||||
# 33 "Lexer.fsl"
|
||||
Parser.EQ
|
||||
# 88 "Lexer.fs"
|
||||
)
|
||||
| 5 -> (
|
||||
# 34 "Lexer.fsl"
|
||||
Parser.PLUS
|
||||
# 93 "Lexer.fs"
|
||||
)
|
||||
| 6 -> (
|
||||
# 35 "Lexer.fsl"
|
||||
Parser.MINUS
|
||||
# 98 "Lexer.fs"
|
||||
)
|
||||
| 7 -> (
|
||||
# 36 "Lexer.fsl"
|
||||
Parser.TIMES
|
||||
# 103 "Lexer.fs"
|
||||
)
|
||||
| 8 -> (
|
||||
# 39 "Lexer.fsl"
|
||||
keyword (Encoding.UTF8.GetString lexbuf.Lexeme)
|
||||
# 108 "Lexer.fs"
|
||||
)
|
||||
| 9 -> (
|
||||
# 54 "Lexer.fsl"
|
||||
Parser.EOF
|
||||
# 113 "Lexer.fs"
|
||||
)
|
||||
| 10 -> (
|
||||
# 57 "Lexer.fsl"
|
||||
failwith "lexer error"
|
||||
# 118 "Lexer.fs"
|
||||
)
|
||||
| _ -> failwith "Token"
|
||||
|
||||
# 3000000 "Lexer.fs"
|
||||
@@ -0,0 +1,57 @@
|
||||
{
|
||||
module Lexer
|
||||
|
||||
open System
|
||||
open FSharp.Text.Lexing
|
||||
open System.Text
|
||||
|
||||
let keyword (s : string) =
|
||||
match s with
|
||||
| "let" -> Parser.LET
|
||||
| "in" -> Parser.IN
|
||||
| "sum" -> Parser.SUM
|
||||
| "prod" -> Parser.PROD
|
||||
| "max" -> Parser.MAX
|
||||
| "argmax" -> Parser.ARGMAX
|
||||
| "to" -> Parser.TO
|
||||
| "of" -> Parser.OF
|
||||
| _ -> Parser.VAR s
|
||||
}
|
||||
|
||||
rule Token = parse
|
||||
(* Skip whitespace. *)
|
||||
[' ' '\t' '\r' '\n' ]+
|
||||
{ Token lexbuf }
|
||||
|
||||
(* Integers. *)
|
||||
| '0' | ['1'-'9']['0'-'9']*
|
||||
{ Parser.INT (int (Encoding.UTF8.GetString lexbuf.Lexeme)) }
|
||||
|
||||
(* Symbols *)
|
||||
| '(' { Parser.LPAR }
|
||||
| ')' { Parser.RPAR }
|
||||
| '=' { Parser.EQ }
|
||||
| '+' { Parser.PLUS }
|
||||
| '-' { Parser.MINUS }
|
||||
| '*' { Parser.TIMES }
|
||||
|
||||
| ['a'-'z' 'A'-'Z'] (['a'-'z' 'A'-'Z' '_']|'_'['0'-'9'])*
|
||||
{ keyword (Encoding.UTF8.GetString lexbuf.Lexeme) }
|
||||
|
||||
(* FIXME: You should implement lexing for:
|
||||
(1) Variable names: may contain letters, digits and underscores,
|
||||
but it must start with one (or several) letters,
|
||||
and a digit must be preceeded by an underscore.
|
||||
(2) Keywords: 'let', 'in', 'sum', ...
|
||||
(3) Symbols: '=', '+', ...
|
||||
For (1) and (2), please change the regular expression above
|
||||
to be consistent with the rule defining variable names,
|
||||
and implement the keywords function.
|
||||
For (3), add the relevant regular expressions under 'Symbols'
|
||||
*)
|
||||
|
||||
(* Special end of file symbol. *)
|
||||
| eof { Parser.EOF }
|
||||
|
||||
(* We don't understand anything else. *)
|
||||
| _ { failwith "lexer error" }
|
||||
@@ -0,0 +1,7 @@
|
||||
.PHONY: all clean
|
||||
|
||||
all:
|
||||
dotnet build
|
||||
|
||||
clean:
|
||||
rm -rf bin obj Lexer.fs Parser.fs Parser.fsyacc.output Parser.fsi
|
||||
@@ -0,0 +1,357 @@
|
||||
// Implementation file for parser generated by fsyacc
|
||||
module Parser
|
||||
#nowarn "64";; // turn off warnings that type variables used in production annotations are instantiated to concrete type
|
||||
open FSharp.Text.Lexing
|
||||
open FSharp.Text.Parsing.ParseHelpers
|
||||
# 1 "Parser.fsp"
|
||||
|
||||
open FSharp.Text.Parsing
|
||||
|
||||
# 10 "Parser.fs"
|
||||
// This type is the type of tokens accepted by the parser
|
||||
type token =
|
||||
| SUM
|
||||
| PROD
|
||||
| MAX
|
||||
| ARGMAX
|
||||
| PLUS
|
||||
| MINUS
|
||||
| TIMES
|
||||
| LET
|
||||
| IN
|
||||
| TO
|
||||
| OF
|
||||
| EOF
|
||||
| LPAR
|
||||
| RPAR
|
||||
| EQ
|
||||
| VAR of (string)
|
||||
| INT of (int)
|
||||
// This type is used to give symbolic names to token indexes, useful for error messages
|
||||
type tokenId =
|
||||
| TOKEN_SUM
|
||||
| TOKEN_PROD
|
||||
| TOKEN_MAX
|
||||
| TOKEN_ARGMAX
|
||||
| TOKEN_PLUS
|
||||
| TOKEN_MINUS
|
||||
| TOKEN_TIMES
|
||||
| TOKEN_LET
|
||||
| TOKEN_IN
|
||||
| TOKEN_TO
|
||||
| TOKEN_OF
|
||||
| TOKEN_EOF
|
||||
| TOKEN_LPAR
|
||||
| TOKEN_RPAR
|
||||
| TOKEN_EQ
|
||||
| TOKEN_VAR
|
||||
| TOKEN_INT
|
||||
| TOKEN_end_of_input
|
||||
| TOKEN_error
|
||||
// This type is used to give symbolic names to token indexes, useful for error messages
|
||||
type nonTerminalId =
|
||||
| NONTERM__startProg
|
||||
| NONTERM_Prog
|
||||
| NONTERM_Exp
|
||||
|
||||
// This function maps tokens to integer indexes
|
||||
let tagOfToken (t:token) =
|
||||
match t with
|
||||
| SUM -> 0
|
||||
| PROD -> 1
|
||||
| MAX -> 2
|
||||
| ARGMAX -> 3
|
||||
| PLUS -> 4
|
||||
| MINUS -> 5
|
||||
| TIMES -> 6
|
||||
| LET -> 7
|
||||
| IN -> 8
|
||||
| TO -> 9
|
||||
| OF -> 10
|
||||
| EOF -> 11
|
||||
| LPAR -> 12
|
||||
| RPAR -> 13
|
||||
| EQ -> 14
|
||||
| VAR _ -> 15
|
||||
| INT _ -> 16
|
||||
|
||||
// This function maps integer indexes to symbolic token ids
|
||||
let tokenTagToTokenId (tokenIdx:int) =
|
||||
match tokenIdx with
|
||||
| 0 -> TOKEN_SUM
|
||||
| 1 -> TOKEN_PROD
|
||||
| 2 -> TOKEN_MAX
|
||||
| 3 -> TOKEN_ARGMAX
|
||||
| 4 -> TOKEN_PLUS
|
||||
| 5 -> TOKEN_MINUS
|
||||
| 6 -> TOKEN_TIMES
|
||||
| 7 -> TOKEN_LET
|
||||
| 8 -> TOKEN_IN
|
||||
| 9 -> TOKEN_TO
|
||||
| 10 -> TOKEN_OF
|
||||
| 11 -> TOKEN_EOF
|
||||
| 12 -> TOKEN_LPAR
|
||||
| 13 -> TOKEN_RPAR
|
||||
| 14 -> TOKEN_EQ
|
||||
| 15 -> TOKEN_VAR
|
||||
| 16 -> TOKEN_INT
|
||||
| 19 -> TOKEN_end_of_input
|
||||
| 17 -> TOKEN_error
|
||||
| _ -> failwith "tokenTagToTokenId: bad token"
|
||||
|
||||
/// This function maps production indexes returned in syntax errors to strings representing the non terminal that would be produced by that production
|
||||
let prodIdxToNonTerminal (prodIdx:int) =
|
||||
match prodIdx with
|
||||
| 0 -> NONTERM__startProg
|
||||
| 1 -> NONTERM_Prog
|
||||
| 2 -> NONTERM_Exp
|
||||
| 3 -> NONTERM_Exp
|
||||
| 4 -> NONTERM_Exp
|
||||
| 5 -> NONTERM_Exp
|
||||
| 6 -> NONTERM_Exp
|
||||
| 7 -> NONTERM_Exp
|
||||
| 8 -> NONTERM_Exp
|
||||
| 9 -> NONTERM_Exp
|
||||
| 10 -> NONTERM_Exp
|
||||
| 11 -> NONTERM_Exp
|
||||
| 12 -> NONTERM_Exp
|
||||
| _ -> failwith "prodIdxToNonTerminal: bad production index"
|
||||
|
||||
let _fsyacc_endOfInputTag = 19
|
||||
let _fsyacc_tagOfErrorTerminal = 17
|
||||
|
||||
// This function gets the name of a token as a string
|
||||
let token_to_string (t:token) =
|
||||
match t with
|
||||
| SUM -> "SUM"
|
||||
| PROD -> "PROD"
|
||||
| MAX -> "MAX"
|
||||
| ARGMAX -> "ARGMAX"
|
||||
| PLUS -> "PLUS"
|
||||
| MINUS -> "MINUS"
|
||||
| TIMES -> "TIMES"
|
||||
| LET -> "LET"
|
||||
| IN -> "IN"
|
||||
| TO -> "TO"
|
||||
| OF -> "OF"
|
||||
| EOF -> "EOF"
|
||||
| LPAR -> "LPAR"
|
||||
| RPAR -> "RPAR"
|
||||
| EQ -> "EQ"
|
||||
| VAR _ -> "VAR"
|
||||
| INT _ -> "INT"
|
||||
|
||||
// This function gets the data carried by a token as an object
|
||||
let _fsyacc_dataOfToken (t:token) =
|
||||
match t with
|
||||
| SUM -> (null : System.Object)
|
||||
| PROD -> (null : System.Object)
|
||||
| MAX -> (null : System.Object)
|
||||
| ARGMAX -> (null : System.Object)
|
||||
| PLUS -> (null : System.Object)
|
||||
| MINUS -> (null : System.Object)
|
||||
| TIMES -> (null : System.Object)
|
||||
| LET -> (null : System.Object)
|
||||
| IN -> (null : System.Object)
|
||||
| TO -> (null : System.Object)
|
||||
| OF -> (null : System.Object)
|
||||
| EOF -> (null : System.Object)
|
||||
| LPAR -> (null : System.Object)
|
||||
| RPAR -> (null : System.Object)
|
||||
| EQ -> (null : System.Object)
|
||||
| VAR _fsyacc_x -> Microsoft.FSharp.Core.Operators.box _fsyacc_x
|
||||
| INT _fsyacc_x -> Microsoft.FSharp.Core.Operators.box _fsyacc_x
|
||||
let _fsyacc_gotos = [| 0us; 65535us; 1us; 65535us; 0us; 1us; 19us; 65535us; 0us; 2us; 6us; 7us; 26us; 9us; 27us; 10us; 28us; 11us; 31us; 12us; 32us; 13us; 35us; 14us; 36us; 15us; 37us; 16us; 40us; 17us; 41us; 18us; 42us; 19us; 45us; 20us; 46us; 21us; 47us; 22us; 50us; 23us; 51us; 24us; 52us; 25us; |]
|
||||
let _fsyacc_sparseGotoTableRowOffsets = [|0us; 1us; 3us; |]
|
||||
let _fsyacc_stateToProdIdxsTableElements = [| 1us; 0us; 1us; 0us; 4us; 1us; 5us; 6us; 7us; 1us; 1us; 1us; 2us; 1us; 3us; 1us; 4us; 4us; 4us; 5us; 6us; 7us; 1us; 4us; 4us; 5us; 5us; 6us; 7us; 4us; 5us; 6us; 6us; 7us; 4us; 5us; 6us; 7us; 7us; 4us; 5us; 6us; 7us; 8us; 4us; 5us; 6us; 7us; 8us; 4us; 5us; 6us; 7us; 9us; 4us; 5us; 6us; 7us; 9us; 4us; 5us; 6us; 7us; 9us; 4us; 5us; 6us; 7us; 10us; 4us; 5us; 6us; 7us; 10us; 4us; 5us; 6us; 7us; 10us; 4us; 5us; 6us; 7us; 11us; 4us; 5us; 6us; 7us; 11us; 4us; 5us; 6us; 7us; 11us; 4us; 5us; 6us; 7us; 12us; 4us; 5us; 6us; 7us; 12us; 4us; 5us; 6us; 7us; 12us; 1us; 5us; 1us; 6us; 1us; 7us; 1us; 8us; 1us; 8us; 1us; 8us; 1us; 8us; 1us; 9us; 1us; 9us; 1us; 9us; 1us; 9us; 1us; 9us; 1us; 10us; 1us; 10us; 1us; 10us; 1us; 10us; 1us; 10us; 1us; 11us; 1us; 11us; 1us; 11us; 1us; 11us; 1us; 11us; 1us; 12us; 1us; 12us; 1us; 12us; 1us; 12us; 1us; 12us; |]
|
||||
let _fsyacc_stateToProdIdxsTableRowOffsets = [|0us; 2us; 4us; 9us; 11us; 13us; 15us; 17us; 22us; 24us; 29us; 34us; 39us; 44us; 49us; 54us; 59us; 64us; 69us; 74us; 79us; 84us; 89us; 94us; 99us; 104us; 109us; 111us; 113us; 115us; 117us; 119us; 121us; 123us; 125us; 127us; 129us; 131us; 133us; 135us; 137us; 139us; 141us; 143us; 145us; 147us; 149us; 151us; 153us; 155us; 157us; 159us; 161us; |]
|
||||
let _fsyacc_action_rows = 53
|
||||
let _fsyacc_actionTableElements = [|8us; 32768us; 0us; 33us; 1us; 38us; 2us; 43us; 3us; 48us; 7us; 29us; 12us; 6us; 15us; 5us; 16us; 4us; 0us; 49152us; 4us; 32768us; 4us; 26us; 5us; 27us; 6us; 28us; 11us; 3us; 0us; 16385us; 0us; 16386us; 0us; 16387us; 8us; 32768us; 0us; 33us; 1us; 38us; 2us; 43us; 3us; 48us; 7us; 29us; 12us; 6us; 15us; 5us; 16us; 4us; 4us; 32768us; 4us; 26us; 5us; 27us; 6us; 28us; 13us; 8us; 0us; 16388us; 0us; 16389us; 0us; 16390us; 2us; 16391us; 4us; 26us; 5us; 27us; 4us; 32768us; 4us; 26us; 5us; 27us; 6us; 28us; 8us; 32us; 3us; 16392us; 4us; 26us; 5us; 27us; 6us; 28us; 4us; 32768us; 4us; 26us; 5us; 27us; 6us; 28us; 9us; 36us; 4us; 32768us; 4us; 26us; 5us; 27us; 6us; 28us; 10us; 37us; 3us; 16393us; 4us; 26us; 5us; 27us; 6us; 28us; 4us; 32768us; 4us; 26us; 5us; 27us; 6us; 28us; 9us; 41us; 4us; 32768us; 4us; 26us; 5us; 27us; 6us; 28us; 10us; 42us; 3us; 16394us; 4us; 26us; 5us; 27us; 6us; 28us; 4us; 32768us; 4us; 26us; 5us; 27us; 6us; 28us; 9us; 46us; 4us; 32768us; 4us; 26us; 5us; 27us; 6us; 28us; 10us; 47us; 3us; 16395us; 4us; 26us; 5us; 27us; 6us; 28us; 4us; 32768us; 4us; 26us; 5us; 27us; 6us; 28us; 9us; 51us; 4us; 32768us; 4us; 26us; 5us; 27us; 6us; 28us; 10us; 52us; 3us; 16396us; 4us; 26us; 5us; 27us; 6us; 28us; 8us; 32768us; 0us; 33us; 1us; 38us; 2us; 43us; 3us; 48us; 7us; 29us; 12us; 6us; 15us; 5us; 16us; 4us; 8us; 32768us; 0us; 33us; 1us; 38us; 2us; 43us; 3us; 48us; 7us; 29us; 12us; 6us; 15us; 5us; 16us; 4us; 8us; 32768us; 0us; 33us; 1us; 38us; 2us; 43us; 3us; 48us; 7us; 29us; 12us; 6us; 15us; 5us; 16us; 4us; 1us; 32768us; 15us; 30us; 1us; 32768us; 14us; 31us; 8us; 32768us; 0us; 33us; 1us; 38us; 2us; 43us; 3us; 48us; 7us; 29us; 12us; 6us; 15us; 5us; 16us; 4us; 8us; 32768us; 0us; 33us; 1us; 38us; 2us; 43us; 3us; 48us; 7us; 29us; 12us; 6us; 15us; 5us; 16us; 4us; 1us; 32768us; 15us; 34us; 1us; 32768us; 14us; 35us; 8us; 32768us; 0us; 33us; 1us; 38us; 2us; 43us; 3us; 48us; 7us; 29us; 12us; 6us; 15us; 5us; 16us; 4us; 8us; 32768us; 0us; 33us; 1us; 38us; 2us; 43us; 3us; 48us; 7us; 29us; 12us; 6us; 15us; 5us; 16us; 4us; 8us; 32768us; 0us; 33us; 1us; 38us; 2us; 43us; 3us; 48us; 7us; 29us; 12us; 6us; 15us; 5us; 16us; 4us; 1us; 32768us; 15us; 39us; 1us; 32768us; 14us; 40us; 8us; 32768us; 0us; 33us; 1us; 38us; 2us; 43us; 3us; 48us; 7us; 29us; 12us; 6us; 15us; 5us; 16us; 4us; 8us; 32768us; 0us; 33us; 1us; 38us; 2us; 43us; 3us; 48us; 7us; 29us; 12us; 6us; 15us; 5us; 16us; 4us; 8us; 32768us; 0us; 33us; 1us; 38us; 2us; 43us; 3us; 48us; 7us; 29us; 12us; 6us; 15us; 5us; 16us; 4us; 1us; 32768us; 15us; 44us; 1us; 32768us; 14us; 45us; 8us; 32768us; 0us; 33us; 1us; 38us; 2us; 43us; 3us; 48us; 7us; 29us; 12us; 6us; 15us; 5us; 16us; 4us; 8us; 32768us; 0us; 33us; 1us; 38us; 2us; 43us; 3us; 48us; 7us; 29us; 12us; 6us; 15us; 5us; 16us; 4us; 8us; 32768us; 0us; 33us; 1us; 38us; 2us; 43us; 3us; 48us; 7us; 29us; 12us; 6us; 15us; 5us; 16us; 4us; 1us; 32768us; 15us; 49us; 1us; 32768us; 14us; 50us; 8us; 32768us; 0us; 33us; 1us; 38us; 2us; 43us; 3us; 48us; 7us; 29us; 12us; 6us; 15us; 5us; 16us; 4us; 8us; 32768us; 0us; 33us; 1us; 38us; 2us; 43us; 3us; 48us; 7us; 29us; 12us; 6us; 15us; 5us; 16us; 4us; 8us; 32768us; 0us; 33us; 1us; 38us; 2us; 43us; 3us; 48us; 7us; 29us; 12us; 6us; 15us; 5us; 16us; 4us; |]
|
||||
let _fsyacc_actionTableRowOffsets = [|0us; 9us; 10us; 15us; 16us; 17us; 18us; 27us; 32us; 33us; 34us; 35us; 38us; 43us; 47us; 52us; 57us; 61us; 66us; 71us; 75us; 80us; 85us; 89us; 94us; 99us; 103us; 112us; 121us; 130us; 132us; 134us; 143us; 152us; 154us; 156us; 165us; 174us; 183us; 185us; 187us; 196us; 205us; 214us; 216us; 218us; 227us; 236us; 245us; 247us; 249us; 258us; 267us; |]
|
||||
let _fsyacc_reductionSymbolCounts = [|1us; 2us; 1us; 1us; 3us; 3us; 3us; 3us; 6us; 8us; 8us; 8us; 8us; |]
|
||||
let _fsyacc_productionToNonTerminalTable = [|0us; 1us; 2us; 2us; 2us; 2us; 2us; 2us; 2us; 2us; 2us; 2us; 2us; |]
|
||||
let _fsyacc_immediateActions = [|65535us; 49152us; 65535us; 16385us; 16386us; 16387us; 65535us; 65535us; 16388us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]
|
||||
let _fsyacc_reductions () = [|
|
||||
# 175 "Parser.fs"
|
||||
(fun (parseState : FSharp.Text.Parsing.IParseState) ->
|
||||
let _1 = parseState.GetInput(1) :?> AbSyn.EXP in
|
||||
Microsoft.FSharp.Core.Operators.box
|
||||
(
|
||||
(
|
||||
raise (FSharp.Text.Parsing.Accept(Microsoft.FSharp.Core.Operators.box _1))
|
||||
)
|
||||
: 'gentype__startProg));
|
||||
# 184 "Parser.fs"
|
||||
(fun (parseState : FSharp.Text.Parsing.IParseState) ->
|
||||
let _1 = parseState.GetInput(1) :?> AbSyn.EXP in
|
||||
Microsoft.FSharp.Core.Operators.box
|
||||
(
|
||||
(
|
||||
# 30 "Parser.fsp"
|
||||
_1
|
||||
)
|
||||
# 30 "Parser.fsp"
|
||||
: AbSyn.EXP));
|
||||
# 195 "Parser.fs"
|
||||
(fun (parseState : FSharp.Text.Parsing.IParseState) ->
|
||||
let _1 = parseState.GetInput(1) :?> int in
|
||||
Microsoft.FSharp.Core.Operators.box
|
||||
(
|
||||
(
|
||||
# 33 "Parser.fsp"
|
||||
AbSyn.CONSTANT (AbSyn.INT _1)
|
||||
)
|
||||
# 33 "Parser.fsp"
|
||||
: AbSyn.EXP));
|
||||
# 206 "Parser.fs"
|
||||
(fun (parseState : FSharp.Text.Parsing.IParseState) ->
|
||||
let _1 = parseState.GetInput(1) :?> string in
|
||||
Microsoft.FSharp.Core.Operators.box
|
||||
(
|
||||
(
|
||||
# 34 "Parser.fsp"
|
||||
AbSyn.VARIABLE _1
|
||||
)
|
||||
# 34 "Parser.fsp"
|
||||
: AbSyn.EXP));
|
||||
# 217 "Parser.fs"
|
||||
(fun (parseState : FSharp.Text.Parsing.IParseState) ->
|
||||
let _2 = parseState.GetInput(2) :?> AbSyn.EXP in
|
||||
Microsoft.FSharp.Core.Operators.box
|
||||
(
|
||||
(
|
||||
# 35 "Parser.fsp"
|
||||
_2
|
||||
)
|
||||
# 35 "Parser.fsp"
|
||||
: AbSyn.EXP));
|
||||
# 228 "Parser.fs"
|
||||
(fun (parseState : FSharp.Text.Parsing.IParseState) ->
|
||||
let _1 = parseState.GetInput(1) :?> AbSyn.EXP in
|
||||
let _3 = parseState.GetInput(3) :?> AbSyn.EXP in
|
||||
Microsoft.FSharp.Core.Operators.box
|
||||
(
|
||||
(
|
||||
# 36 "Parser.fsp"
|
||||
AbSyn.OPERATE (AbSyn.BPLUS, _1, _3)
|
||||
)
|
||||
# 36 "Parser.fsp"
|
||||
: AbSyn.EXP));
|
||||
# 240 "Parser.fs"
|
||||
(fun (parseState : FSharp.Text.Parsing.IParseState) ->
|
||||
let _1 = parseState.GetInput(1) :?> AbSyn.EXP in
|
||||
let _3 = parseState.GetInput(3) :?> AbSyn.EXP in
|
||||
Microsoft.FSharp.Core.Operators.box
|
||||
(
|
||||
(
|
||||
# 37 "Parser.fsp"
|
||||
AbSyn.OPERATE (AbSyn.BMINUS, _1, _3)
|
||||
)
|
||||
# 37 "Parser.fsp"
|
||||
: AbSyn.EXP));
|
||||
# 252 "Parser.fs"
|
||||
(fun (parseState : FSharp.Text.Parsing.IParseState) ->
|
||||
let _1 = parseState.GetInput(1) :?> AbSyn.EXP in
|
||||
let _3 = parseState.GetInput(3) :?> AbSyn.EXP in
|
||||
Microsoft.FSharp.Core.Operators.box
|
||||
(
|
||||
(
|
||||
# 38 "Parser.fsp"
|
||||
AbSyn.OPERATE (AbSyn.BTIMES, _1, _3)
|
||||
)
|
||||
# 38 "Parser.fsp"
|
||||
: AbSyn.EXP));
|
||||
# 264 "Parser.fs"
|
||||
(fun (parseState : FSharp.Text.Parsing.IParseState) ->
|
||||
let _2 = parseState.GetInput(2) :?> string in
|
||||
let _4 = parseState.GetInput(4) :?> AbSyn.EXP in
|
||||
let _6 = parseState.GetInput(6) :?> AbSyn.EXP in
|
||||
Microsoft.FSharp.Core.Operators.box
|
||||
(
|
||||
(
|
||||
# 39 "Parser.fsp"
|
||||
AbSyn.LET_IN (_2, _4, _6)
|
||||
)
|
||||
# 39 "Parser.fsp"
|
||||
: AbSyn.EXP));
|
||||
# 277 "Parser.fs"
|
||||
(fun (parseState : FSharp.Text.Parsing.IParseState) ->
|
||||
let _2 = parseState.GetInput(2) :?> string in
|
||||
let _4 = parseState.GetInput(4) :?> AbSyn.EXP in
|
||||
let _6 = parseState.GetInput(6) :?> AbSyn.EXP in
|
||||
let _8 = parseState.GetInput(8) :?> AbSyn.EXP in
|
||||
Microsoft.FSharp.Core.Operators.box
|
||||
(
|
||||
(
|
||||
# 40 "Parser.fsp"
|
||||
AbSyn.OVER (AbSyn.RSUM, _2, _4, _6, _8)
|
||||
)
|
||||
# 40 "Parser.fsp"
|
||||
: AbSyn.EXP));
|
||||
# 291 "Parser.fs"
|
||||
(fun (parseState : FSharp.Text.Parsing.IParseState) ->
|
||||
let _2 = parseState.GetInput(2) :?> string in
|
||||
let _4 = parseState.GetInput(4) :?> AbSyn.EXP in
|
||||
let _6 = parseState.GetInput(6) :?> AbSyn.EXP in
|
||||
let _8 = parseState.GetInput(8) :?> AbSyn.EXP in
|
||||
Microsoft.FSharp.Core.Operators.box
|
||||
(
|
||||
(
|
||||
# 41 "Parser.fsp"
|
||||
AbSyn.OVER (AbSyn.RPROD, _2, _4, _6, _8)
|
||||
)
|
||||
# 41 "Parser.fsp"
|
||||
: AbSyn.EXP));
|
||||
# 305 "Parser.fs"
|
||||
(fun (parseState : FSharp.Text.Parsing.IParseState) ->
|
||||
let _2 = parseState.GetInput(2) :?> string in
|
||||
let _4 = parseState.GetInput(4) :?> AbSyn.EXP in
|
||||
let _6 = parseState.GetInput(6) :?> AbSyn.EXP in
|
||||
let _8 = parseState.GetInput(8) :?> AbSyn.EXP in
|
||||
Microsoft.FSharp.Core.Operators.box
|
||||
(
|
||||
(
|
||||
# 42 "Parser.fsp"
|
||||
AbSyn.OVER (AbSyn.RMAX, _2, _4, _6, _8)
|
||||
)
|
||||
# 42 "Parser.fsp"
|
||||
: AbSyn.EXP));
|
||||
# 319 "Parser.fs"
|
||||
(fun (parseState : FSharp.Text.Parsing.IParseState) ->
|
||||
let _2 = parseState.GetInput(2) :?> string in
|
||||
let _4 = parseState.GetInput(4) :?> AbSyn.EXP in
|
||||
let _6 = parseState.GetInput(6) :?> AbSyn.EXP in
|
||||
let _8 = parseState.GetInput(8) :?> AbSyn.EXP in
|
||||
Microsoft.FSharp.Core.Operators.box
|
||||
(
|
||||
(
|
||||
# 43 "Parser.fsp"
|
||||
AbSyn.OVER (AbSyn.RARGMAX, _2, _4, _6, _8)
|
||||
)
|
||||
# 43 "Parser.fsp"
|
||||
: AbSyn.EXP));
|
||||
|]
|
||||
# 334 "Parser.fs"
|
||||
let tables : FSharp.Text.Parsing.Tables<_> =
|
||||
{ reductions= _fsyacc_reductions ();
|
||||
endOfInputTag = _fsyacc_endOfInputTag;
|
||||
tagOfToken = tagOfToken;
|
||||
dataOfToken = _fsyacc_dataOfToken;
|
||||
actionTableElements = _fsyacc_actionTableElements;
|
||||
actionTableRowOffsets = _fsyacc_actionTableRowOffsets;
|
||||
stateToProdIdxsTableElements = _fsyacc_stateToProdIdxsTableElements;
|
||||
stateToProdIdxsTableRowOffsets = _fsyacc_stateToProdIdxsTableRowOffsets;
|
||||
reductionSymbolCounts = _fsyacc_reductionSymbolCounts;
|
||||
immediateActions = _fsyacc_immediateActions;
|
||||
gotos = _fsyacc_gotos;
|
||||
sparseGotoTableRowOffsets = _fsyacc_sparseGotoTableRowOffsets;
|
||||
tagOfErrorTerminal = _fsyacc_tagOfErrorTerminal;
|
||||
parseError = (fun (ctxt:FSharp.Text.Parsing.ParseErrorContext<_>) ->
|
||||
match parse_error_rich with
|
||||
| Some f -> f ctxt
|
||||
| None -> parse_error ctxt.Message);
|
||||
numTerminals = 20;
|
||||
productionToNonTerminalTable = _fsyacc_productionToNonTerminalTable }
|
||||
let engine lexer lexbuf startState = tables.Interpret(lexer, lexbuf, startState)
|
||||
let Prog lexer lexbuf : AbSyn.EXP =
|
||||
engine lexer lexbuf 0 :?> _
|
||||
@@ -0,0 +1,56 @@
|
||||
// Signature file for parser generated by fsyacc
|
||||
module Parser
|
||||
type token =
|
||||
| SUM
|
||||
| PROD
|
||||
| MAX
|
||||
| ARGMAX
|
||||
| PLUS
|
||||
| MINUS
|
||||
| TIMES
|
||||
| LET
|
||||
| IN
|
||||
| TO
|
||||
| OF
|
||||
| EOF
|
||||
| LPAR
|
||||
| RPAR
|
||||
| EQ
|
||||
| VAR of (string)
|
||||
| INT of (int)
|
||||
type tokenId =
|
||||
| TOKEN_SUM
|
||||
| TOKEN_PROD
|
||||
| TOKEN_MAX
|
||||
| TOKEN_ARGMAX
|
||||
| TOKEN_PLUS
|
||||
| TOKEN_MINUS
|
||||
| TOKEN_TIMES
|
||||
| TOKEN_LET
|
||||
| TOKEN_IN
|
||||
| TOKEN_TO
|
||||
| TOKEN_OF
|
||||
| TOKEN_EOF
|
||||
| TOKEN_LPAR
|
||||
| TOKEN_RPAR
|
||||
| TOKEN_EQ
|
||||
| TOKEN_VAR
|
||||
| TOKEN_INT
|
||||
| TOKEN_end_of_input
|
||||
| TOKEN_error
|
||||
type nonTerminalId =
|
||||
| NONTERM__startProg
|
||||
| NONTERM_Prog
|
||||
| NONTERM_Exp
|
||||
/// This function maps tokens to integer indexes
|
||||
val tagOfToken: token -> int
|
||||
|
||||
/// This function maps integer indexes to symbolic token ids
|
||||
val tokenTagToTokenId: int -> tokenId
|
||||
|
||||
/// This function maps production indexes returned in syntax errors to strings representing the non terminal that would be produced by that production
|
||||
val prodIdxToNonTerminal: int -> nonTerminalId
|
||||
|
||||
/// This function gets the name of a token as a string
|
||||
val token_to_string: token -> string
|
||||
val Prog : (FSharp.Text.Lexing.LexBuffer<'cty> -> token) -> FSharp.Text.Lexing.LexBuffer<'cty> -> (AbSyn.EXP)
|
||||
@@ -0,0 +1,50 @@
|
||||
%{
|
||||
open FSharp.Text.Parsing
|
||||
%}
|
||||
|
||||
%token <int> INT
|
||||
%token <string> VAR
|
||||
%token LPAR RPAR EQ
|
||||
// FIXME: You should declare tokens for:
|
||||
// + Operators
|
||||
// + Keywords
|
||||
// The token for identifier (variable name) is
|
||||
// already provided ('VAR')
|
||||
%token LET IN TO OF EOF
|
||||
%token TIMES
|
||||
%token PLUS MINUS
|
||||
%token SUM PROD MAX ARGMAX
|
||||
|
||||
// FIXME: Add precedence rules here.
|
||||
|
||||
%nonassoc letprec overprec
|
||||
%left TIMES
|
||||
%left PLUS MINUS
|
||||
|
||||
%start Prog
|
||||
%type <AbSyn.EXP> Prog
|
||||
%type <AbSyn.EXP> Exp
|
||||
|
||||
%%
|
||||
|
||||
Prog : Exp EOF { $1 }
|
||||
;
|
||||
|
||||
Exp : INT { AbSyn.CONSTANT (AbSyn.INT $1) }
|
||||
| VAR { AbSyn.VARIABLE $1 }
|
||||
| LPAR Exp RPAR { $2 }
|
||||
| Exp PLUS Exp { AbSyn.OPERATE (AbSyn.BPLUS, $1, $3) }
|
||||
| Exp MINUS Exp { AbSyn.OPERATE (AbSyn.BMINUS, $1, $3) }
|
||||
| Exp TIMES Exp { AbSyn.OPERATE (AbSyn.BTIMES, $1, $3) }
|
||||
| LET VAR EQ Exp IN Exp %prec letprec { AbSyn.LET_IN ($2, $4, $6) }
|
||||
| SUM VAR EQ Exp TO Exp OF Exp %prec overprec { AbSyn.OVER (AbSyn.RSUM, $2, $4, $6, $8) }
|
||||
| PROD VAR EQ Exp TO Exp OF Exp %prec overprec { AbSyn.OVER (AbSyn.RPROD, $2, $4, $6, $8) }
|
||||
| MAX VAR EQ Exp TO Exp OF Exp %prec overprec { AbSyn.OVER (AbSyn.RMAX, $2, $4, $6, $8) }
|
||||
| ARGMAX VAR EQ Exp TO Exp OF Exp %prec overprec { AbSyn.OVER (AbSyn.RARGMAX, $2, $4, $6, $8) }
|
||||
// FIXME: You should implement parsing for:
|
||||
// + infix opeators
|
||||
// + let ... = ... in ...
|
||||
// + sum ... = ... to ... of ... [and likewise for prod, ...]
|
||||
;
|
||||
|
||||
%%
|
||||
File diff suppressed because it is too large
Load Diff
Executable
BIN
Binary file not shown.
@@ -0,0 +1,114 @@
|
||||
{
|
||||
"runtimeTarget": {
|
||||
"name": ".NETCoreApp,Version=v6.0",
|
||||
"signature": ""
|
||||
},
|
||||
"compilationOptions": {},
|
||||
"targets": {
|
||||
".NETCoreApp,Version=v6.0": {
|
||||
"Calculator/1.0.0": {
|
||||
"dependencies": {
|
||||
"FSharp.Core": "6.0.1",
|
||||
"FsLexYacc": "10.2.0"
|
||||
},
|
||||
"runtime": {
|
||||
"Calculator.dll": {}
|
||||
}
|
||||
},
|
||||
"FSharp.Core/6.0.1": {
|
||||
"runtime": {
|
||||
"lib/netstandard2.1/FSharp.Core.dll": {
|
||||
"assemblyVersion": "6.0.0.0",
|
||||
"fileVersion": "6.0.121.52202"
|
||||
}
|
||||
},
|
||||
"resources": {
|
||||
"lib/netstandard2.1/cs/FSharp.Core.resources.dll": {
|
||||
"locale": "cs"
|
||||
},
|
||||
"lib/netstandard2.1/de/FSharp.Core.resources.dll": {
|
||||
"locale": "de"
|
||||
},
|
||||
"lib/netstandard2.1/es/FSharp.Core.resources.dll": {
|
||||
"locale": "es"
|
||||
},
|
||||
"lib/netstandard2.1/fr/FSharp.Core.resources.dll": {
|
||||
"locale": "fr"
|
||||
},
|
||||
"lib/netstandard2.1/it/FSharp.Core.resources.dll": {
|
||||
"locale": "it"
|
||||
},
|
||||
"lib/netstandard2.1/ja/FSharp.Core.resources.dll": {
|
||||
"locale": "ja"
|
||||
},
|
||||
"lib/netstandard2.1/ko/FSharp.Core.resources.dll": {
|
||||
"locale": "ko"
|
||||
},
|
||||
"lib/netstandard2.1/pl/FSharp.Core.resources.dll": {
|
||||
"locale": "pl"
|
||||
},
|
||||
"lib/netstandard2.1/pt-BR/FSharp.Core.resources.dll": {
|
||||
"locale": "pt-BR"
|
||||
},
|
||||
"lib/netstandard2.1/ru/FSharp.Core.resources.dll": {
|
||||
"locale": "ru"
|
||||
},
|
||||
"lib/netstandard2.1/tr/FSharp.Core.resources.dll": {
|
||||
"locale": "tr"
|
||||
},
|
||||
"lib/netstandard2.1/zh-Hans/FSharp.Core.resources.dll": {
|
||||
"locale": "zh-Hans"
|
||||
},
|
||||
"lib/netstandard2.1/zh-Hant/FSharp.Core.resources.dll": {
|
||||
"locale": "zh-Hant"
|
||||
}
|
||||
}
|
||||
},
|
||||
"FsLexYacc/10.2.0": {
|
||||
"dependencies": {
|
||||
"FSharp.Core": "6.0.1",
|
||||
"FsLexYacc.Runtime": "10.2.0"
|
||||
}
|
||||
},
|
||||
"FsLexYacc.Runtime/10.2.0": {
|
||||
"dependencies": {
|
||||
"FSharp.Core": "6.0.1"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/netstandard2.0/FsLexYacc.Runtime.dll": {
|
||||
"assemblyVersion": "1.0.0.0",
|
||||
"fileVersion": "10.2.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"libraries": {
|
||||
"Calculator/1.0.0": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"FSharp.Core/6.0.1": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-VrFAiW8dEEekk+0aqlbvMNZzDvYXmgWZwAt68AUBqaWK8RnoEVUNglj66bZzhs4/U63q0EfXlhcEKnH1sTYLjw==",
|
||||
"path": "fsharp.core/6.0.1",
|
||||
"hashPath": "fsharp.core.6.0.1.nupkg.sha512"
|
||||
},
|
||||
"FsLexYacc/10.2.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-q7mhuEMm8rvFAJ9jaH1atYCRN96tMbjHarYIDooeMKFCbUuqvep+vA2ijGhA06GZ5BG+jg4TjG6dt/4gR2qHHA==",
|
||||
"path": "fslexyacc/10.2.0",
|
||||
"hashPath": "fslexyacc.10.2.0.nupkg.sha512"
|
||||
},
|
||||
"FsLexYacc.Runtime/10.2.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-d2+gguRIvsn1e7AycVc0r7L1QWptrnUOvQvJLbgkANcS5SjfM/FRgfUGwfqV2cJo3KOFQB5Mqmda/4YTQkkvdA==",
|
||||
"path": "fslexyacc.runtime/10.2.0",
|
||||
"hashPath": "fslexyacc.runtime.10.2.0.nupkg.sha512"
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"runtimeOptions": {
|
||||
"tfm": "net6.0",
|
||||
"framework": {
|
||||
"name": "Microsoft.NETCore.App",
|
||||
"version": "6.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e # Die on first error.
|
||||
|
||||
base_dir="$(dirname "$0")"
|
||||
|
||||
# Determine location of executable. Does this work on all platforms?
|
||||
if ! [ "$CALC" ]; then
|
||||
CALC="$base_dir/bin/Debug/net6.0/Calculator.dll"
|
||||
if [[ $(uname -o 2> /dev/null) = "Cygwin" ]]; then
|
||||
CALC="$(cygpath -w "CALC")"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Verify that .NET is installed.
|
||||
dotnet --version &> /dev/null || (echo "Could not find dotnet" && exit 1)
|
||||
|
||||
dotnet $CALC "$@"
|
||||
@@ -0,0 +1,74 @@
|
||||
{
|
||||
"format": 1,
|
||||
"restore": {
|
||||
"/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W2/calculator/Calculator.fsproj": {}
|
||||
},
|
||||
"projects": {
|
||||
"/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W2/calculator/Calculator.fsproj": {
|
||||
"version": "1.0.0",
|
||||
"restore": {
|
||||
"projectUniqueName": "/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W2/calculator/Calculator.fsproj",
|
||||
"projectName": "Calculator",
|
||||
"projectPath": "/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W2/calculator/Calculator.fsproj",
|
||||
"packagesPath": "/home/nikolaj/.nuget/packages/",
|
||||
"outputPath": "/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W2/calculator/obj/",
|
||||
"projectStyle": "PackageReference",
|
||||
"configFilePaths": [
|
||||
"/home/nikolaj/.nuget/NuGet/NuGet.Config"
|
||||
],
|
||||
"originalTargetFrameworks": [
|
||||
"net6.0"
|
||||
],
|
||||
"sources": {
|
||||
"https://api.nuget.org/v3/index.json": {}
|
||||
},
|
||||
"frameworks": {
|
||||
"net6.0": {
|
||||
"targetAlias": "net6.0",
|
||||
"projectReferences": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"frameworks": {
|
||||
"net6.0": {
|
||||
"targetAlias": "net6.0",
|
||||
"dependencies": {
|
||||
"FSharp.Core": {
|
||||
"include": "Runtime, Compile, Build, Native, Analyzers, BuildTransitive",
|
||||
"target": "Package",
|
||||
"version": "[6.0.1, )",
|
||||
"generatePathProperty": true
|
||||
},
|
||||
"FsLexYacc": {
|
||||
"target": "Package",
|
||||
"version": "[10.2.0, )",
|
||||
"generatePathProperty": true
|
||||
}
|
||||
},
|
||||
"imports": [
|
||||
"net461",
|
||||
"net462",
|
||||
"net47",
|
||||
"net471",
|
||||
"net472",
|
||||
"net48"
|
||||
],
|
||||
"assetTargetFallback": true,
|
||||
"warn": true,
|
||||
"downloadDependencies": [
|
||||
{
|
||||
"name": "Microsoft.AspNetCore.App.Ref",
|
||||
"version": "[6.0.2, 6.0.2]"
|
||||
}
|
||||
],
|
||||
"frameworkReferences": {
|
||||
"Microsoft.NETCore.App": {
|
||||
"privateAssets": "all"
|
||||
}
|
||||
},
|
||||
"runtimeIdentifierGraphPath": "/usr/share/dotnet/sdk/6.0.102/RuntimeIdentifierGraph.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
|
||||
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
|
||||
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
|
||||
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">/home/nikolaj/.nuget/packages/</NuGetPackageRoot>
|
||||
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">/home/nikolaj/.nuget/packages/</NuGetPackageFolders>
|
||||
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
|
||||
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.0.0</NuGetToolVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<SourceRoot Include="/home/nikolaj/.nuget/packages/" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<PkgFSharp_Core Condition=" '$(PkgFSharp_Core)' == '' ">/home/nikolaj/.nuget/packages/fsharp.core/6.0.1</PkgFSharp_Core>
|
||||
<PkgFsLexYacc Condition=" '$(PkgFsLexYacc)' == '' ">/home/nikolaj/.nuget/packages/fslexyacc/10.2.0</PkgFsLexYacc>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<Import Project="$(NuGetPackageRoot)fslexyacc/10.2.0/build/FsLexYacc.targets" Condition="Exists('$(NuGetPackageRoot)fslexyacc/10.2.0/build/FsLexYacc.targets')" />
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,3 @@
|
||||
namespace Microsoft.BuildSettings
|
||||
[<System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v6.0", FrameworkDisplayName="")>]
|
||||
do ()
|
||||
@@ -0,0 +1,17 @@
|
||||
// <auto-generated>
|
||||
// Generated by the FSharp WriteCodeFragment class.
|
||||
// </auto-generated>
|
||||
namespace FSharp
|
||||
|
||||
open System
|
||||
open System.Reflection
|
||||
|
||||
|
||||
[<assembly: System.Reflection.AssemblyCompanyAttribute("Calculator")>]
|
||||
[<assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")>]
|
||||
[<assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")>]
|
||||
[<assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")>]
|
||||
[<assembly: System.Reflection.AssemblyProductAttribute("Calculator")>]
|
||||
[<assembly: System.Reflection.AssemblyTitleAttribute("Calculator")>]
|
||||
[<assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")>]
|
||||
do()
|
||||
@@ -0,0 +1 @@
|
||||
8c72ea1d86216c3b72e48b1ba03640b785639f4b
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
55f40b194561dd93f59870bc14d2a29b46f7c02e
|
||||
@@ -0,0 +1,27 @@
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W2/calculator/bin/Debug/net6.0/Calculator
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W2/calculator/bin/Debug/net6.0/Calculator.deps.json
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W2/calculator/bin/Debug/net6.0/Calculator.runtimeconfig.json
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W2/calculator/bin/Debug/net6.0/Calculator.dll
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W2/calculator/bin/Debug/net6.0/Calculator.pdb
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W2/calculator/bin/Debug/net6.0/FSharp.Core.dll
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W2/calculator/bin/Debug/net6.0/FsLexYacc.Runtime.dll
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W2/calculator/bin/Debug/net6.0/cs/FSharp.Core.resources.dll
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W2/calculator/bin/Debug/net6.0/de/FSharp.Core.resources.dll
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W2/calculator/bin/Debug/net6.0/es/FSharp.Core.resources.dll
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W2/calculator/bin/Debug/net6.0/fr/FSharp.Core.resources.dll
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W2/calculator/bin/Debug/net6.0/it/FSharp.Core.resources.dll
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W2/calculator/bin/Debug/net6.0/ja/FSharp.Core.resources.dll
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W2/calculator/bin/Debug/net6.0/ko/FSharp.Core.resources.dll
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W2/calculator/bin/Debug/net6.0/pl/FSharp.Core.resources.dll
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W2/calculator/bin/Debug/net6.0/pt-BR/FSharp.Core.resources.dll
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W2/calculator/bin/Debug/net6.0/ru/FSharp.Core.resources.dll
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W2/calculator/bin/Debug/net6.0/tr/FSharp.Core.resources.dll
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W2/calculator/bin/Debug/net6.0/zh-Hans/FSharp.Core.resources.dll
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W2/calculator/bin/Debug/net6.0/zh-Hant/FSharp.Core.resources.dll
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W2/calculator/obj/Debug/net6.0/Calculator.fsproj.AssemblyReference.cache
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W2/calculator/obj/Debug/net6.0/Calculator.AssemblyInfoInputs.cache
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W2/calculator/obj/Debug/net6.0/Calculator.AssemblyInfo.fs
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W2/calculator/obj/Debug/net6.0/Calculator.fsproj.CopyComplete
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W2/calculator/obj/Debug/net6.0/Calculator.dll
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W2/calculator/obj/Debug/net6.0/Calculator.pdb
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W2/calculator/obj/Debug/net6.0/Calculator.genruntimeconfig.cache
|
||||
@@ -0,0 +1 @@
|
||||
2747ec3745a2aafc082acd8723763a8889db8be7
|
||||
Binary file not shown.
Executable
BIN
Binary file not shown.
File diff suppressed because one or more lines are too long
@@ -0,0 +1,296 @@
|
||||
{
|
||||
"version": 3,
|
||||
"targets": {
|
||||
"net6.0": {
|
||||
"FSharp.Core/6.0.1": {
|
||||
"type": "package",
|
||||
"compile": {
|
||||
"lib/netstandard2.1/FSharp.Core.dll": {}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/netstandard2.1/FSharp.Core.dll": {}
|
||||
},
|
||||
"resource": {
|
||||
"lib/netstandard2.1/cs/FSharp.Core.resources.dll": {
|
||||
"locale": "cs"
|
||||
},
|
||||
"lib/netstandard2.1/de/FSharp.Core.resources.dll": {
|
||||
"locale": "de"
|
||||
},
|
||||
"lib/netstandard2.1/es/FSharp.Core.resources.dll": {
|
||||
"locale": "es"
|
||||
},
|
||||
"lib/netstandard2.1/fr/FSharp.Core.resources.dll": {
|
||||
"locale": "fr"
|
||||
},
|
||||
"lib/netstandard2.1/it/FSharp.Core.resources.dll": {
|
||||
"locale": "it"
|
||||
},
|
||||
"lib/netstandard2.1/ja/FSharp.Core.resources.dll": {
|
||||
"locale": "ja"
|
||||
},
|
||||
"lib/netstandard2.1/ko/FSharp.Core.resources.dll": {
|
||||
"locale": "ko"
|
||||
},
|
||||
"lib/netstandard2.1/pl/FSharp.Core.resources.dll": {
|
||||
"locale": "pl"
|
||||
},
|
||||
"lib/netstandard2.1/pt-BR/FSharp.Core.resources.dll": {
|
||||
"locale": "pt-BR"
|
||||
},
|
||||
"lib/netstandard2.1/ru/FSharp.Core.resources.dll": {
|
||||
"locale": "ru"
|
||||
},
|
||||
"lib/netstandard2.1/tr/FSharp.Core.resources.dll": {
|
||||
"locale": "tr"
|
||||
},
|
||||
"lib/netstandard2.1/zh-Hans/FSharp.Core.resources.dll": {
|
||||
"locale": "zh-Hans"
|
||||
},
|
||||
"lib/netstandard2.1/zh-Hant/FSharp.Core.resources.dll": {
|
||||
"locale": "zh-Hant"
|
||||
}
|
||||
},
|
||||
"contentFiles": {
|
||||
"contentFiles/any/any/_._": {
|
||||
"buildAction": "None",
|
||||
"codeLanguage": "any",
|
||||
"copyToOutput": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"FsLexYacc/10.2.0": {
|
||||
"type": "package",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "4.5.2",
|
||||
"FsLexYacc.Runtime": "[10.2.0, 10.3.0)"
|
||||
},
|
||||
"build": {
|
||||
"build/FsLexYacc.targets": {}
|
||||
}
|
||||
},
|
||||
"FsLexYacc.Runtime/10.2.0": {
|
||||
"type": "package",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "4.5.2"
|
||||
},
|
||||
"compile": {
|
||||
"lib/netstandard2.0/FsLexYacc.Runtime.dll": {}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/netstandard2.0/FsLexYacc.Runtime.dll": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"libraries": {
|
||||
"FSharp.Core/6.0.1": {
|
||||
"sha512": "VrFAiW8dEEekk+0aqlbvMNZzDvYXmgWZwAt68AUBqaWK8RnoEVUNglj66bZzhs4/U63q0EfXlhcEKnH1sTYLjw==",
|
||||
"type": "package",
|
||||
"path": "fsharp.core/6.0.1",
|
||||
"files": [
|
||||
".nupkg.metadata",
|
||||
".signature.p7s",
|
||||
"Icon.png",
|
||||
"contentFiles/any/netstandard2.0/FSharp.Core.xml",
|
||||
"contentFiles/any/netstandard2.1/FSharp.Core.xml",
|
||||
"fsharp.core.6.0.1.nupkg.sha512",
|
||||
"fsharp.core.nuspec",
|
||||
"lib/netstandard2.0/FSharp.Core.dll",
|
||||
"lib/netstandard2.0/FSharp.Core.xml",
|
||||
"lib/netstandard2.0/cs/FSharp.Core.resources.dll",
|
||||
"lib/netstandard2.0/de/FSharp.Core.resources.dll",
|
||||
"lib/netstandard2.0/es/FSharp.Core.resources.dll",
|
||||
"lib/netstandard2.0/fr/FSharp.Core.resources.dll",
|
||||
"lib/netstandard2.0/it/FSharp.Core.resources.dll",
|
||||
"lib/netstandard2.0/ja/FSharp.Core.resources.dll",
|
||||
"lib/netstandard2.0/ko/FSharp.Core.resources.dll",
|
||||
"lib/netstandard2.0/pl/FSharp.Core.resources.dll",
|
||||
"lib/netstandard2.0/pt-BR/FSharp.Core.resources.dll",
|
||||
"lib/netstandard2.0/ru/FSharp.Core.resources.dll",
|
||||
"lib/netstandard2.0/tr/FSharp.Core.resources.dll",
|
||||
"lib/netstandard2.0/zh-Hans/FSharp.Core.resources.dll",
|
||||
"lib/netstandard2.0/zh-Hant/FSharp.Core.resources.dll",
|
||||
"lib/netstandard2.1/FSharp.Core.dll",
|
||||
"lib/netstandard2.1/FSharp.Core.xml",
|
||||
"lib/netstandard2.1/cs/FSharp.Core.resources.dll",
|
||||
"lib/netstandard2.1/de/FSharp.Core.resources.dll",
|
||||
"lib/netstandard2.1/es/FSharp.Core.resources.dll",
|
||||
"lib/netstandard2.1/fr/FSharp.Core.resources.dll",
|
||||
"lib/netstandard2.1/it/FSharp.Core.resources.dll",
|
||||
"lib/netstandard2.1/ja/FSharp.Core.resources.dll",
|
||||
"lib/netstandard2.1/ko/FSharp.Core.resources.dll",
|
||||
"lib/netstandard2.1/pl/FSharp.Core.resources.dll",
|
||||
"lib/netstandard2.1/pt-BR/FSharp.Core.resources.dll",
|
||||
"lib/netstandard2.1/ru/FSharp.Core.resources.dll",
|
||||
"lib/netstandard2.1/tr/FSharp.Core.resources.dll",
|
||||
"lib/netstandard2.1/zh-Hans/FSharp.Core.resources.dll",
|
||||
"lib/netstandard2.1/zh-Hant/FSharp.Core.resources.dll"
|
||||
]
|
||||
},
|
||||
"FsLexYacc/10.2.0": {
|
||||
"sha512": "q7mhuEMm8rvFAJ9jaH1atYCRN96tMbjHarYIDooeMKFCbUuqvep+vA2ijGhA06GZ5BG+jg4TjG6dt/4gR2qHHA==",
|
||||
"type": "package",
|
||||
"path": "fslexyacc/10.2.0",
|
||||
"files": [
|
||||
".nupkg.metadata",
|
||||
".signature.p7s",
|
||||
"build/FsLexYacc.targets",
|
||||
"build/fslex/netcoreapp3.1/FSharp.Core.dll",
|
||||
"build/fslex/netcoreapp3.1/FsLexYacc.Runtime.dll",
|
||||
"build/fslex/netcoreapp3.1/cs/FSharp.Core.resources.dll",
|
||||
"build/fslex/netcoreapp3.1/de/FSharp.Core.resources.dll",
|
||||
"build/fslex/netcoreapp3.1/en/FSharp.Core.resources.dll",
|
||||
"build/fslex/netcoreapp3.1/es/FSharp.Core.resources.dll",
|
||||
"build/fslex/netcoreapp3.1/fr/FSharp.Core.resources.dll",
|
||||
"build/fslex/netcoreapp3.1/fslex.deps.json",
|
||||
"build/fslex/netcoreapp3.1/fslex.dll",
|
||||
"build/fslex/netcoreapp3.1/fslex.pdb",
|
||||
"build/fslex/netcoreapp3.1/fslex.runtimeconfig.json",
|
||||
"build/fslex/netcoreapp3.1/it/FSharp.Core.resources.dll",
|
||||
"build/fslex/netcoreapp3.1/ja/FSharp.Core.resources.dll",
|
||||
"build/fslex/netcoreapp3.1/ko/FSharp.Core.resources.dll",
|
||||
"build/fslex/netcoreapp3.1/pl/FSharp.Core.resources.dll",
|
||||
"build/fslex/netcoreapp3.1/pt-BR/FSharp.Core.resources.dll",
|
||||
"build/fslex/netcoreapp3.1/ru/FSharp.Core.resources.dll",
|
||||
"build/fslex/netcoreapp3.1/tr/FSharp.Core.resources.dll",
|
||||
"build/fslex/netcoreapp3.1/zh-Hans/FSharp.Core.resources.dll",
|
||||
"build/fslex/netcoreapp3.1/zh-Hant/FSharp.Core.resources.dll",
|
||||
"build/fsyacc/netcoreapp3.1/FSharp.Core.dll",
|
||||
"build/fsyacc/netcoreapp3.1/FsLexYacc.Runtime.dll",
|
||||
"build/fsyacc/netcoreapp3.1/FsLexYacc.targets",
|
||||
"build/fsyacc/netcoreapp3.1/cs/FSharp.Core.resources.dll",
|
||||
"build/fsyacc/netcoreapp3.1/de/FSharp.Core.resources.dll",
|
||||
"build/fsyacc/netcoreapp3.1/en/FSharp.Core.resources.dll",
|
||||
"build/fsyacc/netcoreapp3.1/es/FSharp.Core.resources.dll",
|
||||
"build/fsyacc/netcoreapp3.1/fr/FSharp.Core.resources.dll",
|
||||
"build/fsyacc/netcoreapp3.1/fsyacc.deps.json",
|
||||
"build/fsyacc/netcoreapp3.1/fsyacc.dll",
|
||||
"build/fsyacc/netcoreapp3.1/fsyacc.pdb",
|
||||
"build/fsyacc/netcoreapp3.1/fsyacc.runtimeconfig.json",
|
||||
"build/fsyacc/netcoreapp3.1/it/FSharp.Core.resources.dll",
|
||||
"build/fsyacc/netcoreapp3.1/ja/FSharp.Core.resources.dll",
|
||||
"build/fsyacc/netcoreapp3.1/ko/FSharp.Core.resources.dll",
|
||||
"build/fsyacc/netcoreapp3.1/pl/FSharp.Core.resources.dll",
|
||||
"build/fsyacc/netcoreapp3.1/pt-BR/FSharp.Core.resources.dll",
|
||||
"build/fsyacc/netcoreapp3.1/ru/FSharp.Core.resources.dll",
|
||||
"build/fsyacc/netcoreapp3.1/tr/FSharp.Core.resources.dll",
|
||||
"build/fsyacc/netcoreapp3.1/zh-Hans/FSharp.Core.resources.dll",
|
||||
"build/fsyacc/netcoreapp3.1/zh-Hant/FSharp.Core.resources.dll",
|
||||
"fslexyacc.10.2.0.nupkg.sha512",
|
||||
"fslexyacc.nuspec",
|
||||
"src/FsLexYacc.targets",
|
||||
"src/fslex/Arg.fs",
|
||||
"src/fslex/Arg.fsi",
|
||||
"src/fslex/Lexing.fs",
|
||||
"src/fslex/Lexing.fsi",
|
||||
"src/fslex/Parsing.fs",
|
||||
"src/fslex/Parsing.fsi",
|
||||
"src/fslex/fslex.fs",
|
||||
"src/fslex/fslex.fsx",
|
||||
"src/fslex/fslexast.fs",
|
||||
"src/fslex/fslexlex.fs",
|
||||
"src/fslex/fslexpars.fs",
|
||||
"src/fsyacc/Arg.fs",
|
||||
"src/fsyacc/Arg.fsi",
|
||||
"src/fsyacc/Lexing.fs",
|
||||
"src/fsyacc/Lexing.fsi",
|
||||
"src/fsyacc/Parsing.fs",
|
||||
"src/fsyacc/Parsing.fsi",
|
||||
"src/fsyacc/fsyacc.fs",
|
||||
"src/fsyacc/fsyacc.fsx",
|
||||
"src/fsyacc/fsyaccast.fs",
|
||||
"src/fsyacc/fsyacclex.fs",
|
||||
"src/fsyacc/fsyaccpars.fs"
|
||||
]
|
||||
},
|
||||
"FsLexYacc.Runtime/10.2.0": {
|
||||
"sha512": "d2+gguRIvsn1e7AycVc0r7L1QWptrnUOvQvJLbgkANcS5SjfM/FRgfUGwfqV2cJo3KOFQB5Mqmda/4YTQkkvdA==",
|
||||
"type": "package",
|
||||
"path": "fslexyacc.runtime/10.2.0",
|
||||
"files": [
|
||||
".nupkg.metadata",
|
||||
".signature.p7s",
|
||||
"fslexyacc.runtime.10.2.0.nupkg.sha512",
|
||||
"fslexyacc.runtime.nuspec",
|
||||
"lib/netstandard2.0/FsLexYacc.Runtime.dll",
|
||||
"lib/netstandard2.0/FsLexYacc.Runtime.xml"
|
||||
]
|
||||
}
|
||||
},
|
||||
"projectFileDependencyGroups": {
|
||||
"net6.0": [
|
||||
"FSharp.Core >= 6.0.1",
|
||||
"FsLexYacc >= 10.2.0"
|
||||
]
|
||||
},
|
||||
"packageFolders": {
|
||||
"/home/nikolaj/.nuget/packages/": {}
|
||||
},
|
||||
"project": {
|
||||
"version": "1.0.0",
|
||||
"restore": {
|
||||
"projectUniqueName": "/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W2/calculator/Calculator.fsproj",
|
||||
"projectName": "Calculator",
|
||||
"projectPath": "/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W2/calculator/Calculator.fsproj",
|
||||
"packagesPath": "/home/nikolaj/.nuget/packages/",
|
||||
"outputPath": "/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W2/calculator/obj/",
|
||||
"projectStyle": "PackageReference",
|
||||
"configFilePaths": [
|
||||
"/home/nikolaj/.nuget/NuGet/NuGet.Config"
|
||||
],
|
||||
"originalTargetFrameworks": [
|
||||
"net6.0"
|
||||
],
|
||||
"sources": {
|
||||
"https://api.nuget.org/v3/index.json": {}
|
||||
},
|
||||
"frameworks": {
|
||||
"net6.0": {
|
||||
"targetAlias": "net6.0",
|
||||
"projectReferences": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"frameworks": {
|
||||
"net6.0": {
|
||||
"targetAlias": "net6.0",
|
||||
"dependencies": {
|
||||
"FSharp.Core": {
|
||||
"include": "Runtime, Compile, Build, Native, Analyzers, BuildTransitive",
|
||||
"target": "Package",
|
||||
"version": "[6.0.1, )",
|
||||
"generatePathProperty": true
|
||||
},
|
||||
"FsLexYacc": {
|
||||
"target": "Package",
|
||||
"version": "[10.2.0, )",
|
||||
"generatePathProperty": true
|
||||
}
|
||||
},
|
||||
"imports": [
|
||||
"net461",
|
||||
"net462",
|
||||
"net47",
|
||||
"net471",
|
||||
"net472",
|
||||
"net48"
|
||||
],
|
||||
"assetTargetFallback": true,
|
||||
"warn": true,
|
||||
"downloadDependencies": [
|
||||
{
|
||||
"name": "Microsoft.AspNetCore.App.Ref",
|
||||
"version": "[6.0.2, 6.0.2]"
|
||||
}
|
||||
],
|
||||
"frameworkReferences": {
|
||||
"Microsoft.NETCore.App": {
|
||||
"privateAssets": "all"
|
||||
}
|
||||
},
|
||||
"runtimeIdentifierGraphPath": "/usr/share/dotnet/sdk/6.0.102/RuntimeIdentifierGraph.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"version": 2,
|
||||
"dgSpecHash": "usdcVY2iHEdMW6BxiK1Rq1eg4qqUJfGNxXWjlu4cMznbCq/3PMJjMZIrqhvsTJvpS0Kqqev79I3lhTRhUo8UnQ==",
|
||||
"success": true,
|
||||
"projectFilePath": "/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W2/calculator/Calculator.fsproj",
|
||||
"expectedPackageFiles": [
|
||||
"/home/nikolaj/.nuget/packages/fsharp.core/6.0.1/fsharp.core.6.0.1.nupkg.sha512",
|
||||
"/home/nikolaj/.nuget/packages/fslexyacc/10.2.0/fslexyacc.10.2.0.nupkg.sha512",
|
||||
"/home/nikolaj/.nuget/packages/fslexyacc.runtime/10.2.0/fslexyacc.runtime.10.2.0.nupkg.sha512",
|
||||
"/home/nikolaj/.nuget/packages/microsoft.aspnetcore.app.ref/6.0.2/microsoft.aspnetcore.app.ref.6.0.2.nupkg.sha512"
|
||||
],
|
||||
"logs": []
|
||||
}
|
||||
@@ -0,0 +1,303 @@
|
||||
module AbSyn
|
||||
|
||||
(*
|
||||
Types and utilities for the abstract syntax tree (AbSyn) of Fasto.
|
||||
Fasto er et funktionelt array-sprog til oversættelse, F-A-S-T-O.
|
||||
Fasto er også et spansk ord, der betyder "pomp" eller "pragt".
|
||||
Derfor skal vi programmere en "pragtfuld" oversætter for Fasto.
|
||||
|
||||
The abstract syntax of a (Fasto) program is a representation of the (Fasto)
|
||||
program in terms of a data type in another programming language (F#).
|
||||
|
||||
Some expressions in Fasto (e.g. array constants, indexing operations, map,
|
||||
reduce) are implicitly typed, their types are not explicitly stated in the
|
||||
program text. Their types are infered at run-time by an interpreter, or at
|
||||
compile-time by a type-checker.
|
||||
|
||||
In support of this, this module defines type-parameterized datatypes for
|
||||
expressions "Exp<'T>", let declarations "Dec<'T>", function arguments
|
||||
"FunArg<'T>", function declaration "FunDec<'T>", and program "Prog<'T>".
|
||||
These datatypes are instantiated over the "unit" and "Type" types to provide
|
||||
an abstract syntax tree without type information, e.g., "UntypedProg = Prog<unit>",
|
||||
and another abstract syntax tree in which the inferred type information
|
||||
is made explicit in the representation "TypedProg = Prog<Type>".
|
||||
|
||||
For example:
|
||||
- interpretation uses the untyped version "TypedProg",
|
||||
- the type checking phase receives as input an untype program ("UntypedProg")
|
||||
and produces a typed program ("TypedProg")
|
||||
- the other compiler phases work on the typed program.
|
||||
|
||||
Note that semantically we use two different AbSyns, but we avoid code duplication
|
||||
by means of the afore-mentioned type parameterization.
|
||||
|
||||
Also our AbSyn stores not just the program structure, but also the positions of
|
||||
the program substructures in the original program text. This is useful for
|
||||
reporting errors at later passes of the compiler, e.g. type errors.
|
||||
|
||||
This module also provides pretty printing functionality, printing a valid Fasto
|
||||
program given its abstract syntax. "pp" is used in this module as a shorthand
|
||||
for "prettyPrint".
|
||||
*)
|
||||
|
||||
(*** Helper Functions ***)
|
||||
let toCString (s : string) : string =
|
||||
let escape c =
|
||||
match c with
|
||||
| '\\' -> "\\\\"
|
||||
| '"' -> "\\\""
|
||||
| '\n' -> "\\n"
|
||||
| '\t' -> "\\t"
|
||||
| _ -> System.String.Concat [c]
|
||||
String.collect escape s
|
||||
|
||||
// Doesn't actually support all escapes. Too badefacilliteter.
|
||||
let fromCString (s : string) : string =
|
||||
let rec unescape l: char list =
|
||||
match l with
|
||||
| [] -> []
|
||||
| '\\' :: 'n' :: l' -> '\n' :: unescape l'
|
||||
| '\\' :: 't' :: l' -> '\t' :: unescape l'
|
||||
| '\\' :: c :: l' -> c :: unescape l'
|
||||
| c :: l' -> c :: unescape l'
|
||||
Seq.toList s |> unescape |> System.String.Concat
|
||||
|
||||
(* position: (line, column) *)
|
||||
type Position = int * int
|
||||
|
||||
type Type =
|
||||
Int
|
||||
| Bool
|
||||
| Char
|
||||
| Array of Type
|
||||
|
||||
type Value =
|
||||
IntVal of int
|
||||
| BoolVal of bool
|
||||
| CharVal of char
|
||||
| ArrayVal of Value list * Type
|
||||
(* Type corresponds to the element-type of the array *)
|
||||
|
||||
(* Indentifies value types (for type checking) *)
|
||||
let valueType = function
|
||||
| (IntVal _) -> Int
|
||||
| (BoolVal _) -> Bool
|
||||
| (CharVal _) -> Char
|
||||
| (ArrayVal (_,tp)) -> Array tp
|
||||
|
||||
(* pretty printing types *)
|
||||
let rec ppType = function
|
||||
| Int -> "int"
|
||||
| Char -> "char"
|
||||
| Bool -> "bool"
|
||||
| Array tp -> "[" + ppType tp + "]"
|
||||
|
||||
(* Parameter declaration *)
|
||||
type Param =
|
||||
Param of string * Type
|
||||
|
||||
type Exp<'T> =
|
||||
Constant of Value * Position
|
||||
| StringLit of string * Position
|
||||
| ArrayLit of Exp<'T> list * 'T * Position
|
||||
| Var of string * Position
|
||||
| Plus of Exp<'T> * Exp<'T> * Position
|
||||
| Minus of Exp<'T> * Exp<'T> * Position
|
||||
| Equal of Exp<'T> * Exp<'T> * Position
|
||||
| Less of Exp<'T> * Exp<'T> * Position
|
||||
| If of Exp<'T> * Exp<'T> * Exp<'T> * Position
|
||||
| Apply of string * Exp<'T> list * Position
|
||||
| Let of Dec<'T> * Exp<'T> * Position
|
||||
| Index of string * Exp<'T> * 'T * Position
|
||||
|
||||
(* dirty I/O *)
|
||||
| Read of Type * Position
|
||||
| Write of Exp<'T> * 'T * Position
|
||||
|
||||
(* Project implementations *)
|
||||
| Times of Exp<'T> * Exp<'T> * Position
|
||||
| Divide of Exp<'T> * Exp<'T> * Position
|
||||
| Negate of Exp<'T> * Position
|
||||
| And of Exp<'T> * Exp<'T> * Position
|
||||
| Or of Exp<'T> * Exp<'T> * Position
|
||||
| Not of Exp<'T> * Position
|
||||
|
||||
(* Array constructors/combinators implementations *)
|
||||
| Iota of Exp<'T> * Position
|
||||
|
||||
(* map (f, array)
|
||||
the first 'T corresponds to the mapped array element type,
|
||||
which is the same as the f's input type;
|
||||
the second 'T corresponds to the result-array element type,
|
||||
which is the same as the f's result type.
|
||||
*)
|
||||
| Map of FunArg<'T> * Exp<'T> * 'T * 'T * Position
|
||||
|
||||
(* reduce (f, acc, array)
|
||||
the 'T argument corresponds to the array element type,
|
||||
which is the same as the f's result type.
|
||||
*)
|
||||
| Reduce of FunArg<'T> * Exp<'T> * Exp<'T> * 'T * Position
|
||||
|
||||
(* replicate(n, a); the 'T argument is the type of the
|
||||
the second expression (i.e., a's type)
|
||||
*)
|
||||
| Replicate of Exp<'T> * Exp<'T> * 'T * Position
|
||||
|
||||
(* filter (p, array)
|
||||
p is a predicate, i.e., a function of type alpha -> bool
|
||||
the 'T argument corresponds to the array element type,
|
||||
which is the same as the f's input type (alpha);
|
||||
*)
|
||||
| Filter of FunArg<'T> * Exp<'T> * 'T * Position
|
||||
|
||||
(* scan (f, acc, array); the 'T argument is as in reduce's case *)
|
||||
| Scan of FunArg<'T> * Exp<'T> * Exp<'T> * 'T * Position
|
||||
|
||||
and Dec<'T> =
|
||||
Dec of string * Exp<'T> * Position
|
||||
|
||||
and FunArg<'T> =
|
||||
FunName of string
|
||||
| Lambda of Type * Param list * Exp<'T> * Position
|
||||
|
||||
(* A function declaration is a tuple of:
|
||||
(i) function name,
|
||||
(ii) return type,
|
||||
(iii) formal arguments names & types,
|
||||
(iv) function's body,
|
||||
(v) Position. *)
|
||||
type FunDec<'T> =
|
||||
FunDec of string * Type * Param list * Exp<'T> * Position
|
||||
|
||||
|
||||
(* Functions for extracting function properties *)
|
||||
let getFunName (FunDec(fid, _, _, _, _)) = fid
|
||||
let getFunRTP (FunDec(_, rtp, _, _, _)) = rtp
|
||||
let getFunArgs (FunDec(_, _, arg, _, _)) = arg
|
||||
let getFunBody (FunDec(_, _, _, bdy, _)) = bdy
|
||||
let getFunPos (FunDec(_, _, _, _, pos)) = pos
|
||||
|
||||
type Prog<'T> = FunDec<'T> list
|
||||
|
||||
(****************************************************)
|
||||
(********** Pretty-Printing Functionality ***********)
|
||||
(****************************************************)
|
||||
|
||||
let rec indent = function
|
||||
| 0 -> ""
|
||||
| n -> " " + indent (n-1)
|
||||
|
||||
let ppParam = function
|
||||
| Param(id, tp) -> ppType tp + " " + id
|
||||
|
||||
let rec ppParams = function
|
||||
| [] -> ""
|
||||
| [bd] -> ppParam bd
|
||||
| bd::l -> ppParam bd + ", " + ppParams l
|
||||
|
||||
let rec ppVal d = function
|
||||
| IntVal n -> sprintf "%i" n
|
||||
| BoolVal b -> sprintf "%b" b
|
||||
| CharVal c -> "'" + toCString (string c) + "'"
|
||||
| ArrayVal (vals, t) -> "{ " + (String.concat ", " (List.map (ppVal d) vals)) + " }"
|
||||
|
||||
let newLine exp = match exp with
|
||||
| Let _ -> ""
|
||||
| _ -> "\n"
|
||||
|
||||
let rec ppExp d = function
|
||||
| Constant(v, _) -> ppVal d v
|
||||
| StringLit(s,_) -> "\"" + toCString s + "\""
|
||||
| ArrayLit(es, t, _) -> "{ " + (String.concat ", " (List.map (ppExp d) es)) + " }"
|
||||
| Var (id, _) -> id
|
||||
| Plus (e1, e2, _) -> "(" + ppExp d e1 + " + " + ppExp d e2 + ")"
|
||||
| Minus (e1, e2, _) -> "(" + ppExp d e1 + " - " + ppExp d e2 + ")"
|
||||
| Times (e1, e2, _) -> "(" + ppExp d e1 + " * " + ppExp d e2 + ")"
|
||||
| Divide (e1, e2, _) -> "(" + ppExp d e1 + " / " + ppExp d e2 + ")"
|
||||
| And (e1, e2, _) -> "(" + ppExp d e1 + " && " + ppExp d e2 + ")"
|
||||
| Or (e1, e2, _) -> "(" + ppExp d e1 + " || " + ppExp d e2 + ")"
|
||||
| Not (e, _) -> "not("+ppExp d e + ")"
|
||||
| Negate (e, _) -> "~(" + ppExp d e + ")"
|
||||
| Equal (e1, e2, _) -> "(" + ppExp d e1 + " == " + ppExp d e2 + ")"
|
||||
| Less (e1, e2, _) -> "(" + ppExp d e1 + " < " + ppExp d e2 + ")"
|
||||
| If (e1, e2, e3, _) -> ("if (" + ppExp d e1 + ")\n" +
|
||||
indent (d+2) + "then " + ppExp (d+2) e2 + "\n" +
|
||||
indent (d+2) + "else " + ppExp (d+2) e3 + "\n" +
|
||||
indent d)
|
||||
| Apply (id, args, _) -> (id + "(" +
|
||||
(String.concat ", " (List.map (ppExp d) args)) + ")")
|
||||
| Let (Dec(id, e1, _), e2, _) -> ("\n" + indent (d+1) + "let " + id + " = " +
|
||||
ppExp (d+2) e1 + " in" + newLine e2 +
|
||||
indent (d+1) + ppExp d e2)
|
||||
| Index (id, e, t, _) -> id + "[" + ppExp d e + "]"
|
||||
| Iota (e, _) -> "iota(" + ppExp d e + ")"
|
||||
| Replicate (e, el, t, pos) -> "replicate(" + ppExp d e + ", " + ppExp d el + ")"
|
||||
| Map (f, e, _, _, _) -> "map(" + ppFunArg d f + ", " + ppExp d e + ")"
|
||||
| Filter (f, arr, _, _) -> ("filter(" + ppFunArg d f + ", " + ppExp d arr + ")")
|
||||
| Reduce (f, el, lst, _, _) ->
|
||||
"reduce(" + ppFunArg d f + ", " + ppExp d el + ", " + ppExp d lst + ")"
|
||||
| Scan (f, acc, arr, _, pos) -> ("scan(" + ppFunArg d f +
|
||||
", " + ppExp d acc +
|
||||
", " + ppExp d arr + ")")
|
||||
| Read (t, _) -> "read(" + ppType t + ")"
|
||||
| Write (e, t, _) -> "write(" + ppExp d e + ")"
|
||||
|
||||
and ppFunArg d = function
|
||||
| FunName s -> s
|
||||
| Lambda (rtp, args, body, _) -> ("fn " + ppType rtp + " (" +
|
||||
ppParams args + ") => " + ppExp (d+2) body)
|
||||
|
||||
(* pretty prints a function declaration *)
|
||||
let ppFun d = function
|
||||
| FunDec(id, rtp, args, body, _) -> ( "fun " + ppType rtp + " " + id +
|
||||
"(" + ppParams args + ") =" +
|
||||
indent (d+1) + ppExp(d+1) body )
|
||||
|
||||
(* Pretty pringint a program *)
|
||||
let ppProg (p : Prog<'T>) = (String.concat "\n\n" (List.map (ppFun 0) p)) + "\n"
|
||||
|
||||
let expPos = function
|
||||
| Constant (_, p) -> p
|
||||
| StringLit (_, p) -> p
|
||||
| ArrayLit (_, _, p) -> p
|
||||
| Var (_, p) -> p
|
||||
| Plus (_, _, p) -> p
|
||||
| Minus (_, _, p) -> p
|
||||
| Equal (_, _, p) -> p
|
||||
| Less (_, _, p) -> p
|
||||
| If (_, _, _, p) -> p
|
||||
| Apply (_, _, p) -> p
|
||||
| Let (_, _, p) -> p
|
||||
| Index (_, _, _, p) -> p
|
||||
| Iota (_, p) -> p
|
||||
| Replicate (_, _, _, p) -> p
|
||||
| Map (_, _, _, _, p) -> p
|
||||
| Filter (_, _, _, p) -> p
|
||||
| Reduce (_, _, _, _, p) -> p
|
||||
| Scan (_, _, _, _, p) -> p
|
||||
| Read (_, p) -> p
|
||||
| Write (_, _, p) -> p
|
||||
| Times (_, _, p) -> p
|
||||
| Divide (_, _, p) -> p
|
||||
| And (_, _, p) -> p
|
||||
| Or (_, _, p) -> p
|
||||
| Not (_, p) -> p
|
||||
| Negate (_, p) -> p
|
||||
|
||||
|
||||
|
||||
type UntypedExp = Exp<unit>
|
||||
type TypedExp = Exp<Type>
|
||||
|
||||
type UntypedDec = Dec<unit>
|
||||
type TypedDec = Dec<Type>
|
||||
|
||||
type UntypedFunDec = FunDec<unit>
|
||||
type TypedFunDec = FunDec<Type>
|
||||
|
||||
type UntypedFunArg = FunArg<unit>
|
||||
type TypedFunArg = FunArg<Type>
|
||||
|
||||
type UntypedProg = Prog<unit>
|
||||
type TypedProg = Prog<Type>
|
||||
@@ -0,0 +1,87 @@
|
||||
module CallGraph
|
||||
|
||||
type CallGraph = (string * string list) list
|
||||
|
||||
|
||||
let callsOf (caller : string)
|
||||
(graph : CallGraph) =
|
||||
match List.tryFind (fun (x,_) -> x = caller) graph with
|
||||
| None -> []
|
||||
| Some (_, calls) -> calls
|
||||
|
||||
let calls (caller : string)
|
||||
(callee : string)
|
||||
(graph : CallGraph) =
|
||||
List.exists (fun x -> x=callee) (callsOf caller graph)
|
||||
|
||||
open AbSyn
|
||||
|
||||
|
||||
(* Remove duplicate elements in a list. Quite slow - O(n^2) -
|
||||
but our lists here will be small. *)
|
||||
let rec nub = function
|
||||
| [] -> []
|
||||
| x::xs -> if List.exists (fun y -> y = x) xs
|
||||
then nub xs
|
||||
else x :: nub xs
|
||||
|
||||
let rec expCalls = function
|
||||
| Constant _ -> []
|
||||
| StringLit _ -> []
|
||||
| ArrayLit (es, _, _) -> List.concat (List.map expCalls es)
|
||||
| Var _ -> []
|
||||
| Plus (e1, e2, _) -> expCalls e1 @ expCalls e2
|
||||
| Minus (e1, e2, _) -> expCalls e1 @ expCalls e2
|
||||
| Equal (e1, e2, _) -> expCalls e1 @ expCalls e2
|
||||
| Less (e1, e2, _) -> expCalls e1 @ expCalls e2
|
||||
| If (e1, e2, e3, _) -> expCalls e1 @ expCalls e2 @ expCalls e3
|
||||
| Apply (fname, es, _) -> fname :: List.concat (List.map expCalls es)
|
||||
| Let ( Dec(_, e, _), body, _) -> expCalls e @ expCalls body
|
||||
| Index (_, e, _, _) -> expCalls e
|
||||
| Iota (e, _) -> expCalls e
|
||||
| Map (farg, e, _, _, _) -> fargCalls farg @ expCalls e
|
||||
| Filter (farg, e, _, _) -> fargCalls farg @ expCalls e
|
||||
| Reduce (farg, e1, e2, _, _) -> fargCalls farg @ expCalls e1 @ expCalls e2
|
||||
| Replicate (n, e, _, _) -> expCalls n @ expCalls e
|
||||
| Scan (farg, e1, e2, _, _) -> fargCalls farg @ expCalls e1 @ expCalls e2
|
||||
| Times (e1, e2, _) -> expCalls e1 @ expCalls e2
|
||||
| Divide (e1, e2, _) -> expCalls e1 @ expCalls e2
|
||||
| And (e1, e2, _) -> expCalls e1 @ expCalls e2
|
||||
| Or (e1, e2, _) -> expCalls e1 @ expCalls e2
|
||||
| Not (e, _) -> expCalls e
|
||||
| Negate (e, _) -> expCalls e
|
||||
| Read _ -> []
|
||||
| Write (e, _, _) -> expCalls e
|
||||
|
||||
and fargCalls = function
|
||||
| Lambda (_, _, body, _) -> expCalls body
|
||||
| FunName s -> [s]
|
||||
|
||||
(* Get the direct function calls of a single function *)
|
||||
|
||||
let functionCalls = function
|
||||
| FunDec (fname, _, _, body, _) -> (fname, nub (expCalls body))
|
||||
|
||||
(* Expand the direct function call graph to its transitive closure. *)
|
||||
let rec transitiveClosure (graph : CallGraph) =
|
||||
let grow ((caller : string),
|
||||
(callees : string list)) =
|
||||
let calleecalls =
|
||||
List.concat (List.map (fun callee ->
|
||||
callsOf callee graph) callees)
|
||||
let newCalls = (List.filter (fun call ->
|
||||
not (List.exists (fun x -> x = call) callees)
|
||||
) calleecalls)
|
||||
if List.isEmpty newCalls
|
||||
then ((caller, callees),
|
||||
false)
|
||||
else ((caller, callees @ nub newCalls),
|
||||
true)
|
||||
let (graph', changes) = List.unzip (List.map grow graph)
|
||||
let changed = List.exists (fun x -> x) changes
|
||||
if changed
|
||||
then transitiveClosure graph'
|
||||
else graph'
|
||||
|
||||
let callGraph (prog : TypedProg) =
|
||||
transitiveClosure (List.map functionCalls prog)
|
||||
@@ -0,0 +1,877 @@
|
||||
(* Code generator for Fasto *)
|
||||
|
||||
module CodeGen
|
||||
|
||||
(*
|
||||
compile : TypedProg -> Mips.Instruction list
|
||||
|
||||
(* for debugging *)
|
||||
compileExp : TypedExp
|
||||
-> SymTab<Mips.reg>
|
||||
-> Mips.reg
|
||||
-> Mips.Instruction list
|
||||
*)
|
||||
|
||||
open AbSyn
|
||||
|
||||
exception MyError of string * Position
|
||||
|
||||
type VarTable = SymTab.SymTab<Mips.reg>
|
||||
|
||||
(* Name generator for labels and temporary symbolic registers *)
|
||||
(* Example usage: val tmp = newName "tmp" (* might produce _tmp_5_ *) *)
|
||||
|
||||
let mutable counter = 0
|
||||
|
||||
let newName base_name =
|
||||
counter <- counter + 1
|
||||
"_" + base_name + "_" + string counter + "_"
|
||||
|
||||
let newReg reg_name = Mips.RS (newName reg_name)
|
||||
|
||||
let newLab lab_name = newName lab_name
|
||||
|
||||
(* Table storing all string literals, with labels given to them *)
|
||||
let stringTable : ((Mips.addr*string) list) ref = ref []
|
||||
(* could also contain "\n", ",", "Index out of bounds in line ", but the
|
||||
format is a bit different (length and dummy pointer come first) *)
|
||||
|
||||
(* Building a string in the heap, including initialisation code *)
|
||||
let buildString ( label : Mips.addr
|
||||
, str : string
|
||||
) : (Mips.Instruction list * Mips.Instruction list) =
|
||||
let data = [ Mips.ALIGN 2 (* means: word-align *)
|
||||
; Mips.LABEL label (* pointer *)
|
||||
; Mips.SPACE 4 (* sizeof(Int) *)
|
||||
; Mips.ASCIIZ str]
|
||||
let initR = Mips.RS (label + "_init")
|
||||
let addrR = Mips.RS (label + "_addr")
|
||||
let initcode = [ Mips.LA(addrR, label)
|
||||
; Mips.LI(initR, String.length str)
|
||||
; Mips.SW(initR, addrR, 0) ]
|
||||
(initcode, data)
|
||||
|
||||
(* Link register *)
|
||||
let RA = Mips.RN 31
|
||||
(* Register for stack pointer *)
|
||||
let SP = Mips.RN 29
|
||||
(* Register for heap pointer *)
|
||||
let HP = Mips.RN 28
|
||||
(* Constant-zero register *)
|
||||
let RZ = Mips.RN 0
|
||||
|
||||
(* General scratch-pad registers *)
|
||||
let RN2 = Mips.RN 2
|
||||
let RN4 = Mips.RN 4
|
||||
let RN5 = Mips.RN 5
|
||||
let RN6 = Mips.RN 6
|
||||
|
||||
(* Suggested register division *)
|
||||
let minReg = 2 (* lowest usable register *)
|
||||
let maxCaller = 15 (* highest caller-saves register *)
|
||||
let maxReg = 25 (* highest allocatable register *)
|
||||
|
||||
(* Syscall numbers for MARS, to be put in $2 *)
|
||||
let sysPrintInt = 1 (* print integer in $4 *)
|
||||
let sysPrintString = 4 (* print NUL-terminated string starting at $4 *)
|
||||
let sysReadInt = 5 (* read integer into $2 *)
|
||||
let sysExit = 10 (* terminate execution *)
|
||||
let sysPrintChar = 11 (* print character in $4 *)
|
||||
let sysReadChar = 12 (* read character into $2 *)
|
||||
|
||||
(* Determine the size of an element in an array based on its type *)
|
||||
type ElemSize = ESByte | ESWord
|
||||
|
||||
let getElemSize (tp : Type) : ElemSize =
|
||||
match tp with
|
||||
| Char -> ESByte
|
||||
| Bool -> ESByte
|
||||
| _ -> ESWord
|
||||
|
||||
let elemSizeToInt (elmsz : ElemSize) : int =
|
||||
match elmsz with
|
||||
| ESByte -> 1
|
||||
| ESWord -> 4
|
||||
|
||||
(* Pick the correct instruction from the element size. *)
|
||||
let mipsLoad elem_size = match elem_size with
|
||||
| ESByte -> Mips.LB
|
||||
| ESWord -> Mips.LW
|
||||
|
||||
let mipsStore elem_size = match elem_size with
|
||||
| ESByte -> Mips.SB
|
||||
| ESWord -> Mips.SW
|
||||
|
||||
(* generates the code to check that the array index is within bounds *)
|
||||
let checkBounds ( arr_beg : Mips.reg
|
||||
, ind_reg : Mips.reg
|
||||
, (line : int, c : int)
|
||||
) : Mips.Instruction list =
|
||||
let size_reg = newReg "size_reg"
|
||||
let tmp_reg = newReg "tmp_reg"
|
||||
let err_lab = newLab "error_lab"
|
||||
let safe_lab = newLab "safe_lab"
|
||||
[ Mips.LW(size_reg, arr_beg, 0)
|
||||
; Mips.BGEZ(ind_reg, safe_lab) (* check that ind_reg >= 0 *)
|
||||
; Mips.LABEL(err_lab)
|
||||
; Mips.LI(RN5, line)
|
||||
; Mips.LA(RN6, "_Msg_IllegalIndex_")
|
||||
; Mips.J "_RuntimeError_"
|
||||
; Mips.LABEL(safe_lab)
|
||||
; Mips.SUB(tmp_reg, ind_reg, size_reg)
|
||||
; Mips.BGEZ(tmp_reg, err_lab) (* check that ind_reg < -size_reg *)
|
||||
]
|
||||
|
||||
(* dynalloc(size_reg, place, ty) generates code for allocating arrays of heap
|
||||
memory by incrementing the HP register (heap pointer) by a number of words.
|
||||
The arguments for this function are as follows:
|
||||
|
||||
size_reg: contains the logical array size (number of array elements)
|
||||
place: will contain the address of new allocation (old HP)
|
||||
ty: char/bool elements take 1 byte, int elements take 4 bytes
|
||||
*)
|
||||
let dynalloc (size_reg : Mips.reg,
|
||||
place : Mips.reg,
|
||||
ty : Type )
|
||||
: Mips.Instruction list =
|
||||
let tmp_reg = newReg "tmp"
|
||||
|
||||
(* Use old HP as allocation address. *)
|
||||
let code1 = [ Mips.MOVE (place, HP) ]
|
||||
|
||||
(* For char/bool: Align address to 4-byte boundary by rounding up. *)
|
||||
(* (By adding 3 and rounding down using SRA/SLL.) *)
|
||||
(* For int and arrays: Multiply logical size by 4, no alignment. *)
|
||||
let code2 =
|
||||
match getElemSize ty with
|
||||
| ESByte -> [ Mips.ADDI(tmp_reg, size_reg, 3)
|
||||
; Mips.SRA (tmp_reg, tmp_reg, 2)
|
||||
; Mips.SLL (tmp_reg, tmp_reg, 2) ]
|
||||
| ESWord -> [ Mips.SLL (tmp_reg, size_reg, 2) ]
|
||||
|
||||
(* Make space for array size (+4). Increase HP. *)
|
||||
(* Save size of allocation in header. *)
|
||||
let code3 =
|
||||
[ Mips.ADDI (tmp_reg, tmp_reg, 4)
|
||||
; Mips.ADD (HP, HP, tmp_reg)
|
||||
; Mips.SW (size_reg, place, 0) ]
|
||||
|
||||
code1 @ code2 @ code3
|
||||
|
||||
(* Pushing arguments on the stack: *)
|
||||
(* For each register 'r' in 'rs', copy them to registers from
|
||||
'firstReg' and counting up. Return the full code and the next unused
|
||||
register (firstReg + num_args). *)
|
||||
let applyRegs ( fid : Mips.addr
|
||||
, args : Mips.reg list
|
||||
, place: Mips.reg
|
||||
, pos : Position )
|
||||
: Mips.Instruction list =
|
||||
let regs_num = List.length args
|
||||
let caller_regs = List.map (fun n -> Mips.RN (n + minReg)) [0..regs_num-1]
|
||||
// List.tabulate (regs_num, fun n -> n + minReg)
|
||||
(* zipWith Mips.MOVE =
|
||||
zipWith (fun (regDest, regSrc) -> Mips.MOVE (regDest, regSrc)) *)
|
||||
let move_code = List.map Mips.MOVE (List.zip caller_regs args)
|
||||
if regs_num > maxCaller - minReg
|
||||
then raise (MyError("Number of arguments passed to " + fid +
|
||||
" exceeds number of caller registers", pos))
|
||||
else move_code @ [ Mips.JAL(fid,caller_regs); Mips.MOVE(place, RN2) ]
|
||||
|
||||
|
||||
(* Compile 'e' under bindings 'vtable', putting the result in register 'place'. *)
|
||||
let rec compileExp (e : TypedExp)
|
||||
(vtable : VarTable)
|
||||
(place : Mips.reg)
|
||||
: Mips.Instruction list =
|
||||
match e with
|
||||
| Constant (IntVal n, pos) ->
|
||||
if n < 0 then
|
||||
compileExp (Negate (Constant (IntVal (-n), pos), pos)) vtable place
|
||||
else if n < 32768 then
|
||||
[ Mips.LI (place, n) ]
|
||||
else
|
||||
[ Mips.LUI (place, n / 65536)
|
||||
; Mips.ORI (place, place, n % 65536) ]
|
||||
| Constant (BoolVal p, _) ->
|
||||
(* TODO project task 1: represent `true`/`false` values as `1`/`0` *)
|
||||
failwith "Unimplemented code generation of boolean constants"
|
||||
| Constant (CharVal c, pos) -> [ Mips.LI (place, int c) ]
|
||||
|
||||
(* Create/return a label here, collect all string literals of the program
|
||||
(in stringTable), and create them in the data section before the heap
|
||||
(Mips.ASCIIZ) *)
|
||||
| StringLit (strLit, pos) ->
|
||||
(* Convert string literal into label; only use valid characters. *)
|
||||
let normalChars0 = //String.filter System.Char.IsLetterOrDigit strLit
|
||||
String.map (fun c -> if System.Char.IsLetterOrDigit c then c else 'a') strLit
|
||||
let normalChars = normalChars0 + "__str__"
|
||||
let label = newLab (normalChars.Substring (0, 7))
|
||||
let () = stringTable := (label, strLit)::(!stringTable)
|
||||
[ Mips.LA (place, label)
|
||||
; Mips.COMMENT (label + ": string \"" + toCString strLit + "\"") ]
|
||||
|
||||
| Constant (ArrayVal (vs, tp), pos) ->
|
||||
(* Create corresponding ArrayLit expression to re-use code. *)
|
||||
let arraylit = ArrayLit (List.map (fun v -> Constant (v, pos)) vs, tp, pos)
|
||||
compileExp arraylit vtable place
|
||||
|
||||
| ArrayLit (elems, tp, pos) ->
|
||||
let elem_size = getElemSize tp
|
||||
let size_reg = newReg "size_reg"
|
||||
let addr_reg = newReg "addr_reg"
|
||||
let tmp_reg = newReg "tmp_reg"
|
||||
|
||||
(* Store size of literal in size_reg, dynamically allocate that. *)
|
||||
(* Let addr_reg contain the address for the first array element. *)
|
||||
let header = [ Mips.LI (size_reg, List.length elems) ] @
|
||||
dynalloc (size_reg, place, tp) @
|
||||
[ Mips.ADDI (addr_reg, place, 4) ]
|
||||
|
||||
let compileElem elem_exp =
|
||||
let elem_code = compileExp elem_exp vtable tmp_reg
|
||||
elem_code @
|
||||
[ mipsStore elem_size (tmp_reg, addr_reg, 0)
|
||||
; Mips.ADDI (addr_reg, addr_reg, elemSizeToInt elem_size) ]
|
||||
|
||||
let elems_code = List.concat (List.map compileElem elems)
|
||||
header @ elems_code
|
||||
|
||||
| Var (vname, pos) ->
|
||||
match SymTab.lookup vname vtable with
|
||||
| None -> raise (MyError ("Name " + vname + " not found", pos))
|
||||
| Some reg_name -> [Mips.MOVE (place, reg_name)]
|
||||
|
||||
| Plus (e1, e2, pos) ->
|
||||
let t1 = newReg "plus_L"
|
||||
let t2 = newReg "plus_R"
|
||||
let code1 = compileExp e1 vtable t1
|
||||
let code2 = compileExp e2 vtable t2
|
||||
code1 @ code2 @ [Mips.ADD (place,t1,t2)]
|
||||
|
||||
| Minus (e1, e2, pos) ->
|
||||
let t1 = newReg "minus_L"
|
||||
let t2 = newReg "minus_R"
|
||||
let code1 = compileExp e1 vtable t1
|
||||
let code2 = compileExp e2 vtable t2
|
||||
code1 @ code2 @ [Mips.SUB (place,t1,t2)]
|
||||
|
||||
(* TODO project task 1:
|
||||
Look in `AbSyn.fs` for the expression constructors `Times`, ...
|
||||
`Times` is very similar to `Plus`/`Minus`.
|
||||
For `Divide`, you may ignore division by zero for a quick first
|
||||
version, but remember to come back and clean it up later.
|
||||
`Not` and `Negate` are simpler; you can use `Mips.XORI` for `Not`
|
||||
*)
|
||||
| Times (_, _, _) ->
|
||||
failwith "Unimplemented code generation of multiplication"
|
||||
|
||||
| Divide (_, _, _) ->
|
||||
failwith "Unimplemented code generation of division"
|
||||
|
||||
| Not (_, _) ->
|
||||
failwith "Unimplemented code generation of not"
|
||||
|
||||
| Negate (_, _) ->
|
||||
failwith "Unimplemented code generation of negate"
|
||||
|
||||
| Let (dec, e1, pos) ->
|
||||
let (code1, vtable1) = compileDec dec vtable
|
||||
let code2 = compileExp e1 vtable1 place
|
||||
code1 @ code2
|
||||
|
||||
| If (e1, e2, e3, pos) ->
|
||||
let thenLabel = newLab "then"
|
||||
let elseLabel = newLab "else"
|
||||
let endLabel = newLab "endif"
|
||||
let code1 = compileCond e1 vtable thenLabel elseLabel
|
||||
let code2 = compileExp e2 vtable place
|
||||
let code3 = compileExp e3 vtable place
|
||||
code1 @ [Mips.LABEL thenLabel] @ code2 @
|
||||
[ Mips.J endLabel; Mips.LABEL elseLabel ] @
|
||||
code3 @ [Mips.LABEL endLabel]
|
||||
|
||||
(* special case for length *)
|
||||
| Apply ("length", [arr], pos) ->
|
||||
let arr_addr = newReg "len_arr"
|
||||
let code1 = compileExp arr vtable arr_addr
|
||||
code1 @ [ Mips.LW(place,arr_addr, 0) ]
|
||||
| Apply (f, args, pos) ->
|
||||
(* Convention: args in regs (2..15), result in reg 2 *)
|
||||
let compileArg arg =
|
||||
let arg_reg = newReg "arg"
|
||||
(arg_reg, compileExp arg vtable arg_reg)
|
||||
let (arg_regs, argcode) = List.unzip (List.map compileArg args)
|
||||
let applyCode = applyRegs(f, arg_regs, place, pos)
|
||||
List.concat argcode @ (* Evaluate args *)
|
||||
applyCode (* Jump to function and store result in place *)
|
||||
|
||||
(* dirty I/O. Read and Write: supported for basic types: Int, Char,
|
||||
Bool via system calls. Write of an Array(Chars) is also
|
||||
supported. The others are the user's responsibility.
|
||||
*)
|
||||
| Read(tp, pos) ->
|
||||
match tp with
|
||||
| Int -> [ Mips.JAL ("getint", [RN2])
|
||||
; Mips.MOVE(place, RN2)
|
||||
]
|
||||
| Char -> [ Mips.JAL ("getchar", [RN2])
|
||||
; Mips.MOVE(place, RN2)
|
||||
]
|
||||
| Bool ->
|
||||
(* Note: the following inputs booleans as integers, with 0
|
||||
interpreted as false and everything else as true. This
|
||||
differs from the interpreter! *)
|
||||
let tl = newLab "true_lab"
|
||||
let fl = newLab "false_lab"
|
||||
let ml = newLab "merge_lab"
|
||||
let v = newReg "bool_var"
|
||||
[ Mips.JAL ("getint", [RN2])
|
||||
; Mips.MOVE(v, RN2)
|
||||
; Mips.BEQ (v, RZ,fl)
|
||||
; Mips.J tl
|
||||
; Mips.LABEL fl
|
||||
; Mips.MOVE(place, RZ)
|
||||
; Mips.J ml
|
||||
; Mips.LABEL tl
|
||||
; Mips.LI (place, 1)
|
||||
; Mips.J ml
|
||||
; Mips.LABEL ml
|
||||
]
|
||||
| _ -> raise (MyError("Read on an incompatible type: " + ppType tp, pos))
|
||||
|
||||
| Write(e, tp, pos) ->
|
||||
let tmp = newReg "tmp"
|
||||
let codeexp = compileExp e vtable tmp @ [ Mips.MOVE (place, tmp) ]
|
||||
match tp with
|
||||
| Int -> codeexp @ [ Mips.MOVE(RN2,place); Mips.JAL("putint", [RN2]) ]
|
||||
| Char -> codeexp @ [ Mips.MOVE(RN2,place); Mips.JAL("putchar",[RN2]) ]
|
||||
| Bool ->
|
||||
let tlab = newLab "wBoolF"
|
||||
codeexp @
|
||||
[ Mips.LA (RN2, "_true")
|
||||
; Mips.BNE (place, RZ, tlab)
|
||||
; Mips.LA (RN2, "_false")
|
||||
; Mips.LABEL tlab
|
||||
; Mips.JAL ("putstring", [RN2])
|
||||
]
|
||||
|
||||
| Array Char ->
|
||||
codeexp @ [ Mips.MOVE (RN2, tmp)
|
||||
; Mips.JAL("putstring", [RN2]) ]
|
||||
| _ -> raise (MyError("Write on an incompatible type: " + ppType tp, pos))
|
||||
|
||||
(* Comparison checking, later similar code for And and Or. *)
|
||||
| Equal (e1, e2, pos) ->
|
||||
let t1 = newReg "eq_L"
|
||||
let t2 = newReg "eq_R"
|
||||
let code1 = compileExp e1 vtable t1
|
||||
let code2 = compileExp e2 vtable t2
|
||||
let falseLabel = newLab "false"
|
||||
code1 @ code2 @
|
||||
[ Mips.LI (place, 0)
|
||||
; Mips.BNE (t1,t2,falseLabel)
|
||||
; Mips.LI (place, 1)
|
||||
; Mips.LABEL falseLabel
|
||||
]
|
||||
|
||||
| Less (e1, e2, pos) ->
|
||||
let t1 = newReg "lt_L"
|
||||
let t2 = newReg "lt_R"
|
||||
let code1 = compileExp e1 vtable t1
|
||||
let code2 = compileExp e2 vtable t2
|
||||
code1 @ code2 @ [Mips.SLT (place,t1,t2)]
|
||||
|
||||
(* TODO project task 1:
|
||||
Look in `AbSyn.fs` for the expression constructors of `And` and `Or`.
|
||||
The implementation of `And` and `Or` is more complicated than `Plus`
|
||||
because you need to ensure the short-circuit semantics, e.g.,
|
||||
in `e1 || e2` if the execution of `e1` will evaluate to `true` then
|
||||
the code of `e2` must not be executed. Similarly for `And` (&&).
|
||||
*)
|
||||
| And (_, _, _) ->
|
||||
failwith "Unimplemented code generation of &&"
|
||||
|
||||
| Or (_, _, _) ->
|
||||
failwith "Unimplemented code generation of ||"
|
||||
|
||||
(* Indexing:
|
||||
1. generate code to compute the index
|
||||
2. check index within bounds
|
||||
3. add the start address with the index
|
||||
4. get the element at that address
|
||||
*)
|
||||
| Index (arr_name, i_exp, ty, pos) ->
|
||||
let ind_reg = newReg "arr_ind"
|
||||
let ind_code = compileExp i_exp vtable ind_reg
|
||||
let arr_reg = newReg "arr_reg"
|
||||
|
||||
(* Let arr_reg be the start of the data segment *)
|
||||
let arr_beg =
|
||||
match SymTab.lookup arr_name vtable with
|
||||
| None -> raise (MyError ("Name " + arr_name + " not found", pos))
|
||||
| Some reg_name -> reg_name
|
||||
let init_code = [ Mips.ADDI(arr_reg, arr_beg, 4) ]
|
||||
|
||||
(* code to check bounds *)
|
||||
let check_code = checkBounds(arr_beg, ind_reg, pos)
|
||||
|
||||
(* for INT/ARRAY: ind *= 4 else ind is unchanged *)
|
||||
(* array_var += index; place = *array_var *)
|
||||
let load_code =
|
||||
match getElemSize ty with
|
||||
| ESByte -> [ Mips.ADD(arr_reg, arr_reg, ind_reg)
|
||||
; Mips.LB(place, arr_reg, 0) ]
|
||||
| ESWord -> [ Mips.SLL(ind_reg, ind_reg, 2)
|
||||
; Mips.ADD(arr_reg, arr_reg, ind_reg)
|
||||
; Mips.LW(place, arr_reg, 0) ]
|
||||
ind_code @ init_code @ check_code @ load_code
|
||||
|
||||
(* Second-Order Array Combinators (SOACs):
|
||||
iota, map, reduce
|
||||
*)
|
||||
| Iota (n_exp, (line, _)) ->
|
||||
let size_reg = newReg "size_reg"
|
||||
let n_code = compileExp n_exp vtable size_reg
|
||||
(* size_reg is now the integer n. *)
|
||||
|
||||
(* Check that array size N >= 0:
|
||||
if N >= 0 then jumpto safe_lab
|
||||
jumpto "_IllegalArrSizeError_"
|
||||
safe_lab: ...
|
||||
*)
|
||||
let safe_lab = newLab "safe_lab"
|
||||
let checksize = [ Mips.BGEZ (size_reg, safe_lab)
|
||||
; Mips.LI (RN5, line)
|
||||
; Mips.LA (RN6, "_Msg_IllegalArraySize_")
|
||||
; Mips.J "_RuntimeError_"
|
||||
; Mips.LABEL (safe_lab)
|
||||
]
|
||||
|
||||
let addr_reg = newReg "addr_reg"
|
||||
let i_reg = newReg "i_reg"
|
||||
let init_regs = [ Mips.ADDI (addr_reg, place, 4)
|
||||
; Mips.MOVE (i_reg, RZ) ]
|
||||
(* addr_reg is now the position of the first array element. *)
|
||||
|
||||
(* Run a loop. Keep jumping back to loop_beg until it is not the
|
||||
case that i_reg < size_reg, and then jump to loop_end. *)
|
||||
let loop_beg = newLab "loop_beg"
|
||||
let loop_end = newLab "loop_end"
|
||||
let tmp_reg = newReg "tmp_reg"
|
||||
let loop_header = [ Mips.LABEL (loop_beg)
|
||||
; Mips.SUB (tmp_reg, i_reg, size_reg)
|
||||
; Mips.BGEZ (tmp_reg, loop_end)
|
||||
]
|
||||
(* iota is just 'arr[i] = i'. arr[i] is addr_reg. *)
|
||||
let loop_iota = [ Mips.SW (i_reg, addr_reg, 0) ]
|
||||
let loop_footer = [ Mips.ADDI (addr_reg, addr_reg, 4)
|
||||
; Mips.ADDI (i_reg, i_reg, 1)
|
||||
; Mips.J loop_beg
|
||||
; Mips.LABEL loop_end
|
||||
]
|
||||
n_code
|
||||
@ checksize
|
||||
@ dynalloc (size_reg, place, Int)
|
||||
@ init_regs
|
||||
@ loop_header
|
||||
@ loop_iota
|
||||
@ loop_footer
|
||||
|
||||
| Map (farg, arr_exp, elem_type, ret_type, pos) ->
|
||||
let size_reg = newReg "size_reg" (* size of input/output array *)
|
||||
let arr_reg = newReg "arr_reg" (* address of array *)
|
||||
let elem_reg = newReg "elem_reg" (* address of single element *)
|
||||
let res_reg = newReg "res_reg"
|
||||
let arr_code = compileExp arr_exp vtable arr_reg
|
||||
|
||||
let get_size = [ Mips.LW (size_reg, arr_reg, 0) ]
|
||||
|
||||
let addr_reg = newReg "addr_reg" (* address of element in new array *)
|
||||
let i_reg = newReg "i_reg"
|
||||
let init_regs = [ Mips.ADDI (addr_reg, place, 4)
|
||||
; Mips.MOVE (i_reg, RZ)
|
||||
; Mips.ADDI (elem_reg, arr_reg, 4)
|
||||
]
|
||||
let loop_beg = newLab "loop_beg"
|
||||
let loop_end = newLab "loop_end"
|
||||
let tmp_reg = newReg "tmp_reg"
|
||||
let loop_header = [ Mips.LABEL (loop_beg)
|
||||
; Mips.SUB (tmp_reg, i_reg, size_reg)
|
||||
; Mips.BGEZ (tmp_reg, loop_end) ]
|
||||
(* map is 'arr[i] = f(old_arr[i])'. *)
|
||||
let src_size = getElemSize elem_type
|
||||
let dst_size = getElemSize ret_type
|
||||
let loop_map =
|
||||
[ mipsLoad src_size (res_reg, elem_reg, 0)
|
||||
; Mips.ADDI(elem_reg, elem_reg, elemSizeToInt src_size)
|
||||
]
|
||||
@ applyFunArg(farg, [res_reg], vtable, res_reg, pos)
|
||||
@
|
||||
[ mipsStore dst_size (res_reg, addr_reg, 0)
|
||||
; Mips.ADDI (addr_reg, addr_reg, elemSizeToInt dst_size)
|
||||
]
|
||||
|
||||
let loop_footer =
|
||||
[ Mips.ADDI (i_reg, i_reg, 1)
|
||||
; Mips.J loop_beg
|
||||
; Mips.LABEL loop_end
|
||||
]
|
||||
arr_code
|
||||
@ get_size
|
||||
@ dynalloc (size_reg, place, ret_type)
|
||||
@ init_regs
|
||||
@ loop_header
|
||||
@ loop_map
|
||||
@ loop_footer
|
||||
|
||||
(* reduce(f, acc, {x1, x2, ...xn}) = f(f(f(acc,x1),x2),...xn) *)
|
||||
| Reduce (binop, acc_exp, arr_exp, tp, pos) ->
|
||||
let arr_reg = newReg "arr_reg" (* address of array *)
|
||||
let size_reg = newReg "size_reg" (* size of input array *)
|
||||
let i_reg = newReg "ind_var" (* loop counter *)
|
||||
let tmp_reg = newReg "tmp_reg" (* several purposes *)
|
||||
let loop_beg = newLab "loop_beg"
|
||||
let loop_end = newLab "loop_end"
|
||||
|
||||
let arr_code = compileExp arr_exp vtable arr_reg
|
||||
let header1 = [ Mips.LW(size_reg, arr_reg, 0) ]
|
||||
|
||||
(* Compile initial value into place (will be updated below) *)
|
||||
let acc_code = compileExp acc_exp vtable place
|
||||
|
||||
(* Set arr_reg to address of first element instead. *)
|
||||
(* Set i_reg to 0. While i < size_reg, loop. *)
|
||||
let loop_code =
|
||||
[ Mips.ADDI(arr_reg, arr_reg, 4)
|
||||
; Mips.MOVE(i_reg, RZ)
|
||||
; Mips.LABEL(loop_beg)
|
||||
; Mips.SUB(tmp_reg, i_reg, size_reg)
|
||||
; Mips.BGEZ(tmp_reg, loop_end)
|
||||
]
|
||||
(* Load arr[i] into tmp_reg *)
|
||||
let elem_size = getElemSize tp
|
||||
let load_code =
|
||||
[ mipsLoad elem_size (tmp_reg, arr_reg, 0)
|
||||
; Mips.ADDI (arr_reg, arr_reg, elemSizeToInt elem_size)
|
||||
]
|
||||
(* place := binop(place, tmp_reg) *)
|
||||
let apply_code =
|
||||
applyFunArg(binop, [place; tmp_reg], vtable, place, pos)
|
||||
|
||||
arr_code @ header1 @ acc_code @ loop_code @ load_code @ apply_code @
|
||||
[ Mips.ADDI(i_reg, i_reg, 1)
|
||||
; Mips.J loop_beg
|
||||
; Mips.LABEL loop_end
|
||||
]
|
||||
|
||||
(* TODO project task 2:
|
||||
`replicate (n, a)`
|
||||
`filter (f, arr)`
|
||||
`scan (f, ne, arr)`
|
||||
Look in `AbSyn.fs` for the shape of expression constructors
|
||||
`Replicate`, `Filter`, `Scan`.
|
||||
General Hint: write down on a piece of paper the C-like pseudocode
|
||||
for implementing them, then translate that to Mips pseudocode.
|
||||
To allocate heap space for an array you may use `dynalloc` defined
|
||||
above. For example, if `sz_reg` is a register containing an integer `n`,
|
||||
and `ret_type` is the element-type of the to-be-allocated array, then
|
||||
`dynalloc (sz_reg, arr_reg, ret_type)` will alocate enough space for
|
||||
an n-element array of element-type `ret_type` (including the first
|
||||
word that holds the length, and the necessary allignment padding), and
|
||||
will place in register `arr_reg` the start address of the new array.
|
||||
Since you need to allocate space for the result arrays of `Replicate`,
|
||||
`Map` and `Scan`, then `arr_reg` should probably be `place` ...
|
||||
|
||||
`replicate(n,a)`: You should allocate a new (result) array, and execute a
|
||||
loop of count `n`, in which you store the value hold into the register
|
||||
corresponding to `a` into each memory location corresponding to an
|
||||
element of the result array.
|
||||
If `n` is less than `0` then remember to terminate the program with
|
||||
an error -- see implementation of `iota`.
|
||||
*)
|
||||
| Replicate (_, _, _, _) ->
|
||||
failwith "Unimplemented code generation of replicate"
|
||||
|
||||
(* TODO project task 2: see also the comment to replicate.
|
||||
(a) `filter(f, arr)`: has some similarity with the implementation of map.
|
||||
(b) Use `applyFunArg` to call `f(a)` in a loop, for every element `a` of `arr`.
|
||||
(c) If `f(a)` succeeds (result in the `true` value) then (and only then):
|
||||
- set the next element of the result array to `a`, and
|
||||
- increment a counter (initialized before the loop)
|
||||
(d) It is useful to maintain two array iterators: one for the input array `arr`
|
||||
and one for the result array. (The latter increases slower because
|
||||
some of the elements of the input array are skipped because they fail
|
||||
under the predicate).
|
||||
(e) The last step (after the loop writing the elments of the result array)
|
||||
is to update the logical size of the result array to the value of the
|
||||
counter computed in step (c). You do this of course with a
|
||||
`Mips.SW(counter_reg, place, 0)` instruction.
|
||||
*)
|
||||
| Filter (_, _, _, _) ->
|
||||
failwith "Unimplemented code generation of filter"
|
||||
|
||||
(* TODO project task 2: see also the comment to replicate.
|
||||
`scan(f, ne, arr)`: you can inspire yourself from the implementation of
|
||||
`reduce`, but in the case of `scan` you will need to also maintain
|
||||
an iterator through the result array, and write the accumulator in
|
||||
the current location of the result iterator at every iteration of
|
||||
the loop.
|
||||
*)
|
||||
| Scan (_, _, _, _, _) ->
|
||||
failwith "Unimplemented code generation of scan"
|
||||
|
||||
and applyFunArg ( ff : TypedFunArg
|
||||
, args : Mips.reg list
|
||||
, vtable : VarTable
|
||||
, place : Mips.reg
|
||||
, pos : Position
|
||||
) : Mips.Instruction list =
|
||||
match ff with
|
||||
| FunName s ->
|
||||
let tmp_reg = newReg "tmp_reg"
|
||||
applyRegs(s, args, tmp_reg, pos) @ [Mips.MOVE(place, tmp_reg)]
|
||||
|
||||
| Lambda (_, parms, body, lampos) ->
|
||||
let rec bindParams parms args vtable' =
|
||||
match (parms, args) with
|
||||
| (Param (pname,_)::parms', arg::args') ->
|
||||
bindParams parms' args' (SymTab.bind pname arg vtable')
|
||||
| _ -> vtable'
|
||||
let vtable' = bindParams parms args vtable
|
||||
let t = newReg "fun_arg_res"
|
||||
compileExp body vtable' t @ [ Mips.MOVE(place, t) ]
|
||||
|
||||
(* compile condition *)
|
||||
and compileCond (c : TypedExp)
|
||||
(vtable : VarTable)
|
||||
(tlab : Mips.addr)
|
||||
(flab : Mips.addr)
|
||||
: Mips.Instruction list =
|
||||
let t1 = newReg "cond"
|
||||
let code1 = compileExp c vtable t1
|
||||
code1 @ [Mips.BNE (t1, RZ, tlab); Mips.J flab]
|
||||
|
||||
(* compile let declaration *)
|
||||
and compileDec (dec : TypedDec)
|
||||
(vtable : VarTable)
|
||||
: (Mips.Instruction list * VarTable) =
|
||||
let (Dec (s,e,pos)) = dec
|
||||
let t = newReg "letBind"
|
||||
let code = compileExp e vtable t
|
||||
let new_vtable = SymTab.bind s t vtable
|
||||
(code, new_vtable)
|
||||
|
||||
(* code for saving and restoring callee-saves registers *)
|
||||
let rec stackSave (currentReg : int)
|
||||
(maxReg : int)
|
||||
(savecode : Mips.Instruction list)
|
||||
(restorecode : Mips.Instruction list)
|
||||
(offset : int)
|
||||
: (Mips.Instruction list * Mips.Instruction list * int) =
|
||||
if currentReg > maxReg
|
||||
then (savecode, restorecode, offset) (* done *)
|
||||
else stackSave (currentReg+1)
|
||||
maxReg
|
||||
(Mips.SW (Mips.RN currentReg, SP, offset)
|
||||
:: savecode) (* save register *)
|
||||
(Mips.LW (Mips.RN currentReg, SP, offset)
|
||||
:: restorecode) (* restore register *)
|
||||
(offset-4) (* adjust offset *)
|
||||
|
||||
(* add function arguments to symbol table *)
|
||||
and getArgs (parms : Param list)
|
||||
(vtable : VarTable)
|
||||
(nextReg : int)
|
||||
: (Mips.Instruction list * VarTable) =
|
||||
match parms with
|
||||
| [] -> ([], vtable)
|
||||
| (Param (v,_)::vs) ->
|
||||
if nextReg > maxCaller
|
||||
then raise (MyError ("Passing too many arguments!", (0,0)))
|
||||
else let vname = newReg ("param_" + v)
|
||||
let vtable1 = SymTab.bind v vname vtable (* (v,vname)::vtable *)
|
||||
let (code2,vtable2) = getArgs vs vtable1 (nextReg + 1)
|
||||
([Mips.MOVE (vname, Mips.RN nextReg)] @ code2, vtable2)
|
||||
|
||||
(* compile function declaration *)
|
||||
and compileFun (fundec : TypedFunDec) : Mips.Prog =
|
||||
let (FunDec (fname, resty, args, exp, (line,col))) = fundec
|
||||
(* make a vtable from bound formal parameters,
|
||||
then evaluate expression in this context, return it *)
|
||||
(* arguments passed in registers, "move" into local vars. *)
|
||||
let (argcode, vtable_local) = getArgs args (SymTab.empty ()) minReg
|
||||
(* return value in register 2 *)
|
||||
let rtmp = newReg (fname + "res")
|
||||
let returncode = [Mips.MOVE (RN2,rtmp)] (* move return val to R2 *)
|
||||
let body = compileExp exp vtable_local rtmp (* target expr *)
|
||||
let (body1, _, maxr, spilled) =
|
||||
RegAlloc.registerAlloc (* call register allocator *)
|
||||
(argcode @ body @ returncode)
|
||||
(Set.singleton (RN2)) 2 maxCaller maxReg 0
|
||||
let (savecode, restorecode, offset) = (* save/restore callee-saves *)
|
||||
stackSave (maxCaller+1) maxr [] [] (-8 + (-4 * spilled))
|
||||
[Mips.COMMENT ("Function " + fname);
|
||||
Mips.LABEL fname; (* function label *)
|
||||
Mips.SW (RA, SP, -4)] (* save return address *)
|
||||
@ savecode (* save callee-saves registers *)
|
||||
@ [Mips.ADDI (SP,SP,offset)] (* SP adjustment *)
|
||||
@ body1 (* code for function body *)
|
||||
@ [Mips.ADDI (SP,SP,-offset)] (* move SP up *)
|
||||
@ restorecode (* restore callee-saves registers *)
|
||||
@ [Mips.LW (RA, SP, -4); (* restore return addr *)
|
||||
Mips.JR (RA, [])] (* return *)
|
||||
|
||||
|
||||
(* compile program *)
|
||||
let compile (funs : TypedProg) : Mips.Instruction list =
|
||||
let () = stringTable := [("_true","true"); ("_false","false")]
|
||||
let funsCode = List.concat (List.map compileFun funs)
|
||||
let (stringinit_sym, stringdata) =
|
||||
List.unzip (List.map buildString (!stringTable))
|
||||
let (stringinit,_,_,_) =
|
||||
match stringinit_sym with
|
||||
| [] -> ([],Set.empty,0,0)
|
||||
| _ -> RegAlloc.registerAlloc (* call register allocator *)
|
||||
(List.concat stringinit_sym)
|
||||
(Set.singleton (RN2)) 2 maxCaller maxReg 0
|
||||
let mips_prog =
|
||||
[Mips.TEXT "0x00400000";
|
||||
Mips.GLOBL "main"]
|
||||
(* initialisation: heap pointer and string pointers *)
|
||||
@ (Mips.LA (HP, "_heap_"):: stringinit)
|
||||
(* jump to main (and stop after returning) *)
|
||||
@ [Mips.JAL ("main",[])]
|
||||
@ (* stop code *)
|
||||
[Mips.LABEL "_stop_";
|
||||
Mips.LI (RN2, sysExit);
|
||||
Mips.SYSCALL]
|
||||
@ (* code for functions *)
|
||||
funsCode
|
||||
(* pre-defined ord: char -> int and chr: int -> char *)
|
||||
@ [Mips.LABEL "ord"; (* char returned unmodified, interpreted as int *)
|
||||
Mips.JR (RA,[]);
|
||||
Mips.LABEL "chr"; (* int values are truncated to 8 bit (ASCII), *)
|
||||
Mips.ANDI (RN2, RN2, 255);
|
||||
Mips.JR (RA,[])]
|
||||
(* built-in read and write functions *)
|
||||
@ [Mips.LABEL "putint"; (* putint function *)
|
||||
Mips.ADDI(SP,SP,-8);
|
||||
Mips.SW (RN2,SP,0); (* save used registers *)
|
||||
Mips.SW (RN4,SP,4);
|
||||
Mips.MOVE (RN4, RN2); (* convention: number to be written in r2 *)
|
||||
Mips.LI (RN2, sysPrintInt);
|
||||
Mips.SYSCALL;
|
||||
Mips.LI (RN2, sysPrintString);
|
||||
Mips.LA(RN4,"_space_");
|
||||
Mips.SYSCALL; (* write CR *)
|
||||
Mips.LW (RN2,SP,0); (* reload used registers *)
|
||||
Mips.LW (RN4,SP,4);
|
||||
Mips.ADDI(SP,SP,8);
|
||||
Mips.JR (RA,[]);
|
||||
|
||||
Mips.LABEL "getint"; (* getint function *)
|
||||
Mips.LI (RN2,sysReadInt);
|
||||
Mips.SYSCALL;
|
||||
Mips.JR (RA,[])]
|
||||
@ (* putchar *)
|
||||
[ Mips.LABEL "putchar";
|
||||
Mips.ADDI(SP,SP,-8); (* make space for 2 registers on the stack *)
|
||||
Mips.SW (RN2,SP,0); (* save registers $2 and $4 to stack *)
|
||||
Mips.SW (RN4,SP,4);
|
||||
Mips.MOVE (RN4, RN2); (* put char in $4 for syscall to work on *)
|
||||
Mips.LI(RN2, sysPrintChar);
|
||||
Mips.SYSCALL;
|
||||
Mips.LI (RN2, sysPrintString);
|
||||
Mips.LA(RN4,"_space_"); (* the string we'll write is a space *)
|
||||
Mips.SYSCALL;
|
||||
Mips.LW (RN2,SP,0); (* reload registers $2 and $4 from stack *)
|
||||
Mips.LW (RN4,SP,4);
|
||||
Mips.ADDI(SP,SP,8); (* free stack space again *)
|
||||
Mips.JR (RA,[])
|
||||
]
|
||||
@ (* getchar *)
|
||||
[ Mips.LABEL "getchar";
|
||||
Mips.ADDI(SP,SP,-8); (* make space for 2 registers on the stack *)
|
||||
Mips.SW (RN4,SP,0); (* save registers $4 and $5 to stack *)
|
||||
Mips.SW (RN5,SP,4);
|
||||
Mips.LI(RN2, sysReadChar);
|
||||
Mips.SYSCALL;
|
||||
Mips.MOVE(RN5,RN2); (* temporarily move the result in reg $5*)
|
||||
Mips.LI (RN2, sysPrintString);
|
||||
Mips.LA(RN4,"_cr_");
|
||||
Mips.SYSCALL; (* write CR *)
|
||||
Mips.MOVE(RN2, RN5); (* put the result back in $2*)
|
||||
Mips.LW (RN4, SP, 0); (* restore registers *)
|
||||
Mips.LW (RN5, SP, 4);
|
||||
Mips.ADDI(SP,SP,8); (* free stack space again *)
|
||||
Mips.JR (RA,[])
|
||||
]
|
||||
@ (* putstring *)
|
||||
[ Mips.LABEL "putstring";
|
||||
Mips.ADDI(SP, SP, -16); (* make space on stack for registers *)
|
||||
Mips.SW (RN2, SP, 0); (* save registers $2,$4,$5,$6 to stack *)
|
||||
Mips.SW (RN4, SP, 4);
|
||||
Mips.SW (RN5, SP, 8);
|
||||
Mips.SW (RN6, SP, 12);
|
||||
Mips.LW (RN4, RN2, 0); (* $4 := size($2) *)
|
||||
Mips.ADDI(RN5, RN2, 4); (* $5 := $2 + 4 *)
|
||||
Mips.ADD (RN6, RN5, RN4); (* $6 := $5 + $4 *)
|
||||
Mips.LI (RN2, sysPrintChar);
|
||||
Mips.LABEL "putstring_begin";
|
||||
Mips.SUB (RN4, RN5, RN6); (* while ($5 < $6) { *)
|
||||
Mips.BGEZ(RN4, "putstring_done"); (* *)
|
||||
Mips.LB(RN4, RN5, 0); (* $4 := M[$5] *)
|
||||
Mips.SYSCALL; (* putchar($4) *)
|
||||
Mips.ADDI(RN5, RN5, 1); (* $5 := $5 + 1 *)
|
||||
Mips.J "putstring_begin"; (* } *)
|
||||
Mips.LABEL "putstring_done";
|
||||
Mips.LW (RN2, SP, 0); (* restore registers $2,$4,$5,$6 *)
|
||||
Mips.LW (RN4, SP, 4);
|
||||
Mips.LW (RN5, SP, 8);
|
||||
Mips.LW (RN6, SP, 12);
|
||||
Mips.ADDI(SP, SP, 16); (* free stack space again *)
|
||||
Mips.JR (RA,[])
|
||||
]
|
||||
@ (* Fixed code for reporting runtime errors.
|
||||
expects source line number in $5, pointer to error message in $6 *)
|
||||
[Mips.LABEL "_RuntimeError_";
|
||||
Mips.LA (RN4, "_ErrMsg_");
|
||||
Mips.LI (RN2, sysPrintString); Mips.SYSCALL;
|
||||
Mips.MOVE (RN4, RN5);
|
||||
Mips.LI (RN2, sysPrintInt); Mips.SYSCALL;
|
||||
Mips.LA (RN4, "_colon_space_");
|
||||
Mips.LI (RN2, sysPrintString); Mips.SYSCALL;
|
||||
Mips.MOVE (RN4, RN6);
|
||||
Mips.LI (RN2, sysPrintString); Mips.SYSCALL;
|
||||
Mips.LA (RN4, "_cr_");
|
||||
Mips.LI (RN2, sysPrintString); Mips.SYSCALL;
|
||||
Mips.J "_stop_"]
|
||||
@
|
||||
[Mips.DATA "";
|
||||
Mips.COMMENT "Fixed strings for I/O";
|
||||
Mips.LABEL "_ErrMsg_";
|
||||
Mips.ASCIIZ "Runtime error at line ";
|
||||
Mips.LABEL "_colon_space_";
|
||||
Mips.ASCIIZ ": ";
|
||||
Mips.LABEL "_cr_";
|
||||
Mips.ASCIIZ "\n";
|
||||
Mips.LABEL "_space_";
|
||||
Mips.ASCIIZ " "]
|
||||
@
|
||||
[Mips.COMMENT "Message strings for specific errors";
|
||||
Mips.LABEL "_Msg_IllegalArraySize_";
|
||||
Mips.ASCIIZ "negative array size";
|
||||
Mips.LABEL "_Msg_IllegalIndex_";
|
||||
Mips.ASCIIZ "array index out of bounds"
|
||||
Mips.LABEL "_Msg_DivZero_";
|
||||
Mips.ASCIIZ "division by zero"
|
||||
]
|
||||
@ (* String literals *)
|
||||
(Mips.COMMENT "String Literals" ::
|
||||
List.concat stringdata)
|
||||
(* Heap (to allocate arrays in, word-aligned) *)
|
||||
@ [Mips.ALIGN 2;
|
||||
Mips.LABEL "_heap_";
|
||||
Mips.SPACE 100000]
|
||||
mips_prog
|
||||
@@ -0,0 +1,208 @@
|
||||
module CopyConstPropFold
|
||||
|
||||
|
||||
(*
|
||||
(* An optimisation takes a program and returns a new program. *)
|
||||
val optimiseProgram : Fasto.KnownTypes.Prog -> Fasto.KnownTypes.Prog
|
||||
*)
|
||||
|
||||
open AbSyn
|
||||
|
||||
(* A propagatee is something that we can propagate - either a variable
|
||||
name or a constant value. *)
|
||||
type Propagatee =
|
||||
ConstProp of Value
|
||||
| VarProp of string
|
||||
|
||||
type VarTable = SymTab.SymTab<Propagatee>
|
||||
|
||||
let rec copyConstPropFoldExp (vtable : VarTable)
|
||||
(e : TypedExp) =
|
||||
match e with
|
||||
(* Copy propagation is handled entirely in the following three
|
||||
cases for variables, array indexing, and let-bindings. *)
|
||||
| Var (name, pos) ->
|
||||
(* TODO project task 3:
|
||||
Should probably look in the symbol table to see if
|
||||
a binding corresponding to the current variable `name`
|
||||
exists and if so, it should replace the current expression
|
||||
with the variable or constant to be propagated.
|
||||
*)
|
||||
failwith "Unimplemented copyConstPropFold for Var"
|
||||
| Index (name, e, t, pos) ->
|
||||
(* TODO project task 3:
|
||||
Should probably do the same as the `Var` case, for
|
||||
the array name, and optimize the index expression `e` as well.
|
||||
*)
|
||||
failwith "Unimplemented copyConstPropFold for Index"
|
||||
| Let (Dec (name, e, decpos), body, pos) ->
|
||||
let e' = copyConstPropFoldExp vtable e
|
||||
match e' with
|
||||
| Var (_, _) ->
|
||||
(* TODO project task 3:
|
||||
Hint: I have discovered a variable-copy statement `let x = a`.
|
||||
I should probably record it in the `vtable` by
|
||||
associating `x` with a variable-propagatee binding,
|
||||
and optimize the `body` of the let.
|
||||
*)
|
||||
failwith "Unimplemented copyConstPropFold for Let with Var"
|
||||
| Constant (_, _) ->
|
||||
(* TODO project task 3:
|
||||
Hint: I have discovered a constant-copy statement `let x = 5`.
|
||||
I should probably record it in the `vtable` by
|
||||
associating `x` with a constant-propagatee binding,
|
||||
and optimize the `body` of the let.
|
||||
*)
|
||||
failwith "Unimplemented copyConstPropFold for Let with Constant"
|
||||
| Let (_, _, _) ->
|
||||
(* TODO project task 3:
|
||||
Hint: this has the structure
|
||||
`let y = (let x = e1 in e2) in e3`
|
||||
Problem is, in this form, `e2` may simplify
|
||||
to a variable or constant, but I will miss
|
||||
identifying the resulting variable/constant-copy
|
||||
statement on `y`.
|
||||
A potential solution is to optimize directly the
|
||||
restructured, semantically-equivalent expression:
|
||||
`let x = e1 in let y = e2 in e3`
|
||||
*)
|
||||
failwith "Unimplemented copyConstPropFold for Let with Let"
|
||||
| _ -> (* Fallthrough - for everything else, do nothing *)
|
||||
let body' = copyConstPropFoldExp vtable body
|
||||
Let (Dec (name, e', decpos), body', pos)
|
||||
|
||||
| Times (_, _, _) ->
|
||||
(* TODO project task 3: implement as many safe algebraic
|
||||
simplifications as you can think of. You may inspire
|
||||
yourself from the case of `Plus`. For example:
|
||||
1 * x = ?
|
||||
x * 0 = ?
|
||||
*)
|
||||
failwith "Unimplemented copyConstPropFold for multiplication"
|
||||
| And (e1, e2, pos) ->
|
||||
(* TODO project task 3: see above. You may inspire yourself from
|
||||
`Or` below, but that only scratches the surface of what's possible *)
|
||||
failwith "Unimplemented copyConstPropFold for &&"
|
||||
| Constant (x,pos) -> Constant (x,pos)
|
||||
| StringLit (x,pos) -> StringLit (x,pos)
|
||||
| ArrayLit (es, t, pos) ->
|
||||
ArrayLit (List.map (copyConstPropFoldExp vtable) es, t, pos)
|
||||
| Plus (e1, e2, pos) ->
|
||||
let e1' = copyConstPropFoldExp vtable e1
|
||||
let e2' = copyConstPropFoldExp vtable e2
|
||||
match (e1', e2') with
|
||||
| (Constant (IntVal x, _), Constant (IntVal y, _)) ->
|
||||
Constant (IntVal (x + y), pos)
|
||||
| (Constant (IntVal 0, _), _) -> e2'
|
||||
| (_, Constant (IntVal 0, _)) -> e1'
|
||||
| _ -> Plus (e1', e2', pos)
|
||||
| Minus (e1, e2, pos) ->
|
||||
let e1' = copyConstPropFoldExp vtable e1
|
||||
let e2' = copyConstPropFoldExp vtable e2
|
||||
match (e1', e2') with
|
||||
| (Constant (IntVal x, _), Constant (IntVal y, _)) ->
|
||||
Constant (IntVal (x - y), pos)
|
||||
| (_, Constant (IntVal 0, _)) -> e1'
|
||||
| _ -> Minus (e1', e2', pos)
|
||||
| Equal (e1, e2, pos) ->
|
||||
let e1' = copyConstPropFoldExp vtable e1
|
||||
let e2' = copyConstPropFoldExp vtable e2
|
||||
match (e1', e2') with
|
||||
| (Constant (IntVal v1, _), Constant (IntVal v2, _)) ->
|
||||
Constant (BoolVal (v1 = v2), pos)
|
||||
| _ ->
|
||||
if false (* e1' = e2' *) (* <- this would be unsafe! (why?) *)
|
||||
then Constant (BoolVal true, pos)
|
||||
else Equal (e1', e2', pos)
|
||||
| Less (e1, e2, pos) ->
|
||||
let e1' = copyConstPropFoldExp vtable e1
|
||||
let e2' = copyConstPropFoldExp vtable e2
|
||||
match (e1', e2') with
|
||||
| (Constant (IntVal v1, _), Constant (IntVal v2, _)) ->
|
||||
Constant (BoolVal (v1 < v2), pos)
|
||||
| _ ->
|
||||
if false (* e1' = e2' *) (* <- as above *)
|
||||
then Constant (BoolVal false, pos)
|
||||
else Less (e1', e2', pos)
|
||||
| If (e1, e2, e3, pos) ->
|
||||
let e1' = copyConstPropFoldExp vtable e1
|
||||
match e1' with
|
||||
| Constant (BoolVal b, _) ->
|
||||
if b
|
||||
then copyConstPropFoldExp vtable e2
|
||||
else copyConstPropFoldExp vtable e3
|
||||
| _ ->
|
||||
If (e1',
|
||||
copyConstPropFoldExp vtable e2,
|
||||
copyConstPropFoldExp vtable e3,
|
||||
pos)
|
||||
| Apply (fname, es, pos) ->
|
||||
Apply (fname, List.map (copyConstPropFoldExp vtable) es, pos)
|
||||
| Iota (e, pos) ->
|
||||
Iota (copyConstPropFoldExp vtable e, pos)
|
||||
| Replicate (n, e, t, pos) ->
|
||||
Replicate (copyConstPropFoldExp vtable n,
|
||||
copyConstPropFoldExp vtable e,
|
||||
t, pos)
|
||||
| Map (farg, e, t1, t2, pos) ->
|
||||
Map (copyConstPropFoldFunArg vtable farg,
|
||||
copyConstPropFoldExp vtable e,
|
||||
t1, t2, pos)
|
||||
| Filter (farg, e, t1, pos) ->
|
||||
Filter (copyConstPropFoldFunArg vtable farg,
|
||||
copyConstPropFoldExp vtable e,
|
||||
t1, pos)
|
||||
| Reduce (farg, e1, e2, t, pos) ->
|
||||
Reduce (copyConstPropFoldFunArg vtable farg,
|
||||
copyConstPropFoldExp vtable e1,
|
||||
copyConstPropFoldExp vtable e2,
|
||||
t, pos)
|
||||
| Scan (farg, e1, e2, t, pos) ->
|
||||
Scan (copyConstPropFoldFunArg vtable farg,
|
||||
copyConstPropFoldExp vtable e1,
|
||||
copyConstPropFoldExp vtable e2,
|
||||
t, pos)
|
||||
| Divide (e1, e2, pos) ->
|
||||
let e1' = copyConstPropFoldExp vtable e1
|
||||
let e2' = copyConstPropFoldExp vtable e2
|
||||
match (e1', e2') with
|
||||
| (Constant (IntVal x, _), Constant (IntVal y, _)) when y <> 0 ->
|
||||
Constant (IntVal (x / y), pos)
|
||||
| _ -> Divide (e1', e2', pos)
|
||||
| Or (e1, e2, pos) ->
|
||||
let e1' = copyConstPropFoldExp vtable e1
|
||||
let e2' = copyConstPropFoldExp vtable e2
|
||||
match (e1', e2') with
|
||||
| (Constant (BoolVal a, _), Constant (BoolVal b, _)) ->
|
||||
Constant (BoolVal (a || b), pos)
|
||||
| _ -> Or (e1', e2', pos)
|
||||
| Not (e, pos) ->
|
||||
let e' = copyConstPropFoldExp vtable e
|
||||
match e' with
|
||||
| Constant (BoolVal a, _) -> Constant (BoolVal (not a), pos)
|
||||
| _ -> Not (e', pos)
|
||||
| Negate (e, pos) ->
|
||||
let e' = copyConstPropFoldExp vtable e
|
||||
match e' with
|
||||
| Constant (IntVal x, _) -> Constant (IntVal (-x), pos)
|
||||
| _ -> Negate (e', pos)
|
||||
| Read (t, pos) -> Read (t, pos)
|
||||
| Write (e, t, pos) -> Write (copyConstPropFoldExp vtable e, t, pos)
|
||||
|
||||
and copyConstPropFoldFunArg (vtable : VarTable)
|
||||
(farg : TypedFunArg) =
|
||||
match farg with
|
||||
| FunName fname -> FunName fname
|
||||
| Lambda (rettype, paramls, body, pos) ->
|
||||
(* Remove any bindings with the same names as the parameters. *)
|
||||
let paramNames = (List.map (fun (Param (name, _)) -> name) paramls)
|
||||
let vtable' = SymTab.removeMany paramNames vtable
|
||||
Lambda (rettype, paramls, copyConstPropFoldExp vtable' body, pos)
|
||||
|
||||
let copyConstPropFoldFunDec = function
|
||||
| FunDec (fname, rettype, paramls, body, loc) ->
|
||||
let body' = copyConstPropFoldExp (SymTab.empty ()) body
|
||||
FunDec (fname, rettype, paramls, body', loc)
|
||||
|
||||
let optimiseProgram (prog : TypedProg) =
|
||||
List.map copyConstPropFoldFunDec prog
|
||||
@@ -0,0 +1,239 @@
|
||||
module DeadBindingRemoval
|
||||
|
||||
(*
|
||||
val removeDeadBindings : Fasto.KnownTypes.Prog -> Fasto.KnownTypes.Prog
|
||||
*)
|
||||
|
||||
open AbSyn
|
||||
|
||||
type DBRtab = SymTab.SymTab<unit>
|
||||
|
||||
let isUsed (name : string) (stab : DBRtab) =
|
||||
match SymTab.lookup name stab with
|
||||
| None -> false
|
||||
| Some _ -> true
|
||||
|
||||
let recordUse (name : string) (stab : DBRtab) =
|
||||
match SymTab.lookup name stab with
|
||||
| None -> SymTab.bind name () stab
|
||||
| Some _ -> stab
|
||||
|
||||
let rec unzip3 = function
|
||||
| [] -> ([], [], [])
|
||||
| (x,y,z)::l ->
|
||||
let (xs, ys, zs) = unzip3 l
|
||||
(x::xs, y::ys, z::zs)
|
||||
let anytrue = List.exists (fun x -> x)
|
||||
|
||||
(* Input: the expression to be optimised (by removing inner dead bindings)
|
||||
The result is a three-tuple:
|
||||
- bool refers to whether the expression _may_ contain I/O
|
||||
operations (directly or indirectly). We always err on the safe side;
|
||||
that is, we only return false if we are certain that
|
||||
a dead binding to this expression is safe to remove.
|
||||
- DBRtab is the symbol table that is synthesized from processing the
|
||||
subexpressions -- its keys are the names that were used in subexpressions.
|
||||
- the TypedExp is the resulting (optimised) expression
|
||||
The idea is that you do a bottom-up traversal of AbSyn, and you record
|
||||
any (variable) names that you find in the symbol table. You find such
|
||||
names when (1) the expression is a `Var` expression or (2) an `Index`
|
||||
expression.
|
||||
Then, whenever you reach a `Let` expression, you check whether the body
|
||||
of the let has used the variable name currently defined. If not, then
|
||||
the current binding is unused and can be omitted/removed, _if_
|
||||
it contains no I/O operations. For example, assume the original
|
||||
program is:
|
||||
`let x = (let y = 4 + 5 in 6) in x * 2`
|
||||
then one can observe that `y` is unused and the binding `let y = 4 + 5`
|
||||
can be removed (because `y` is not subsequently used), resulting in the
|
||||
optimised program: `let x = 6 in x * 2`.
|
||||
The rest of the expression constructors mainly perform the AbSyn (bottom-up)
|
||||
traversal by recursively calling `removeDeadBindingsInExp` on subexpressions
|
||||
and joining the results.
|
||||
*)
|
||||
let rec removeDeadBindingsInExp (e : TypedExp) : (bool * DBRtab * TypedExp) =
|
||||
match e with
|
||||
| Constant (x, pos) -> (false, SymTab.empty(), Constant (x, pos))
|
||||
| StringLit (x, pos) -> (false, SymTab.empty(), StringLit (x, pos))
|
||||
| ArrayLit (es, t, pos) ->
|
||||
let (ios, uses, es') = unzip3 (List.map removeDeadBindingsInExp es)
|
||||
(anytrue ios,
|
||||
List.fold SymTab.combine (SymTab.empty()) uses,
|
||||
ArrayLit (es', t, pos) )
|
||||
(* ToDO: Task 3: implement the cases of `Var`, `Index` and `Let` expressions below *)
|
||||
| Var (name, pos) ->
|
||||
(* Task 3, Hints for the `Var` case:
|
||||
- 1st element of result tuple: can a variable name contain IO?
|
||||
- 2nd element of result tuple: you have discovered a name, hence
|
||||
you need to record it in a new symbol table.
|
||||
- 3rd element of the tuple: should be the optimised expression.
|
||||
*)
|
||||
failwith "Unimplemented removeDeadBindingsInExp for Var"
|
||||
| Plus (x, y, pos) ->
|
||||
let (xios, xuses, x') = removeDeadBindingsInExp x
|
||||
let (yios, yuses, y') = removeDeadBindingsInExp y
|
||||
(xios || yios,
|
||||
SymTab.combine xuses yuses,
|
||||
Plus (x', y', pos))
|
||||
| Minus (x, y, pos) ->
|
||||
let (xios, xuses, x') = removeDeadBindingsInExp x
|
||||
let (yios, yuses, y') = removeDeadBindingsInExp y
|
||||
(xios || yios,
|
||||
SymTab.combine xuses yuses,
|
||||
Minus (x', y', pos))
|
||||
| Equal (x, y, pos) ->
|
||||
let (xios, xuses, x') = removeDeadBindingsInExp x
|
||||
let (yios, yuses, y') = removeDeadBindingsInExp y
|
||||
(xios || yios,
|
||||
SymTab.combine xuses yuses,
|
||||
Equal (x', y', pos))
|
||||
| Less (x, y, pos) ->
|
||||
let (xios, xuses, x') = removeDeadBindingsInExp x
|
||||
let (yios, yuses, y') = removeDeadBindingsInExp y
|
||||
(xios || yios,
|
||||
SymTab.combine xuses yuses,
|
||||
Less (x', y', pos))
|
||||
| If (e1, e2, e3, pos) ->
|
||||
let (ios1, uses1, e1') = removeDeadBindingsInExp e1
|
||||
let (ios2, uses2, e2') = removeDeadBindingsInExp e2
|
||||
let (ios3, uses3, e3') = removeDeadBindingsInExp e3
|
||||
(ios1 || ios2 || ios3,
|
||||
SymTab.combine (SymTab.combine uses1 uses2) uses3,
|
||||
If (e1', e2', e3', pos))
|
||||
| Apply (fname, args, pos) ->
|
||||
let (ios, uses, args') = unzip3 (List.map removeDeadBindingsInExp args)
|
||||
(* Since we don't currently analyze the body of the called function,
|
||||
we don't know if it might contain I/O. Thus, we always mark
|
||||
a function call as non-removable, unless it is to a
|
||||
known-safe builtin function, such as "length".
|
||||
(However, if we perform function inlining before removing
|
||||
dead bindings, being overly cautious here will generally
|
||||
not cause us to miss many optimization opportunities.) *)
|
||||
(anytrue ios || fname <> "length",
|
||||
List.fold SymTab.combine (SymTab.empty()) uses,
|
||||
Apply (fname, args', pos))
|
||||
| Index (name, e, t, pos) ->
|
||||
(* Task 3, `Index` case: is similar to the `Var` case, except that,
|
||||
additionally, you also need to recursively optimize the index
|
||||
expression `e` and to propagate its results (in addition
|
||||
to recording the use of `name`).
|
||||
*)
|
||||
failwith "Unimplemented removeDeadBindingsInExp for Index"
|
||||
|
||||
| Let (Dec (name, e, decpos), body, pos) ->
|
||||
(* Task 3, Hints for the `Let` case:
|
||||
- recursively process the `e` and `body` subexpressions
|
||||
of the Let-binding
|
||||
- a Let-binding contains IO if at least one of `e`
|
||||
and `body` does.
|
||||
- a variable is used in a Let-binding if it is used
|
||||
in either `e` or `body`, except that any uses in
|
||||
`body` do not count if they refer to the local
|
||||
binding of `name`. For example, in
|
||||
`let x = y+1 in x*z`,
|
||||
`x` is _not_ considered to be used in the
|
||||
Let-expression, but `y` and `z` are. Consider how
|
||||
to express this with the SymTab operations.
|
||||
- the optimized expression will be either just the
|
||||
optimized body (if it doesn't use `name` _and_ `e`
|
||||
does not contain IO), or a new Let-expression
|
||||
built from the optimized subexpressions
|
||||
(otherwise). Note that the returned IO-flag and
|
||||
used-variable table should describe the expression
|
||||
*resulting* from the optmization, not the original
|
||||
Let-expression.
|
||||
|
||||
*)
|
||||
failwith "Unimplemented removeDeadBindingsInExp for Let"
|
||||
| Iota (e, pos) ->
|
||||
let (io, uses, e') = removeDeadBindingsInExp e
|
||||
(io,
|
||||
uses,
|
||||
Iota (e', pos))
|
||||
| Map (farg, e, t1, t2, pos) ->
|
||||
let (eio, euses, e') = removeDeadBindingsInExp e
|
||||
let (fio, fuses, farg') = removeDeadBindingsInFunArg farg
|
||||
(eio || fio,
|
||||
SymTab.combine euses fuses,
|
||||
Map (farg', e', t1, t2, pos))
|
||||
| Filter (farg, e, t1, pos) ->
|
||||
let (eio, euses, e') = removeDeadBindingsInExp e
|
||||
let (fio, fuses, farg') = removeDeadBindingsInFunArg farg
|
||||
(eio || fio,
|
||||
SymTab.combine euses fuses,
|
||||
Filter (farg', e', t1, pos))
|
||||
| Reduce (farg, e1, e2, t, pos) ->
|
||||
let (io1, uses1, e1') = removeDeadBindingsInExp e1
|
||||
let (io2, uses2, e2') = removeDeadBindingsInExp e2
|
||||
let (fio, fuses, farg') = removeDeadBindingsInFunArg farg
|
||||
(io1 || io2 || fio,
|
||||
SymTab.combine (SymTab.combine uses1 uses2) fuses,
|
||||
Reduce(farg', e1', e2', t, pos))
|
||||
| Replicate (n, e, t, pos) ->
|
||||
let (nio, nuses, n') = removeDeadBindingsInExp n
|
||||
let (eio, euses, e') = removeDeadBindingsInExp e
|
||||
(nio || eio,
|
||||
SymTab.combine nuses euses,
|
||||
Replicate (n', e', t, pos))
|
||||
| Scan (farg, e1, e2, t, pos) ->
|
||||
let (io1, uses1, e1') = removeDeadBindingsInExp e1
|
||||
let (io2, uses2, e2') = removeDeadBindingsInExp e2
|
||||
let (fio, fuses, farg') = removeDeadBindingsInFunArg farg
|
||||
(io1 || io2 || fio,
|
||||
SymTab.combine (SymTab.combine uses1 uses2) fuses,
|
||||
Scan(farg', e1', e2', t, pos))
|
||||
| Times (x, y, pos) ->
|
||||
let (xios, xuses, x') = removeDeadBindingsInExp x
|
||||
let (yios, yuses, y') = removeDeadBindingsInExp y
|
||||
(xios || yios,
|
||||
SymTab.combine xuses yuses,
|
||||
Times (x', y', pos))
|
||||
| Divide (x, y, pos) ->
|
||||
let (xios, xuses, x') = removeDeadBindingsInExp x
|
||||
let (yios, yuses, y') = removeDeadBindingsInExp y
|
||||
(xios || yios,
|
||||
SymTab.combine xuses yuses,
|
||||
Divide (x', y', pos))
|
||||
| And (x, y, pos) ->
|
||||
let (xios, xuses, x') = removeDeadBindingsInExp x
|
||||
let (yios, yuses, y') = removeDeadBindingsInExp y
|
||||
(xios || yios,
|
||||
SymTab.combine xuses yuses,
|
||||
And (x', y', pos))
|
||||
| Or (x, y, pos) ->
|
||||
let (xios, xuses, x') = removeDeadBindingsInExp x
|
||||
let (yios, yuses, y') = removeDeadBindingsInExp y
|
||||
(xios || yios,
|
||||
SymTab.combine xuses yuses,
|
||||
Or (x', y', pos))
|
||||
| Not (e, pos) ->
|
||||
let (ios, uses, e') = removeDeadBindingsInExp e
|
||||
(ios, uses, Not (e', pos))
|
||||
| Negate (e, pos) ->
|
||||
let (ios, uses, e') = removeDeadBindingsInExp e
|
||||
(ios, uses, Negate (e', pos))
|
||||
| Read (x, pos) ->
|
||||
(true, SymTab.empty(), Read (x, pos))
|
||||
| Write (e, t, pos) ->
|
||||
let (_, uses, e') = removeDeadBindingsInExp e
|
||||
(true, uses, Write (e', t, pos))
|
||||
|
||||
and removeDeadBindingsInFunArg (farg : TypedFunArg) =
|
||||
match farg with
|
||||
| FunName fname -> (false, SymTab.empty(), FunName fname)
|
||||
| Lambda (rettype, paramls, body, pos) ->
|
||||
let (io, uses, body') = removeDeadBindingsInExp body
|
||||
let uses' = List.fold (fun acc (Param (pname,_)) ->
|
||||
SymTab.remove pname acc
|
||||
) uses paramls
|
||||
(io,
|
||||
uses',
|
||||
Lambda (rettype, paramls, body', pos))
|
||||
|
||||
let removeDeadBindingsInFunDec (FunDec (fname, rettype, paramls, body, pos)) =
|
||||
let (_, _, body') = removeDeadBindingsInExp body
|
||||
FunDec (fname, rettype, paramls, body', pos)
|
||||
|
||||
(* Entrypoint: remove dead bindings from the whole program *)
|
||||
let removeDeadBindings (prog : TypedProg) =
|
||||
List.map removeDeadBindingsInFunDec prog
|
||||
@@ -0,0 +1,10 @@
|
||||
module DeadFunctionRemoval
|
||||
|
||||
open AbSyn
|
||||
open CallGraph
|
||||
|
||||
let removeDeadFunction (prog : TypedProg) =
|
||||
let graph = callGraph prog
|
||||
let alive (FunDec (fname, _, _, _, _)) =
|
||||
fname = "main" || calls "main" fname graph
|
||||
List.filter alive prog
|
||||
@@ -0,0 +1,38 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FsLexYacc" Version="10.2.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<FsYacc Include="Parser.fsp">
|
||||
<OtherFlags>-v --module Parser</OtherFlags>
|
||||
</FsYacc>
|
||||
<FsLex Include="Lexer.fsl">
|
||||
<OtherFlags></OtherFlags>
|
||||
</FsLex>
|
||||
<Compile Include="AbSyn.fs" />
|
||||
<Compile Include="SymTab.fs" />
|
||||
<Compile Include="Parser.fs" />
|
||||
<Compile Include="Lexer.fs" />
|
||||
<Compile Include="Interpreter.fs" />
|
||||
<Compile Include="TypeChecker.fs" />
|
||||
<Compile Include="CallGraph.fs" />
|
||||
<Compile Include="Inlining.fs" />
|
||||
<Compile Include="DeadFunctionRemoval.fs" />
|
||||
<Compile Include="DeadBindingRemoval.fs" />
|
||||
<Compile Include="CopyConstPropFold.fs" />
|
||||
<Compile Include="Mips.fs" />
|
||||
<Compile Include="RegAlloc.fs" />
|
||||
<Compile Include="CodeGen.fs" />
|
||||
|
||||
<Compile Include="Fasto.fsx" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,252 @@
|
||||
// The Fasto compiler command-line interface.
|
||||
//
|
||||
// This is the main program for when this compiler is turned into an executable.
|
||||
// It ties together all the compiler modules. You can build the compiler by
|
||||
// running 'make' or 'dotnet build Fasto' in the top-level directory.
|
||||
|
||||
open System.Text
|
||||
open FSharp.Text.Lexing
|
||||
open System.IO
|
||||
|
||||
open AbSyn
|
||||
open Inlining
|
||||
open DeadFunctionRemoval
|
||||
open DeadBindingRemoval
|
||||
open CopyConstPropFold
|
||||
|
||||
|
||||
// YOU DO NOT NEED TO UNDERSTAND THIS; IT IS A HACK: State machine for getting
|
||||
// line and position numbers from a Parser error string. This is really nasty.
|
||||
// The problem is that we can only define the needed 'parse_error_rich' function
|
||||
// in Parser.fsp at the top of the file, which means that we have not defined
|
||||
// the actual tokens yet, so we cannot pattern match on them for extracting
|
||||
// their source code positions, although we *can* print them. An alternative
|
||||
// solution is to inject a proper 'parse_error_rich' function in the bottom of
|
||||
// the generated Parser.fs.
|
||||
exception SyntaxError of int * int
|
||||
let printPos (errString : string) : unit =
|
||||
let rec state3 (s : string) (p : int) (lin : string) (col : int) =
|
||||
(* read digits until not *)
|
||||
let c = s.[p]
|
||||
if System.Char.IsDigit c
|
||||
then state3 s (p-1) (System.Char.ToString c + lin) col
|
||||
else raise (SyntaxError (System.Int32.Parse lin, col))
|
||||
|
||||
let rec state2 (s : string) (p : int) (col : string) =
|
||||
(* skip from position until digit *)
|
||||
let c = s.[p]
|
||||
if System.Char.IsDigit c
|
||||
then state3 s (p-1) (System.Char.ToString c) (System.Int32.Parse col)
|
||||
else state2 s (p-1) col
|
||||
|
||||
let rec state1 (s : string) (p : int) (col : string) =
|
||||
(* read digits until not *)
|
||||
let c = s.[p]
|
||||
if System.Char.IsDigit c
|
||||
then state1 s (p-1) (System.Char.ToString c + col)
|
||||
else state2 s (p-1) col
|
||||
|
||||
let rec state0 (s : string) (p : int) =
|
||||
(* skip from end until digit *)
|
||||
let c = s.[p]
|
||||
if System.Char.IsDigit c
|
||||
then state1 s (p-1) (System.Char.ToString c)
|
||||
else state0 s (p-1)
|
||||
|
||||
state0 errString (String.length errString - 1)
|
||||
|
||||
// Parse program from string.
|
||||
let parseString (s : string) : AbSyn.UntypedProg =
|
||||
Parser.Prog Lexer.Token
|
||||
<| LexBuffer<_>.FromBytes (Encoding.UTF8.GetBytes s)
|
||||
|
||||
////////////////////
|
||||
/// Usage helper ///
|
||||
////////////////////
|
||||
let usage =
|
||||
[ " fasto -i tests/fib.fo\n"
|
||||
; " Run 'fib.fo' in the 'tests' directory in interpreted mode.\n"
|
||||
; " and print the result.\n"
|
||||
; "\n"
|
||||
; " fasto -r tests/fib.fo\n"
|
||||
; " Run 'fib.fo' in interpreted mode, but do not print the result.\n"
|
||||
; "\n"
|
||||
; " fasto -c tests/fib.fo\n"
|
||||
; " Compile 'tests/fib.fo' into the MIPS program 'tests/fib.asm'.\n"
|
||||
; "\n"
|
||||
; " fasto -o [opts] tests/fib.fo\n"
|
||||
; " Compile the optimised 'tests/fib.fo' into 'tests/fib.asm'.\n"
|
||||
; "\n"
|
||||
; " fasto -p [opts] tests/fib.fo\n"
|
||||
; " Optimise 'tests/fib.fo' and print the result on standard output.\n"
|
||||
; " <opts> is a sequence of characters corresponding to optimisation\n"
|
||||
; " passes, where: \n"
|
||||
; " i - Inline functions.\n"
|
||||
; " c - Copy propagation and constant folding.\n"
|
||||
; " d - Remove dead bindings.\n"
|
||||
; " D - Remove dead functions.\n"
|
||||
]
|
||||
|
||||
|
||||
// Print error message to the standard error channel.
|
||||
let errorMessage (message : string) : Unit =
|
||||
printfn "%s\n" message
|
||||
|
||||
let errorMessage' (errorType : string, message : string, line : int, col : int) =
|
||||
printfn "%s: %s at line %d, column %d" errorType message line col
|
||||
|
||||
let bad () : Unit =
|
||||
errorMessage "Unknown command-line arguments. Usage:\n"
|
||||
errorMessage (usage |> List.fold (+) "")
|
||||
|
||||
exception FileProblem of string
|
||||
|
||||
// Remove trailing .fo from filename.
|
||||
let sanitiseFilename (argFilename : string) : string =
|
||||
if argFilename.EndsWith ".fo"
|
||||
then argFilename.Substring(0, (String.length argFilename)-3)
|
||||
else argFilename
|
||||
|
||||
// Save the content of a string to file.
|
||||
let saveFile (filename : string) (content : string) : Unit =
|
||||
try
|
||||
let outFile = File.CreateText filename
|
||||
// Generate code here.
|
||||
outFile.Write content
|
||||
outFile.Close()
|
||||
with
|
||||
| ex ->
|
||||
printfn "Problem writing file named: %s, error: %s,\n where content is:\n %s\n" filename ex.Message content
|
||||
System.Environment.Exit 1
|
||||
|
||||
|
||||
let parseFastoFile (filename : string) : AbSyn.UntypedProg =
|
||||
let txt = try // read text from file given as parameter with added extension
|
||||
let inStream = File.OpenText (filename + ".fo")
|
||||
let txt = inStream.ReadToEnd()
|
||||
inStream.Close()
|
||||
txt
|
||||
with // or return empty string
|
||||
| ex -> ""
|
||||
if txt <> "" then // valid file content
|
||||
let program =
|
||||
try
|
||||
parseString txt
|
||||
with
|
||||
| Lexer.LexicalError (info,(line,col)) ->
|
||||
printfn "%s at line %d, position %d\n" info line col
|
||||
System.Environment.Exit 1
|
||||
[]
|
||||
| ex ->
|
||||
if ex.Message = "parse error"
|
||||
then printPos Parser.ErrorContextDescriptor
|
||||
else printfn "%s" ex.Message
|
||||
System.Environment.Exit 1
|
||||
[]
|
||||
program
|
||||
else failwith "Invalid file name or empty file"
|
||||
|
||||
let compile (filename : string) optimiser : Unit =
|
||||
let pgm = parseFastoFile filename
|
||||
let pgm_decorated = TypeChecker.checkProg pgm
|
||||
let pgm_optimised = optimiser pgm_decorated
|
||||
let mips_code = CodeGen.compile pgm_optimised
|
||||
let mips_code_text = Mips.ppMipsProg mips_code
|
||||
saveFile (filename + ".asm") mips_code_text
|
||||
|
||||
let interpret (filename : string) : Unit =
|
||||
let pgm = parseFastoFile filename
|
||||
printfn "Program is:\n\n%s" (AbSyn.ppProg pgm)
|
||||
printfn "\n+-----------------------------------------+"
|
||||
printfn "\n| You might need to enter some input now. |"
|
||||
printfn "\n+-----------------------------------------+"
|
||||
printfn "\n"
|
||||
let res = Interpreter.evalProg pgm
|
||||
printfn "\n\nResult of 'main': %s\n" (AbSyn.ppVal 0 res)
|
||||
|
||||
let interpretSimple (filename : string) : AbSyn.Value =
|
||||
let pgm = parseFastoFile filename
|
||||
Interpreter.evalProg pgm
|
||||
|
||||
let printOptimised (argFilename : string) optimiser : Unit =
|
||||
let pgm = parseFastoFile argFilename
|
||||
let pgm_decorated = TypeChecker.checkProg pgm
|
||||
let pgm_optimised = optimiser pgm_decorated
|
||||
printfn "%s\n" (ppProg pgm_optimised)
|
||||
|
||||
let withoutOptimisations (prog : TypedProg) = prog
|
||||
|
||||
let defaultOptimisations (prog : TypedProg) =
|
||||
(removeDeadFunction <<
|
||||
removeDeadBindings <<
|
||||
optimiseProgram <<
|
||||
inlineOptimiseProgram) prog
|
||||
|
||||
type opt = char
|
||||
|
||||
let rec extractOpts (opts : opt list) =
|
||||
match opts with
|
||||
| [] -> Some (fun x -> x)
|
||||
| opt::opls ->
|
||||
let extractOpt (op : opt) =
|
||||
match op with
|
||||
| 'i' -> Some inlineOptimiseProgram
|
||||
| 'c' -> Some optimiseProgram
|
||||
| 'd' -> Some removeDeadBindings
|
||||
| 'D' -> Some removeDeadFunction
|
||||
| _ -> None
|
||||
match (extractOpt opt, extractOpts opls) with
|
||||
| (Some opt', Some opts') -> Some (fun x -> opts' (opt' x))
|
||||
| _ -> None
|
||||
|
||||
let explode (s:string) =
|
||||
[for c in s -> c]
|
||||
|
||||
[<EntryPoint>]
|
||||
let main (paramList: string[]) : int =
|
||||
try
|
||||
match paramList with
|
||||
| [|"-i"; file|] -> interpret (sanitiseFilename file)
|
||||
| [|"-r"; file|] -> let res = interpretSimple (sanitiseFilename file)
|
||||
printfn "\n\nResult of 'main': %s\n" (AbSyn.ppVal 0 res)
|
||||
| [|"-c"; file|] -> compile (sanitiseFilename file) (fun x -> x)
|
||||
| [|"-o"; file|] -> compile (sanitiseFilename file) defaultOptimisations
|
||||
| [|"-o"; opts; file|] ->
|
||||
match extractOpts (explode opts) with
|
||||
| Some (opts') -> compile (sanitiseFilename file) opts'
|
||||
| None -> bad ()
|
||||
| [|"-P"; file|] ->
|
||||
printOptimised (sanitiseFilename file) withoutOptimisations
|
||||
| [|"-p"; file|] ->
|
||||
printOptimised (sanitiseFilename file) defaultOptimisations
|
||||
| [|"-p"; opts; file|] ->
|
||||
match extractOpts (explode opts) with
|
||||
| Some (opts') -> printOptimised (sanitiseFilename file) opts'
|
||||
| None -> bad ()
|
||||
| _ -> bad ()
|
||||
0
|
||||
with
|
||||
| SyntaxError (line, col) ->
|
||||
errorMessage' ("Parse error", "Error", line, col)
|
||||
System.Environment.Exit 1
|
||||
1
|
||||
| Lexer.LexicalError (message, (line, col)) ->
|
||||
errorMessage' ("Lexical error", message, line, col)
|
||||
System.Environment.Exit 1
|
||||
1
|
||||
| Interpreter.MyError (message, (line, col)) ->
|
||||
errorMessage' ("Interpreter error", message, line, col)
|
||||
System.Environment.Exit 1
|
||||
1
|
||||
| CodeGen.MyError (message, (line, col)) ->
|
||||
errorMessage' ("Code generator error", message, line, col)
|
||||
System.Environment.Exit 1
|
||||
1
|
||||
| TypeChecker.MyError (message, (line, col)) ->
|
||||
errorMessage' ("Type error", message, line, col)
|
||||
System.Environment.Exit 1
|
||||
1
|
||||
| FileProblem filename ->
|
||||
errorMessage ("There was a problem with the file: " + filename)
|
||||
System.Environment.Exit 1
|
||||
1
|
||||
@@ -0,0 +1,140 @@
|
||||
(* We will inline any function that does not call itselt. *)
|
||||
module Inlining
|
||||
|
||||
open AbSyn
|
||||
open CallGraph
|
||||
|
||||
let mutable inlining_ctr = 0 (* for generating fresh variable names *)
|
||||
|
||||
let newSuffix () =
|
||||
inlining_ctr <- inlining_ctr + 1
|
||||
"_I" + string inlining_ctr
|
||||
|
||||
let rec inlineInExp (graph : CallGraph)
|
||||
(prog : TypedProg)
|
||||
(e : TypedExp) =
|
||||
match e with
|
||||
| Constant _ -> e
|
||||
| StringLit _ -> e
|
||||
| ArrayLit (es, t, pos) ->
|
||||
ArrayLit (List.map (inlineInExp graph prog) es, t, pos)
|
||||
| Var _ -> e
|
||||
| Plus (e1, e2, pos) ->
|
||||
Plus (inlineInExp graph prog e1,
|
||||
inlineInExp graph prog e2, pos)
|
||||
| Minus (e1, e2, pos) ->
|
||||
Minus (inlineInExp graph prog e1,
|
||||
inlineInExp graph prog e2, pos)
|
||||
| Equal (e1, e2, pos) ->
|
||||
Equal (inlineInExp graph prog e1,
|
||||
inlineInExp graph prog e2, pos)
|
||||
| Less (e1, e2, pos) ->
|
||||
Less (inlineInExp graph prog e1,
|
||||
inlineInExp graph prog e2, pos)
|
||||
| If (e1, e2, e3, pos) ->
|
||||
If (inlineInExp graph prog e1,
|
||||
inlineInExp graph prog e2,
|
||||
inlineInExp graph prog e3,
|
||||
pos)
|
||||
| Apply (fname, es, pos) ->
|
||||
if calls fname fname graph then
|
||||
(* Function is recursive - do not inline. *)
|
||||
Apply (fname, List.map (inlineInExp graph prog) es, pos)
|
||||
else (* OK - inline. *)
|
||||
inlineFuncall fname graph prog es pos
|
||||
| Let (Dec (name, e, decpos), body, pos) ->
|
||||
Let (Dec (name, inlineInExp graph prog e, decpos),
|
||||
inlineInExp graph prog body,
|
||||
pos)
|
||||
| Index (name, e, t, pos) ->
|
||||
Index (name, inlineInExp graph prog e, t, pos)
|
||||
| Iota (e, pos) ->
|
||||
Iota (e, pos)
|
||||
| Map (farg, e, t1, t2, pos) ->
|
||||
Map (inlineInFunArg graph prog farg,
|
||||
inlineInExp graph prog e,
|
||||
t1, t2, pos)
|
||||
| Filter (farg, e, t1, pos) ->
|
||||
Filter (inlineInFunArg graph prog farg,
|
||||
inlineInExp graph prog e,
|
||||
t1, pos)
|
||||
| Reduce (farg, e1, e2, t, pos) ->
|
||||
Reduce (inlineInFunArg graph prog farg,
|
||||
inlineInExp graph prog e1,
|
||||
inlineInExp graph prog e2,
|
||||
t, pos)
|
||||
| Replicate (n, e, t, pos) ->
|
||||
Replicate (inlineInExp graph prog n,
|
||||
inlineInExp graph prog e,
|
||||
t, pos)
|
||||
| Scan (farg, e1, e2, t, pos) ->
|
||||
Scan (inlineInFunArg graph prog farg,
|
||||
inlineInExp graph prog e1,
|
||||
inlineInExp graph prog e2,
|
||||
t, pos)
|
||||
| Times (e1, e2, pos) ->
|
||||
Times (inlineInExp graph prog e1,
|
||||
inlineInExp graph prog e2,
|
||||
pos)
|
||||
| Divide (e1, e2, pos) ->
|
||||
Divide (inlineInExp graph prog e1,
|
||||
inlineInExp graph prog e2,
|
||||
pos)
|
||||
| And (e1, e2, pos) ->
|
||||
And (inlineInExp graph prog e1,
|
||||
inlineInExp graph prog e2,
|
||||
pos)
|
||||
| Or (e1, e2, pos) ->
|
||||
Or (inlineInExp graph prog e1,
|
||||
inlineInExp graph prog e2,
|
||||
pos)
|
||||
| Not (e, pos) ->
|
||||
Not (inlineInExp graph prog e, pos)
|
||||
| Negate (e, pos) ->
|
||||
Negate (inlineInExp graph prog e, pos)
|
||||
| Read (t, pos) ->
|
||||
Read (t, pos)
|
||||
| Write (e, t, pos) ->
|
||||
Write (inlineInExp graph prog e, t, pos)
|
||||
|
||||
and inlineInFunArg (graph : CallGraph)
|
||||
(prog : TypedProg) = function
|
||||
| Lambda (rettype, paramls, body, pos) ->
|
||||
Lambda (rettype, paramls, inlineInExp graph prog body, pos)
|
||||
| FunName fname ->
|
||||
match List.tryFind (fun (FunDec (x, _, _, _, _)) -> x = fname) prog with
|
||||
| None -> FunName fname
|
||||
| Some (FunDec (_, rettype, paramls, body, pos)) ->
|
||||
inlineInFunArg graph prog (Lambda (rettype, paramls, body, pos))
|
||||
|
||||
and inlineFuncall (fname : string)
|
||||
(graph : CallGraph)
|
||||
(prog : TypedProg)
|
||||
(args : TypedExp list)
|
||||
(pos : Position) =
|
||||
match List.tryFind (fun (FunDec(x, _, _, _, _)) -> x = fname) prog with
|
||||
| None -> Apply (fname, List.map ( inlineInExp graph prog) args, pos)
|
||||
| Some (FunDec (_, _, paramls, body, _)) ->
|
||||
let parNames = List.map (fun (Param (v,t)) -> v) paramls
|
||||
// let paramBindings = List.zip parNames args (* too simplistic *)
|
||||
let uniq = newSuffix () (* can use same suffix for all pars *)
|
||||
let parNames1 = List.map (fun v -> v + uniq) parNames
|
||||
let paramBindings =
|
||||
List.zip parNames1 args @
|
||||
List.zip parNames (List.map (fun v -> Var (v,pos)) parNames1)
|
||||
let rec mkLetsAroundBody = function
|
||||
| [] -> body
|
||||
| ((paramname, arg) :: rest) ->
|
||||
Let ( Dec ( paramname, arg, pos),
|
||||
mkLetsAroundBody rest,
|
||||
pos)
|
||||
inlineInExp graph prog (mkLetsAroundBody paramBindings)
|
||||
|
||||
let inlineInFunction (graph : CallGraph)
|
||||
(prog : TypedProg)
|
||||
(FunDec (fname, rettype, paramls, body, pos)) =
|
||||
FunDec (fname, rettype, paramls, inlineInExp graph prog body, pos)
|
||||
|
||||
let inlineOptimiseProgram (prog : TypedProg) =
|
||||
let graph = callGraph prog
|
||||
List.map (inlineInFunction graph prog) prog
|
||||
@@ -0,0 +1,376 @@
|
||||
(* An interpreter for Fasto. *)
|
||||
|
||||
module Interpreter
|
||||
|
||||
(*
|
||||
|
||||
An interpreter executes a (Fasto) program by inspecting the abstract syntax
|
||||
tree of the program, and doing what needs to be done in another programming
|
||||
language (F#).
|
||||
|
||||
As mentioned in AbSyn.fs, some Fasto expressions are implicitly typed. The
|
||||
interpreter infers the missing types, and checks the types of the operands
|
||||
before performing any Fasto operation. Some type errors might still occur though.
|
||||
|
||||
Any valid Fasto program must contain a "main" function, which is the entry
|
||||
point of the program. The return value of this function is the result of the
|
||||
Fasto program.
|
||||
|
||||
The main function of interest in this module is:
|
||||
|
||||
val evalProg : AbSyn.UntypedProg -> AbSyn.Value
|
||||
|
||||
*)
|
||||
|
||||
open System
|
||||
open AbSyn
|
||||
|
||||
(* An exception for reporting run-time errors. *)
|
||||
exception MyError of string * Position
|
||||
|
||||
type FunTable = SymTab.SymTab<UntypedFunDec>
|
||||
type VarTable = SymTab.SymTab<Value>
|
||||
|
||||
(* Build a function table, which associates a function names with function
|
||||
declarations. *)
|
||||
let rec buildFtab (fdecs : UntypedFunDec list) : FunTable =
|
||||
match fdecs with
|
||||
| [] -> let p = (0, 0)
|
||||
let ch = 'a'
|
||||
let fdec_chr = FunDec ("chr", Char, [Param ("n", Int) ], Constant (CharVal ch, p), p)
|
||||
let fdec_ord = FunDec ("ord", Int, [Param ("c", Char)], Constant (IntVal 1, p), p)
|
||||
SymTab.fromList [("chr", fdec_chr); ("ord", fdec_ord)]
|
||||
| ( fdcl::fs ) ->
|
||||
(* Bind the user-defined functions, in reverse order. *)
|
||||
let fid = getFunName fdcl
|
||||
let pos = getFunPos fdcl
|
||||
let ftab = buildFtab fs
|
||||
match SymTab.lookup fid ftab with
|
||||
| None -> SymTab.bind fid fdcl ftab
|
||||
| Some ofdecl ->
|
||||
(* Report the first occurrence of the name. *)
|
||||
raise (MyError ("Already defined function: "+fid, getFunPos ofdecl))
|
||||
|
||||
(* Check whether a value matches a type. *)
|
||||
let rec typeMatch (tpval : Type * Value) : bool =
|
||||
match tpval with
|
||||
| ( Int, IntVal _ ) -> true
|
||||
| ( Bool, BoolVal _) -> true
|
||||
| ( Char, CharVal _) -> true
|
||||
| ( Array t, ArrayVal (vals, tp) ) ->
|
||||
(t = tp) && (List.map (fun value -> typeMatch (t, value)) vals |> List.fold (&&) true)
|
||||
| (_, _) -> false
|
||||
|
||||
let reportBadType (str : string)
|
||||
(want : string)
|
||||
(v : Value)
|
||||
(pos : Position) =
|
||||
let msg = "Bad type for " + str + ": expected " + want + ", but got " +
|
||||
ppType (valueType v) + " (" + (ppVal 0 v) + ")"
|
||||
raise (MyError(msg, pos))
|
||||
|
||||
let reportWrongType str tp v pos = reportBadType str (ppType tp) v pos
|
||||
|
||||
let reportNonArray str v pos = reportBadType str "an array" v pos
|
||||
|
||||
(* Bind the formal parameters of a function declaration to actual parameters in
|
||||
a new vtab. *)
|
||||
|
||||
let rec bindParams (fargs : Param list)
|
||||
(aargs : Value list)
|
||||
(fid : String)
|
||||
(pdec : Position)
|
||||
(pcall : Position) : VarTable =
|
||||
match (fargs, aargs) with
|
||||
| ([], []) -> SymTab.empty ()
|
||||
| (Param (faid, fatp) :: fargs, v :: aargs) ->
|
||||
let vtab = bindParams fargs aargs fid pdec pcall
|
||||
if typeMatch(fatp, v)
|
||||
then match SymTab.lookup faid vtab with
|
||||
None -> SymTab.bind faid v vtab
|
||||
| Some m -> raise (MyError( "Formal argument is already in symbol table!"+
|
||||
" In function: "+fid+" formal argument: "+faid
|
||||
, pdec ))
|
||||
else reportWrongType ("argument " + faid + " of function " + fid)
|
||||
fatp v pcall
|
||||
| (_, _) -> raise (MyError("Number of formal and actual params do not match in call to "+fid,
|
||||
pcall))
|
||||
|
||||
|
||||
(* Interpreter for Fasto expressions:
|
||||
1. vtab holds bindings between variable names and
|
||||
their interpreted value (Fasto.Value).
|
||||
2. ftab holds bindings between function names and
|
||||
function declarations (Fasto.FunDec).
|
||||
3. Returns the interpreted value. *)
|
||||
let rec evalExp (e : UntypedExp, vtab : VarTable, ftab : FunTable) : Value =
|
||||
match e with
|
||||
| Constant (v,_) -> v
|
||||
| ArrayLit (l, t, pos) ->
|
||||
let els = (List.map (fun x -> evalExp(x, vtab, ftab)) l)
|
||||
let elt = match els with
|
||||
| [] -> Int (* Arbitrary *)
|
||||
| v::_ -> valueType v
|
||||
ArrayVal (els, elt)
|
||||
| StringLit(s, pos) ->
|
||||
let cvs = List.map (fun c -> CharVal c) (Seq.toList s)
|
||||
ArrayVal (cvs, Char)
|
||||
| Var(id, pos) ->
|
||||
let res = SymTab.lookup id vtab
|
||||
match res with
|
||||
| None -> raise (MyError("Unknown variable "+id, pos))
|
||||
| Some m -> m
|
||||
| Plus(e1, e2, pos) ->
|
||||
let res1 = evalExp(e1, vtab, ftab)
|
||||
let res2 = evalExp(e2, vtab, ftab)
|
||||
match (res1, res2) with
|
||||
| (IntVal n1, IntVal n2) -> IntVal (n1+n2)
|
||||
| (IntVal _, _) -> reportWrongType "right operand of +" Int res2 (expPos e2)
|
||||
| (_, _) -> reportWrongType "left operand of +" Int res1 (expPos e1)
|
||||
| Minus(e1, e2, pos) ->
|
||||
let res1 = evalExp(e1, vtab, ftab)
|
||||
let res2 = evalExp(e2, vtab, ftab)
|
||||
match (res1, res2) with
|
||||
| (IntVal n1, IntVal n2) -> IntVal (n1-n2)
|
||||
| (IntVal _, _) -> reportWrongType "right operand of -" Int res2 (expPos e2)
|
||||
| (_, _) -> reportWrongType "left operand of -" Int res1 (expPos e1)
|
||||
(* TODO: project task 1:
|
||||
Look in `AbSyn.fs` for the arguments of the `Times`
|
||||
(`Divide`,...) expression constructors.
|
||||
Implementation similar to the cases of Plus/Minus.
|
||||
Try to pattern match the code above.
|
||||
For `Divide`, remember to check for attempts to divide by zero.
|
||||
For `And`/`Or`: make sure to implement the short-circuit semantics,
|
||||
e.g., `And (e1, e2, pos)` should not evaluate `e2` if `e1` already
|
||||
evaluates to false.
|
||||
*)
|
||||
| Times(_, _, _) ->
|
||||
failwith "Unimplemented interpretation of multiplication"
|
||||
| Divide(_, _, _) ->
|
||||
failwith "Unimplemented interpretation of division"
|
||||
| And (_, _, _) ->
|
||||
failwith "Unimplemented interpretation of &&"
|
||||
| Or (_, _, _) ->
|
||||
failwith "Unimplemented interpretation of ||"
|
||||
| Not(_, _) ->
|
||||
failwith "Unimplemented interpretation of not"
|
||||
| Negate(_, _) ->
|
||||
failwith "Unimplemented interpretation of negate"
|
||||
| Equal(e1, e2, pos) ->
|
||||
let r1 = evalExp(e1, vtab, ftab)
|
||||
let r2 = evalExp(e2, vtab, ftab)
|
||||
match (r1, r2) with
|
||||
| (IntVal n1, IntVal n2) -> BoolVal (n1 = n2)
|
||||
| (BoolVal b1, BoolVal b2) -> BoolVal (b1 = b2)
|
||||
| (CharVal c1, CharVal c2) -> BoolVal (c1 = c2)
|
||||
| (ArrayVal _, _) -> reportBadType "left operand of =" "a base type" r1 pos
|
||||
| (_, _) -> reportWrongType "right operand of =" (valueType r1) r2 pos
|
||||
| Less(e1, e2, pos) ->
|
||||
let r1 = evalExp(e1, vtab, ftab)
|
||||
let r2 = evalExp(e2, vtab, ftab)
|
||||
match (r1, r2) with
|
||||
| (IntVal n1, IntVal n2 ) -> BoolVal (n1 < n2)
|
||||
| (BoolVal false, BoolVal true) -> BoolVal true
|
||||
| (BoolVal _, BoolVal _ ) -> BoolVal false
|
||||
| (CharVal c1, CharVal c2 ) -> BoolVal ( (int c1) < (int c2) )
|
||||
| (ArrayVal _, _) -> reportBadType "left operand of <" "a base type" r1 pos
|
||||
| (_, _) -> reportWrongType "right operand of <" (valueType r1) r2 pos
|
||||
| If(e1, e2, e3, pos) ->
|
||||
let cond = evalExp(e1, vtab, ftab)
|
||||
match cond with
|
||||
| BoolVal true -> evalExp(e2, vtab, ftab)
|
||||
| BoolVal false -> evalExp(e3, vtab, ftab)
|
||||
| other -> reportWrongType "if condition" Bool cond (expPos e1)
|
||||
//raise (MyError("If condition is not a boolean", pos))
|
||||
(* The case of length receives special treatment below *)
|
||||
| Apply("length", [arg], pos) ->
|
||||
let evarg = evalExp(arg, vtab, ftab)
|
||||
match evarg with
|
||||
| ArrayVal (lst, _) -> IntVal (List.length lst)
|
||||
| otherwise -> reportNonArray "argument of length" evarg pos
|
||||
| Apply("length", args, pos) ->
|
||||
let msg = sprintf "Call to length function expects exactly one arg, given: %i" (List.length args)
|
||||
raise (MyError(msg, pos))
|
||||
(* general case of function application *)
|
||||
| Apply(fid, args, pos) ->
|
||||
let evargs = List.map (fun e -> evalExp(e, vtab, ftab)) args
|
||||
match (SymTab.lookup fid ftab) with
|
||||
| Some f -> callFunWithVtable(f, evargs, SymTab.empty(), ftab, pos)
|
||||
| None -> raise (MyError("Call to unknown function "+fid, pos))
|
||||
| Let(Dec(id,e,p), exp, pos) ->
|
||||
let res = evalExp(e, vtab, ftab)
|
||||
let nvtab = SymTab.bind id res vtab
|
||||
evalExp(exp, nvtab, ftab)
|
||||
| Index(id, e, tp, pos) ->
|
||||
let indv = evalExp(e, vtab, ftab)
|
||||
let arr = SymTab.lookup id vtab
|
||||
match (arr, indv) with
|
||||
| (None, _) -> raise (MyError("Unknown array variable "+id, pos))
|
||||
| (Some (ArrayVal(lst, tp)), IntVal ind) ->
|
||||
let len = List.length(lst)
|
||||
if( len > ind && ind >= 0 )
|
||||
then lst.Item(ind)
|
||||
else let msg = sprintf "Array index out of bounds! Array length: %i, index: %i" len ind
|
||||
raise (MyError( msg, pos ))
|
||||
| (Some m, IntVal _) -> reportNonArray ("indexing into " + id) m pos
|
||||
| (_, _) -> reportWrongType "indexing expression" Int indv pos
|
||||
| Iota (e, pos) ->
|
||||
let sz = evalExp(e, vtab, ftab)
|
||||
match sz with
|
||||
| IntVal size ->
|
||||
if size >= 0
|
||||
then ArrayVal( List.map (fun x -> IntVal x) [0..size-1], Int )
|
||||
else let msg = sprintf "Argument of \"iota\" is negative: %i" size
|
||||
raise (MyError(msg, pos))
|
||||
| _ -> reportWrongType "argument of \"iota\"" Int sz pos
|
||||
| Map (farg, arrexp, _, _, pos) ->
|
||||
let arr = evalExp(arrexp, vtab, ftab)
|
||||
let farg_ret_type = rtpFunArg farg ftab pos
|
||||
match arr with
|
||||
| ArrayVal (lst,tp1) ->
|
||||
let mlst = List.map (fun x -> evalFunArg (farg, vtab, ftab, pos, [x])) lst
|
||||
ArrayVal (mlst, farg_ret_type)
|
||||
| otherwise -> reportNonArray "2nd argument of \"map\"" arr pos
|
||||
| Reduce (farg, ne, arrexp, tp, pos) ->
|
||||
let farg_ret_type = rtpFunArg farg ftab pos
|
||||
let arr = evalExp(arrexp, vtab, ftab)
|
||||
let nel = evalExp(ne, vtab, ftab)
|
||||
match arr with
|
||||
| ArrayVal (lst,tp1) ->
|
||||
List.fold (fun acc x -> evalFunArg (farg, vtab, ftab, pos, [acc;x])) nel lst
|
||||
| otherwise -> reportNonArray "3rd argument of \"reduce\"" arr pos
|
||||
(* TODO project task 2: `replicate(n, a)`
|
||||
Look in `AbSyn.fs` for the arguments of the `Replicate`
|
||||
(`Map`,`Scan`) expression constructors.
|
||||
- evaluate `n` then evaluate `a`,
|
||||
- check that `n` evaluates to an integer value >= 0
|
||||
- If so then create an array containing `n` replicas of
|
||||
the value of `a`; otherwise raise an error (containing
|
||||
a meaningful message).
|
||||
*)
|
||||
| Replicate (_, _, _, _) ->
|
||||
failwith "Unimplemented interpretation of replicate"
|
||||
|
||||
(* TODO project task 2: `filter(p, arr)`
|
||||
pattern match the implementation of map:
|
||||
- check that the function `p` result type (use `rtpFunArg`) is bool;
|
||||
- evaluate `arr` and check that the (value) result corresponds to an array;
|
||||
- use F# `List.filter` to keep only the elements `a` of `arr` which succeed
|
||||
under predicate `p`, i.e., `p(a) = true`;
|
||||
- create an `ArrayVal` from the (list) result of the previous step.
|
||||
*)
|
||||
| Filter (_, _, _, _) ->
|
||||
failwith "Unimplemented interpretation of filter"
|
||||
|
||||
(* TODO project task 2: `scan(f, ne, arr)`
|
||||
Implementation similar to reduce, except that it produces an array
|
||||
of the same type and length to the input array `arr`.
|
||||
*)
|
||||
| Scan (_, _, _, _, _) ->
|
||||
failwith "Unimplemented interpretation of scan"
|
||||
|
||||
| Read (t,p) ->
|
||||
let str = Console.ReadLine()
|
||||
match t with
|
||||
| Int -> let v : int = int str
|
||||
IntVal v
|
||||
| Bool when str = "true" -> BoolVal true
|
||||
| Bool when str = "false" -> BoolVal false
|
||||
| Char -> let v : char = char str
|
||||
CharVal v
|
||||
| otherwise -> raise (MyError("Read operation is valid only on basic types ", p))
|
||||
|
||||
| Write(exp,t,p) ->
|
||||
let v = evalExp(exp, vtab, ftab)
|
||||
match v with
|
||||
| IntVal n -> printfn "%i " n
|
||||
| BoolVal b -> let res = if(b) then "true " else "false "
|
||||
printfn "%s" res
|
||||
| CharVal c -> printfn "%c " c
|
||||
| ArrayVal (a, Char) ->
|
||||
let mapfun = function
|
||||
| CharVal c -> c
|
||||
| otherwise -> raise (MyError("Write argument " +
|
||||
ppVal 0 v +
|
||||
" should have been evaluated to string", p))
|
||||
printfn "%s" ( System.String.Concat (List.map mapfun a) )
|
||||
| otherwise -> raise (MyError("Write can be called only on basic and array(char) types ", p))
|
||||
v
|
||||
|
||||
|
||||
|
||||
(* finds the return type of a function argument *)
|
||||
and rtpFunArg (funarg : UntypedFunArg)
|
||||
(ftab : FunTable)
|
||||
(callpos : Position)
|
||||
: Type =
|
||||
match funarg with
|
||||
| FunName fid ->
|
||||
match SymTab.lookup fid ftab with
|
||||
| None -> raise (MyError("Call to unknown function "+fid, callpos))
|
||||
| Some (FunDec (_, rettype, _, _, _)) -> rettype
|
||||
| Lambda (rettype, _, _, _) -> rettype
|
||||
|
||||
(* evalFunArg takes as argument a FunArg, a vtable, an ftable, the
|
||||
position where the call is performed, and the list of actual arguments.
|
||||
It returns the result of calling the (lambda) function.
|
||||
*)
|
||||
and evalFunArg ( funarg : UntypedFunArg
|
||||
, vtab : VarTable
|
||||
, ftab : FunTable
|
||||
, callpos : Position
|
||||
, aargs : Value list
|
||||
) : Value =
|
||||
match funarg with
|
||||
| (FunName fid) ->
|
||||
let fexp = SymTab.lookup fid ftab
|
||||
match fexp with
|
||||
| None -> raise (MyError("Call to known function "+fid, callpos))
|
||||
| Some f -> callFunWithVtable(f, aargs, SymTab.empty(), ftab, callpos)
|
||||
| Lambda (rettype, parms, body, fpos) ->
|
||||
callFunWithVtable ( FunDec ("<anonymous>", rettype, parms, body, fpos)
|
||||
, aargs, vtab, ftab, callpos )
|
||||
|
||||
(* Interpreter for Fasto function calls:
|
||||
1. f is the function declaration.
|
||||
2. args is a list of (already interpreted) arguments.
|
||||
3. vtab is the variable symbol table
|
||||
4. ftab is the function symbol table (containing f itself).
|
||||
5. pcall is the position of the function call. *)
|
||||
and callFunWithVtable (fundec : UntypedFunDec
|
||||
, aargs : Value list
|
||||
, vtab : VarTable
|
||||
, ftab : FunTable
|
||||
, pcall : Position
|
||||
) : Value =
|
||||
let (FunDec (fid, rtp, fargs, body, pdcl)) = fundec
|
||||
match fid with
|
||||
(* treat the special functions *)
|
||||
| "ord" -> match aargs with
|
||||
| [CharVal c] -> IntVal (int c)
|
||||
| [v] -> reportWrongType "argument of \"ord\"" Char v pcall
|
||||
| _ -> raise (MyError ("Wrong argument count for \"ord\"", pcall))
|
||||
| "chr" -> match aargs with
|
||||
| [IntVal n] -> CharVal (char n)
|
||||
| [v] -> reportWrongType "argument of \"chr\"" Int v pcall
|
||||
| _ -> raise (MyError ("Wrong argument count for \"chr\"", pcall))
|
||||
| _ ->
|
||||
let vtab' = SymTab.combine (bindParams fargs aargs fid pdcl pcall) vtab
|
||||
let res = evalExp (body, vtab', ftab)
|
||||
if typeMatch (rtp, res)
|
||||
then res
|
||||
else reportWrongType ("result of function \"" + fid + "\"") rtp res pcall
|
||||
|
||||
(* Interpreter for Fasto programs:
|
||||
1. builds the function symbol table,
|
||||
2. interprets the body of "main", and
|
||||
3. returns its result. *)
|
||||
and evalProg (prog : UntypedProg) : Value =
|
||||
let ftab = buildFtab prog
|
||||
let mainf = SymTab.lookup "main" ftab
|
||||
match mainf with
|
||||
| None -> raise (MyError("Could not find the main function", (0,0)))
|
||||
| Some m ->
|
||||
match getFunArgs m with
|
||||
| [] -> callFunWithVtable(m, [], SymTab.empty(), ftab, (0,0))
|
||||
| _ -> raise (MyError("The main function is not allowed to have parameters", getFunPos m))
|
||||
@@ -0,0 +1,267 @@
|
||||
# 18 "Lexer.fsl"
|
||||
|
||||
module Lexer
|
||||
|
||||
open System;;
|
||||
open FSharp.Text.Lexing;;
|
||||
open System.Text;;
|
||||
|
||||
(* A lexer definition for Fasto, for use with fslex. *)
|
||||
|
||||
(* boilerplate code for all lexer files... *)
|
||||
let mutable currentLine = 1
|
||||
let mutable lineStartPos = [0]
|
||||
|
||||
let rec getLineCol pos line = function
|
||||
| (p1::ps) ->
|
||||
if pos>=p1
|
||||
then (line, pos-p1)
|
||||
else getLineCol pos (line-1) ps
|
||||
| [] -> (0,0) (* should not happen *)
|
||||
|
||||
let getPos (lexbuf : LexBuffer<'char>) =
|
||||
getLineCol lexbuf.StartPos.pos_cnum
|
||||
(currentLine)
|
||||
(lineStartPos)
|
||||
|
||||
exception LexicalError of string * (int * int) (* (message, (line, column)) *)
|
||||
|
||||
let lexerError lexbuf s =
|
||||
raise (LexicalError (s, getPos lexbuf))
|
||||
|
||||
(* This one is language specific, yet very common. Alternative would
|
||||
be to encode every keyword as a regexp. This one is much easier.
|
||||
Note that here we recognize specific keywords, and if none matches
|
||||
then we assume we have found a user-defined identifier (last case).
|
||||
*)
|
||||
let keyword (s, pos) =
|
||||
match s with
|
||||
| "if" -> Parser.IF pos
|
||||
| "then" -> Parser.THEN pos
|
||||
| "else" -> Parser.ELSE pos
|
||||
| "let" -> Parser.LET pos
|
||||
| "in" -> Parser.IN pos
|
||||
| "int" -> Parser.INT pos
|
||||
| "bool" -> Parser.BOOL pos
|
||||
| "char" -> Parser.CHAR pos
|
||||
| "fun" -> Parser.FUN pos
|
||||
| "fn" -> Parser.FN pos
|
||||
| "op" -> Parser.OP pos
|
||||
|
||||
(* specials: *)
|
||||
| "iota" -> Parser.IOTA pos
|
||||
| "map" -> Parser.MAP pos
|
||||
| "reduce" -> Parser.REDUCE pos
|
||||
| "read" -> Parser.READ pos
|
||||
| "write" -> Parser.WRITE pos
|
||||
| _ -> Parser.ID (s, pos)
|
||||
|
||||
|
||||
# 60 "Lexer.fs"
|
||||
let trans : uint16[] array =
|
||||
[|
|
||||
(* State 0 *)
|
||||
[|21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 1us; 2us; 21us; 2us; 1us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 1us; 21us; 8us; 21us; 21us; 21us; 21us; 7us; 13us; 14us; 21us; 9us; 19us; 10us; 21us; 3us; 4us; 5us; 5us; 5us; 5us; 5us; 5us; 5us; 5us; 5us; 21us; 21us; 12us; 11us; 21us; 21us; 21us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 15us; 21us; 16us; 21us; 21us; 21us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 17us; 21us; 18us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 21us; 20us; |];
|
||||
(* State 1 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 34us; 65535us; 65535us; 65535us; 34us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 34us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 2 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 3 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 32us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 4 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 5 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 31us; 31us; 31us; 31us; 31us; 31us; 31us; 31us; 31us; 31us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 6 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 65535us; 65535us; 65535us; 65535us; 30us; 65535us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 7 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 27us; 27us; 65535us; 27us; 27us; 27us; 27us; 65535us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 28us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 27us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 8 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 25us; 25us; 24us; 25us; 25us; 25us; 25us; 65535us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 26us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 9 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 10 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 11 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 23us; 22us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 12 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 13 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 14 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 15 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 16 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 17 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 18 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 19 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 20 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 21 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 22 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 23 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 24 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 25 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 25us; 25us; 24us; 25us; 25us; 25us; 25us; 65535us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 26us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 26 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 25us; 65535us; 65535us; 65535us; 65535us; 25us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 25us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 25us; 65535us; 65535us; 65535us; 65535us; 65535us; 25us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 27 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 29us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 28 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 27us; 65535us; 65535us; 65535us; 65535us; 27us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 27us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 27us; 65535us; 65535us; 65535us; 65535us; 65535us; 27us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 29 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 30 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 65535us; 65535us; 65535us; 65535us; 30us; 65535us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 31 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 31us; 31us; 31us; 31us; 31us; 31us; 31us; 31us; 31us; 31us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
(* State 32 *)
|
||||
[|33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 65535us; 33us; 65535us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 65535us; |];
|
||||
(* State 33 *)
|
||||
[|33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 65535us; 33us; 65535us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 65535us; |];
|
||||
(* State 34 *)
|
||||
[|65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 34us; 65535us; 65535us; 65535us; 34us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 34us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |];
|
||||
|]
|
||||
let actions : uint16[] = [|65535us; 0us; 1us; 21us; 3us; 3us; 4us; 21us; 21us; 7us; 8us; 11us; 12us; 13us; 14us; 15us; 16us; 17us; 18us; 19us; 20us; 21us; 9us; 10us; 6us; 65535us; 65535us; 65535us; 65535us; 5us; 4us; 3us; 2us; 2us; 0us; |]
|
||||
let _fslex_tables = FSharp.Text.Lexing.AsciiTables.Create(trans,actions)
|
||||
let rec _fslex_dummy () = _fslex_dummy()
|
||||
// Rule Token
|
||||
and Token lexbuf =
|
||||
match _fslex_tables.Interpret(0,lexbuf) with
|
||||
| 0 -> (
|
||||
# 78 "Lexer.fsl"
|
||||
Token lexbuf
|
||||
# 143 "Lexer.fs"
|
||||
)
|
||||
| 1 -> (
|
||||
# 79 "Lexer.fsl"
|
||||
currentLine <- currentLine + 1;
|
||||
lineStartPos <- lexbuf.StartPos.pos_cnum
|
||||
:: lineStartPos;
|
||||
Token lexbuf
|
||||
# 151 "Lexer.fs"
|
||||
)
|
||||
| 2 -> (
|
||||
# 83 "Lexer.fsl"
|
||||
Token lexbuf
|
||||
# 156 "Lexer.fs"
|
||||
)
|
||||
| 3 -> (
|
||||
# 85 "Lexer.fsl"
|
||||
Parser.NUM
|
||||
( int (Encoding.UTF8.GetString(lexbuf.Lexeme))
|
||||
, getPos lexbuf )
|
||||
|
||||
# 164 "Lexer.fs"
|
||||
)
|
||||
| 4 -> (
|
||||
# 90 "Lexer.fsl"
|
||||
keyword ( Encoding.UTF8.GetString(lexbuf.Lexeme)
|
||||
, getPos lexbuf )
|
||||
# 170 "Lexer.fs"
|
||||
)
|
||||
| 5 -> (
|
||||
# 93 "Lexer.fsl"
|
||||
let str0 = Encoding.UTF8.GetString(lexbuf.Lexeme)
|
||||
let str1 = str0.Substring (1, (String.length str0) - 2)
|
||||
let str2 = AbSyn.fromCString str1
|
||||
Parser.CHARLIT (str2.Chars(0), getPos lexbuf)
|
||||
|
||||
# 179 "Lexer.fs"
|
||||
)
|
||||
| 6 -> (
|
||||
# 99 "Lexer.fsl"
|
||||
|
||||
let str0 = Encoding.UTF8.GetString(lexbuf.Lexeme)
|
||||
let str1 = str0.Substring (1, (String.length str0) - 2)
|
||||
Parser.STRINGLIT (AbSyn.fromCString str1, getPos lexbuf)
|
||||
|
||||
# 188 "Lexer.fs"
|
||||
)
|
||||
| 7 -> (
|
||||
# 104 "Lexer.fsl"
|
||||
Parser.PLUS (getPos lexbuf)
|
||||
# 193 "Lexer.fs"
|
||||
)
|
||||
| 8 -> (
|
||||
# 105 "Lexer.fsl"
|
||||
Parser.MINUS (getPos lexbuf)
|
||||
# 198 "Lexer.fs"
|
||||
)
|
||||
| 9 -> (
|
||||
# 106 "Lexer.fsl"
|
||||
Parser.ARROW (getPos lexbuf)
|
||||
# 203 "Lexer.fs"
|
||||
)
|
||||
| 10 -> (
|
||||
# 107 "Lexer.fsl"
|
||||
Parser.DEQ (getPos lexbuf)
|
||||
# 208 "Lexer.fs"
|
||||
)
|
||||
| 11 -> (
|
||||
# 108 "Lexer.fsl"
|
||||
Parser.EQ (getPos lexbuf)
|
||||
# 213 "Lexer.fs"
|
||||
)
|
||||
| 12 -> (
|
||||
# 109 "Lexer.fsl"
|
||||
Parser.LTH (getPos lexbuf)
|
||||
# 218 "Lexer.fs"
|
||||
)
|
||||
| 13 -> (
|
||||
# 110 "Lexer.fsl"
|
||||
Parser.LPAR (getPos lexbuf)
|
||||
# 223 "Lexer.fs"
|
||||
)
|
||||
| 14 -> (
|
||||
# 111 "Lexer.fsl"
|
||||
Parser.RPAR (getPos lexbuf)
|
||||
# 228 "Lexer.fs"
|
||||
)
|
||||
| 15 -> (
|
||||
# 112 "Lexer.fsl"
|
||||
Parser.LBRACKET (getPos lexbuf)
|
||||
# 233 "Lexer.fs"
|
||||
)
|
||||
| 16 -> (
|
||||
# 113 "Lexer.fsl"
|
||||
Parser.RBRACKET (getPos lexbuf)
|
||||
# 238 "Lexer.fs"
|
||||
)
|
||||
| 17 -> (
|
||||
# 114 "Lexer.fsl"
|
||||
Parser.LCURLY (getPos lexbuf)
|
||||
# 243 "Lexer.fs"
|
||||
)
|
||||
| 18 -> (
|
||||
# 115 "Lexer.fsl"
|
||||
Parser.RCURLY (getPos lexbuf)
|
||||
# 248 "Lexer.fs"
|
||||
)
|
||||
| 19 -> (
|
||||
# 116 "Lexer.fsl"
|
||||
Parser.COMMA (getPos lexbuf)
|
||||
# 253 "Lexer.fs"
|
||||
)
|
||||
| 20 -> (
|
||||
# 117 "Lexer.fsl"
|
||||
Parser.EOF (getPos lexbuf)
|
||||
# 258 "Lexer.fs"
|
||||
)
|
||||
| 21 -> (
|
||||
# 118 "Lexer.fsl"
|
||||
lexerError lexbuf "Illegal symbol in input"
|
||||
# 263 "Lexer.fs"
|
||||
)
|
||||
| _ -> failwith "Token"
|
||||
|
||||
# 3000000 "Lexer.fs"
|
||||
@@ -0,0 +1,118 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// TODO: project task 1
|
||||
// implement lexer tokens for the new operators:
|
||||
// multiplication (*), division (/), numerical negation (~),
|
||||
// logical negation (not), logical and (&&), logical or (||),
|
||||
// boolean literals (true, false), semicolon (;)
|
||||
//
|
||||
//
|
||||
// TODO: project task 2
|
||||
// implement lexer tokens (keywords) for replicate, filter, scan
|
||||
//
|
||||
//
|
||||
// TODO: project task 4
|
||||
// implement the lexer tokens (keywords) for array comprehension
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
{
|
||||
module Lexer
|
||||
|
||||
open System;;
|
||||
open FSharp.Text.Lexing;;
|
||||
open System.Text;;
|
||||
|
||||
(* A lexer definition for Fasto, for use with fslex. *)
|
||||
|
||||
(* boilerplate code for all lexer files... *)
|
||||
let mutable currentLine = 1
|
||||
let mutable lineStartPos = [0]
|
||||
|
||||
let rec getLineCol pos line = function
|
||||
| (p1::ps) ->
|
||||
if pos>=p1
|
||||
then (line, pos-p1)
|
||||
else getLineCol pos (line-1) ps
|
||||
| [] -> (0,0) (* should not happen *)
|
||||
|
||||
let getPos (lexbuf : LexBuffer<'char>) =
|
||||
getLineCol lexbuf.StartPos.pos_cnum
|
||||
(currentLine)
|
||||
(lineStartPos)
|
||||
|
||||
exception LexicalError of string * (int * int) (* (message, (line, column)) *)
|
||||
|
||||
let lexerError lexbuf s =
|
||||
raise (LexicalError (s, getPos lexbuf))
|
||||
|
||||
(* This one is language specific, yet very common. Alternative would
|
||||
be to encode every keyword as a regexp. This one is much easier.
|
||||
Note that here we recognize specific keywords, and if none matches
|
||||
then we assume we have found a user-defined identifier (last case).
|
||||
*)
|
||||
let keyword (s, pos) =
|
||||
match s with
|
||||
| "if" -> Parser.IF pos
|
||||
| "then" -> Parser.THEN pos
|
||||
| "else" -> Parser.ELSE pos
|
||||
| "let" -> Parser.LET pos
|
||||
| "in" -> Parser.IN pos
|
||||
| "int" -> Parser.INT pos
|
||||
| "bool" -> Parser.BOOL pos
|
||||
| "char" -> Parser.CHAR pos
|
||||
| "fun" -> Parser.FUN pos
|
||||
| "fn" -> Parser.FN pos
|
||||
| "op" -> Parser.OP pos
|
||||
|
||||
(* specials: *)
|
||||
| "iota" -> Parser.IOTA pos
|
||||
| "map" -> Parser.MAP pos
|
||||
| "reduce" -> Parser.REDUCE pos
|
||||
| "read" -> Parser.READ pos
|
||||
| "write" -> Parser.WRITE pos
|
||||
| _ -> Parser.ID (s, pos)
|
||||
|
||||
}
|
||||
|
||||
rule Token = parse
|
||||
[' ' '\t' '\r']+ { Token lexbuf } (* whitespace *)
|
||||
| ['\n' '\012'] { currentLine <- currentLine + 1;
|
||||
lineStartPos <- lexbuf.StartPos.pos_cnum
|
||||
:: lineStartPos;
|
||||
Token lexbuf } (* newlines *)
|
||||
| "//" [^ '\n' '\012']* { Token lexbuf } (* comment *)
|
||||
|
||||
| '0' | ['1'-'9']['0'-'9']* { Parser.NUM
|
||||
( int (Encoding.UTF8.GetString(lexbuf.Lexeme))
|
||||
, getPos lexbuf )
|
||||
}
|
||||
| ['a'-'z' 'A'-'Z']['a'-'z' 'A'-'Z' '0'-'9' '_']*
|
||||
{ keyword ( Encoding.UTF8.GetString(lexbuf.Lexeme)
|
||||
, getPos lexbuf ) }
|
||||
| '\'' ( [' ' '!' '#'-'&' '('-'[' ']'-'~'] | '\\' ['n' 't' '\'' '"' '\\'] ) '\''
|
||||
{ let str0 = Encoding.UTF8.GetString(lexbuf.Lexeme)
|
||||
let str1 = str0.Substring (1, (String.length str0) - 2)
|
||||
let str2 = AbSyn.fromCString str1
|
||||
Parser.CHARLIT (str2.Chars(0), getPos lexbuf)
|
||||
}
|
||||
| '"' ( [' ' '!' '#'-'&' '('-'[' ']'-'~'] | '\\' ['n' 't' '\'' '"' '\\'] )* '"'
|
||||
{
|
||||
let str0 = Encoding.UTF8.GetString(lexbuf.Lexeme)
|
||||
let str1 = str0.Substring (1, (String.length str0) - 2)
|
||||
Parser.STRINGLIT (AbSyn.fromCString str1, getPos lexbuf)
|
||||
}
|
||||
| '+' { Parser.PLUS (getPos lexbuf) }
|
||||
| '-' { Parser.MINUS (getPos lexbuf) }
|
||||
| "=>" { Parser.ARROW (getPos lexbuf) }
|
||||
| "==" { Parser.DEQ (getPos lexbuf) }
|
||||
| '=' { Parser.EQ (getPos lexbuf) }
|
||||
| '<' { Parser.LTH (getPos lexbuf) }
|
||||
| '(' { Parser.LPAR (getPos lexbuf) }
|
||||
| ')' { Parser.RPAR (getPos lexbuf) }
|
||||
| '[' { Parser.LBRACKET (getPos lexbuf) }
|
||||
| ']' { Parser.RBRACKET (getPos lexbuf) }
|
||||
| '{' { Parser.LCURLY (getPos lexbuf) }
|
||||
| '}' { Parser.RCURLY (getPos lexbuf) }
|
||||
| ',' { Parser.COMMA (getPos lexbuf) }
|
||||
| eof { Parser.EOF (getPos lexbuf) }
|
||||
| _ { lexerError lexbuf "Illegal symbol in input" }
|
||||
@@ -0,0 +1,127 @@
|
||||
(* Types and utilities for the abstract syntax of MIPS. *)
|
||||
|
||||
module Mips
|
||||
|
||||
open AbSyn
|
||||
|
||||
type reg = RN of int | RS of string
|
||||
type imm = int
|
||||
type addr = string
|
||||
|
||||
type Instruction =
|
||||
LABEL of addr (* Angiver en label, man fx kan hoppe til *)
|
||||
| COMMENT of string (* Placerer en kommentar i assemblerkoden *)
|
||||
|
||||
| LA of reg*addr (* LA($rd,addr): $rd = addr (label) *)
|
||||
| LUI of reg*imm (* LUI($rd,imm): $rd = (imm << 16) *)
|
||||
| LW of reg*reg*imm (* LW($rd,$rs,imm): $rd = Mem[$rs + imm] *)
|
||||
| LB of reg*reg*imm (* LB($rd,$rs,imm): $rd = Mem[$rs + imm] *)
|
||||
| SW of reg*reg*imm (* SW($rw,$rm,imm): Mem[$rm + imm] = $rw *)
|
||||
| SB of reg*reg*imm (* SB($rb,$rm,imm): Mem[$rm + imm] = $rb *)
|
||||
|
||||
(* Aritmetiske instruktioner *)
|
||||
| ADD of reg*reg*reg (* ADD($rd,$rs,$rt): $rd = $rs + $rt. *)
|
||||
| ADDI of reg*reg*imm (* ADDI($rd,$rs,imm): $rd = $rs + imm *)
|
||||
| SUB of reg*reg*reg (* SUB($rd,$rs,$rt): $rd = $rs - $rt. *)
|
||||
| MUL of reg*reg*reg (* MUL($rd,$rs,$rt): $rd = $rs * $rt, no overflow. *)
|
||||
| DIV of reg*reg*reg (* DIV($rd,$rs,$rt): $rd = quotient($rd / $rs), no overflow. *)
|
||||
|
||||
(* Bitvise operatorer *)
|
||||
| AND of reg*reg*reg (* AND($rd,$rs,$rt): $rd = $rs & $rt *)
|
||||
| ANDI of reg*reg*imm (* ANDI($rd,$rs,imm): $rd = $rs & imm *)
|
||||
| OR of reg*reg*reg (* OR($rd,$rs,$rt): $rd = $rs | $rt *)
|
||||
| ORI of reg*reg*imm (* ORI($rd,$rs,imm): $rd = $rs | imm *)
|
||||
| XOR of reg*reg*reg (* XOR($rd,$rs,$rt): $rd = $rs ^ $rt *)
|
||||
| XORI of reg*reg*imm (* XORI($rd,$rs,imm): $rd = $rs ^ imm *)
|
||||
|
||||
(* Bit-shifting *)
|
||||
| SLL of reg*reg*imm (* SLL($rd,$rs,imm): $rd = $rs << imm *)
|
||||
| SRA of reg*reg*imm (* SRA($rd,$rs,imm): $rd = $rs >> imm *)
|
||||
|
||||
(* Instruktioner til sammenligning *)
|
||||
| SLT of reg*reg*reg (* SLT($rd,$rs,$rt): $rd = $rs < $rt *)
|
||||
| SLTI of reg*reg*imm (* SLTI($rd,$rs,imm): $rd = $rs < imm *)
|
||||
| BEQ of reg*reg*addr (* BEQ($rs,$rt,addr): if ($rs == $rd) goto(addr) *)
|
||||
| BNE of reg*reg*addr (* BNE($rs,$rt,addr): if ($rs != $rd) goto(addr) *)
|
||||
| BGEZ of reg*addr (* BGEZ($rs,addr): if ($rs >= $0) goto(addr) *)
|
||||
| J of addr (* J(addr): goto(addr) *)
|
||||
| JR of reg * reg list (* JR($rd,regs): goto($rd) *)
|
||||
| JAL of addr* reg list (* JAL(addr,regs): $RA = $PC; goto(addr) *)
|
||||
| NOP
|
||||
| SYSCALL (* Udfører det systemkald som er nævnt i $2 *)
|
||||
|
||||
(* Angiver direktiverne .globl, .text, .data, .space, ascii, .asciiz, .align *)
|
||||
| GLOBL of addr
|
||||
| TEXT of addr
|
||||
| DATA of addr
|
||||
| SPACE of int
|
||||
| ASCII of string
|
||||
| ASCIIZ of string
|
||||
| ALIGN of int
|
||||
|
||||
(* Diverse pseudo-instruktioner *)
|
||||
let MOVE (rd,rs) = ORI (rd, rs, 0) (* MOVE($rd,$rs): $rd = $rs *)
|
||||
let LI (rd,imm) = ORI (rd, RN 0, imm) (* LI($rd,imm): $rd = imm *)
|
||||
let SUBI (rd, rs, imm) = ADDI (rd, rs, -imm)
|
||||
|
||||
type Prog = Instruction list
|
||||
|
||||
(* Pretty-print a list of MIPS instructions in the
|
||||
format accepted by the MARS MIPS simulator. *)
|
||||
let rec ppMipsProg instructions =
|
||||
String.concat "\n" (List.map ppMips instructions)
|
||||
|
||||
(* Pretty-print a single MIPS instruction for .asm output *)
|
||||
and ppMips inst =
|
||||
match inst with
|
||||
| LABEL l -> l + ":"
|
||||
| COMMENT s -> "# " + s
|
||||
|
||||
| LA (rt,l) -> "\tla\t" + ppReg rt + ", " + l
|
||||
| LUI (rt,v) -> "\tlui\t" + ppReg rt + ", " + imm2str v
|
||||
| LW (rd,rs,v) -> "\tlw\t" + ppReg rd + ", " + imm2str v + "(" + ppReg rs + ")"
|
||||
| LB (rd,rs,v) -> "\tlb\t" + ppReg rd + ", " + imm2str v + "(" + ppReg rs + ")"
|
||||
| SW (rd,rs,v) -> "\tsw\t" + ppReg rd + ", " + imm2str v + "(" + ppReg rs + ")"
|
||||
| SB (rd,rs,v) -> "\tsb\t" + ppReg rd + ", " + imm2str v + "(" + ppReg rs + ")"
|
||||
|
||||
| ADD (rd,rs,rt) -> "\tadd\t" + ppReg rd + ", " + ppReg rs + ", " + ppReg rt
|
||||
| ADDI (rd,rs,v) -> "\taddi\t" + ppReg rd + ", " + ppReg rs + ", " + imm2str v
|
||||
| SUB (rd,rs,rt) -> "\tsub\t" + ppReg rd + ", " + ppReg rs + ", " + ppReg rt
|
||||
| MUL (rd,rs,rt) -> "\tmul\t" + ppReg rd + ", " + ppReg rs + ", " + ppReg rt
|
||||
| DIV (rd,rs,rt) -> "\tdiv\t" + ppReg rd + ", " + ppReg rs + ", " + ppReg rt
|
||||
|
||||
| AND (rd,rs,rt) -> "\tand\t" + ppReg rd + ", " + ppReg rs + ", " + ppReg rt
|
||||
| ANDI (rd,rs,v) -> "\tandi\t" + ppReg rd + ", " + ppReg rs + ", " + imm2str v
|
||||
| OR (rd,rs,rt) -> "\tor\t" + ppReg rd + ", " + ppReg rs + ", " + ppReg rt
|
||||
| ORI (rd,rs,v) -> "\tori\t" + ppReg rd + ", " + ppReg rs + ", " + imm2str v
|
||||
| XOR (rd,rs,rt) -> "\txor\t" + ppReg rd + ", " + ppReg rs + ", " + ppReg rt
|
||||
| XORI (rd,rs,v) -> "\txori\t" + ppReg rd + ", " + ppReg rs + ", " + imm2str v
|
||||
|
||||
| SLL (rd,rt,v) -> "\tsll\t" + ppReg rd + ", " + ppReg rt + ", " + imm2str v
|
||||
| SRA (rd,rt,v) -> "\tsra\t" + ppReg rd + ", " + ppReg rt + ", " + imm2str v
|
||||
|
||||
| SLT (rd,rs,rt) -> "\tslt\t" + ppReg rd + ", " + ppReg rs + ", " + ppReg rt
|
||||
| SLTI (rd,rs,v) -> "\tslti\t" + ppReg rd + ", " + ppReg rs + ", " + imm2str v
|
||||
| BEQ (rs,rt,l) -> "\tbeq\t" + ppReg rs + ", " + ppReg rt + ", " + l
|
||||
| BNE (rs,rt,l) -> "\tbne\t" + ppReg rs + ", " + ppReg rt + ", " + l
|
||||
| BGEZ (rs,l) -> "\tbgez\t" + ppReg rs + ", " + l
|
||||
| J l -> "\tj\t" + l
|
||||
| JAL (l,argRegs) -> "\tjal\t" + l
|
||||
| JR (r,resRegs) -> "\tjr\t" + ppReg r
|
||||
| NOP -> "\tnop"
|
||||
| SYSCALL -> "\tsyscall"
|
||||
|
||||
| GLOBL s -> "\t.globl\t" + s
|
||||
| TEXT s -> "\t.text\t" + s
|
||||
| DATA s -> "\t.data\t" + s
|
||||
| SPACE s -> "\t.space\t" + string s
|
||||
| ASCII s -> "\t.ascii\t\"" + toCString s + "\""
|
||||
| ASCIIZ s -> "\t.asciiz\t\"" + toCString s + "\""
|
||||
| ALIGN s -> "\t.align\t" + string s
|
||||
|
||||
and ppReg r =
|
||||
match r with
|
||||
| RN n -> "$" + string n
|
||||
| RS s -> s
|
||||
|
||||
and imm2str (i:imm) = string i (* maybe add some sanity checks here *)
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,101 @@
|
||||
// Signature file for parser generated by fsyacc
|
||||
module Parser
|
||||
type token =
|
||||
| LPAR of (Position)
|
||||
| RPAR of (Position)
|
||||
| LBRACKET of (Position)
|
||||
| RBRACKET of (Position)
|
||||
| LCURLY of (Position)
|
||||
| RCURLY of (Position)
|
||||
| FUN of (Position)
|
||||
| FN of (Position)
|
||||
| COMMA of (Position)
|
||||
| SEMICOLON of (Position)
|
||||
| READ of (Position)
|
||||
| WRITE of (Position)
|
||||
| DEQ of (Position)
|
||||
| LTH of (Position)
|
||||
| EQ of (Position)
|
||||
| OP of (Position)
|
||||
| MAP of (Position)
|
||||
| REDUCE of (Position)
|
||||
| IOTA of (Position)
|
||||
| ARROW of (Position)
|
||||
| PLUS of (Position)
|
||||
| MINUS of (Position)
|
||||
| LESS of (Position)
|
||||
| INT of (Position)
|
||||
| CHAR of (Position)
|
||||
| BOOL of (Position)
|
||||
| IF of (Position)
|
||||
| THEN of (Position)
|
||||
| ELSE of (Position)
|
||||
| LET of (Position)
|
||||
| IN of (Position)
|
||||
| EOF of (Position)
|
||||
| ID of (string * Position)
|
||||
| STRINGLIT of (string * Position)
|
||||
| CHARLIT of (char * Position)
|
||||
| NUM of (int * Position)
|
||||
type tokenId =
|
||||
| TOKEN_LPAR
|
||||
| TOKEN_RPAR
|
||||
| TOKEN_LBRACKET
|
||||
| TOKEN_RBRACKET
|
||||
| TOKEN_LCURLY
|
||||
| TOKEN_RCURLY
|
||||
| TOKEN_FUN
|
||||
| TOKEN_FN
|
||||
| TOKEN_COMMA
|
||||
| TOKEN_SEMICOLON
|
||||
| TOKEN_READ
|
||||
| TOKEN_WRITE
|
||||
| TOKEN_DEQ
|
||||
| TOKEN_LTH
|
||||
| TOKEN_EQ
|
||||
| TOKEN_OP
|
||||
| TOKEN_MAP
|
||||
| TOKEN_REDUCE
|
||||
| TOKEN_IOTA
|
||||
| TOKEN_ARROW
|
||||
| TOKEN_PLUS
|
||||
| TOKEN_MINUS
|
||||
| TOKEN_LESS
|
||||
| TOKEN_INT
|
||||
| TOKEN_CHAR
|
||||
| TOKEN_BOOL
|
||||
| TOKEN_IF
|
||||
| TOKEN_THEN
|
||||
| TOKEN_ELSE
|
||||
| TOKEN_LET
|
||||
| TOKEN_IN
|
||||
| TOKEN_EOF
|
||||
| TOKEN_ID
|
||||
| TOKEN_STRINGLIT
|
||||
| TOKEN_CHARLIT
|
||||
| TOKEN_NUM
|
||||
| TOKEN_end_of_input
|
||||
| TOKEN_error
|
||||
type nonTerminalId =
|
||||
| NONTERM__startProg
|
||||
| NONTERM_Prog
|
||||
| NONTERM_FunDecs
|
||||
| NONTERM_Fun
|
||||
| NONTERM_Type
|
||||
| NONTERM_Params
|
||||
| NONTERM_BinOp
|
||||
| NONTERM_Exp
|
||||
| NONTERM_Exps
|
||||
| NONTERM_FunArg
|
||||
/// This function maps tokens to integer indexes
|
||||
val tagOfToken: token -> int
|
||||
|
||||
/// This function maps integer indexes to symbolic token ids
|
||||
val tokenTagToTokenId: int -> tokenId
|
||||
|
||||
/// This function maps production indexes returned in syntax errors to strings representing the non terminal that would be produced by that production
|
||||
val prodIdxToNonTerminal: int -> nonTerminalId
|
||||
|
||||
/// This function gets the name of a token as a string
|
||||
val token_to_string: token -> string
|
||||
val Prog : (FSharp.Text.Lexing.LexBuffer<'cty> -> token) -> FSharp.Text.Lexing.LexBuffer<'cty> -> (AbSyn.UntypedProg)
|
||||
@@ -0,0 +1,149 @@
|
||||
|
||||
%{
|
||||
|
||||
let p0 = (0,0)
|
||||
|
||||
open FSharp.Text.Parsing
|
||||
open AbSyn
|
||||
|
||||
(* parse-error function *)
|
||||
let mutable ErrorContextDescriptor : string = ""
|
||||
|
||||
let parse_error_rich =
|
||||
Some (fun (ctxt: ParseErrorContext<_>) ->
|
||||
ErrorContextDescriptor <-
|
||||
match ctxt.CurrentToken with
|
||||
| None -> "At beginning of input\n"
|
||||
| Some token -> sprintf "at token %A\n" token
|
||||
)
|
||||
|
||||
%}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// TODO: Add new (lexer) token definitions:
|
||||
//
|
||||
// TODO: project task 1 :
|
||||
// - multiplication (*), division (/), numerical negation (~),
|
||||
// logical negation (not), logical and (&&), logical or (||),
|
||||
// boolean literals (true, false)
|
||||
// - add the required precedence and associativity rules for
|
||||
// *, /, ~, not, &&, ||
|
||||
// - generalize the syntax of let-expressions to allow
|
||||
// multiple variable declarations
|
||||
//
|
||||
// TODO: project task 2: replicate, filter, scan
|
||||
//
|
||||
// TODO: project task 4: array comprehension
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
%token <int * Position> NUM
|
||||
%token <char * Position> CHARLIT
|
||||
%token <string * Position> ID STRINGLIT
|
||||
%token <Position> IF THEN ELSE LET IN EOF
|
||||
%token <Position> INT CHAR BOOL
|
||||
%token <Position> PLUS MINUS LESS
|
||||
%token <Position> DEQ LTH EQ OP MAP REDUCE IOTA ARROW
|
||||
%token <Position> FUN FN COMMA SEMICOLON READ WRITE
|
||||
%token <Position> LPAR RPAR LBRACKET RBRACKET LCURLY RCURLY
|
||||
|
||||
%nonassoc ifprec letprec
|
||||
%left DEQ LTH
|
||||
%left PLUS MINUS
|
||||
|
||||
%start Prog
|
||||
%type <AbSyn.UntypedProg> Prog
|
||||
%type <AbSyn.UntypedFunDec list> FunDecs
|
||||
%type <AbSyn.UntypedFunDec> Fun
|
||||
%type <AbSyn.Type> Type
|
||||
%type <AbSyn.UntypedExp> Exp
|
||||
%type <AbSyn.UntypedExp list> Exps
|
||||
%type <AbSyn.UntypedFunArg> FunArg
|
||||
// TODO: Task 1(b): add any new nonterminals here
|
||||
|
||||
%%
|
||||
|
||||
Prog : FunDecs EOF { $1 }
|
||||
;
|
||||
|
||||
FunDecs : FUN Fun FunDecs { $2 :: $3 }
|
||||
| FUN Fun { $2 :: [] }
|
||||
;
|
||||
|
||||
Fun : Type ID LPAR Params RPAR EQ Exp
|
||||
{ FunDec (fst $2, $1, $4, $7, snd $2) }
|
||||
| Type ID LPAR RPAR EQ Exp
|
||||
{ FunDec (fst $2, $1, [], $6, snd $2) }
|
||||
;
|
||||
|
||||
Type : INT { AbSyn.Int }
|
||||
| CHAR { AbSyn.Char }
|
||||
| BOOL { AbSyn.Bool }
|
||||
| LBRACKET Type RBRACKET { AbSyn.Array $2 }
|
||||
;
|
||||
|
||||
Params : Type ID COMMA Params
|
||||
{ Param (fst $2, $1) :: $4 }
|
||||
| Type ID { Param (fst $2, $1) :: [] }
|
||||
;
|
||||
|
||||
|
||||
BinOp : PLUS { (Lambda
|
||||
(Int, [Param ("x", Int);
|
||||
Param ("y", Int)],
|
||||
Plus (Var ("x", $1),
|
||||
Var ("y", $1),
|
||||
$1) ,$1))}
|
||||
;
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// TODO: project tasks 1,2,4:
|
||||
// add grammer rules for the new expressions
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
Exp : NUM { Constant (IntVal (fst $1), snd $1) }
|
||||
| CHARLIT { Constant (CharVal (fst $1), snd $1) }
|
||||
| ID { Var $1 }
|
||||
| STRINGLIT { StringLit $1 }
|
||||
| LCURLY Exps RCURLY
|
||||
{ ArrayLit ($2, (), $1) }
|
||||
| Exp PLUS Exp { Plus ($1, $3, $2) }
|
||||
| Exp MINUS Exp { Minus($1, $3, $2) }
|
||||
| Exp DEQ Exp { Equal($1, $3, $2) }
|
||||
| Exp LTH Exp { Less ($1, $3, $2) }
|
||||
| IF Exp THEN Exp ELSE Exp %prec ifprec
|
||||
{ If ($2, $4, $6, $1) }
|
||||
| ID LPAR Exps RPAR
|
||||
{ Apply (fst $1, $3, snd $1) }
|
||||
| ID LPAR RPAR { Apply (fst $1, [], snd $1) }
|
||||
| READ LPAR Type RPAR
|
||||
{ Read ($3, $1) }
|
||||
| WRITE LPAR Exp RPAR
|
||||
{ Write ($3, (), $1) }
|
||||
| IOTA LPAR Exp RPAR
|
||||
{ Iota ($3, $1) }
|
||||
| MAP LPAR FunArg COMMA Exp RPAR
|
||||
{ Map ($3, $5, (), (), $1) }
|
||||
| REDUCE LPAR FunArg COMMA Exp COMMA Exp RPAR
|
||||
{ Reduce ($3, $5, $7, (), $1) }
|
||||
| REDUCE LPAR OP BinOp COMMA Exp COMMA Exp RPAR
|
||||
{ Reduce ($4, $6, $8, (), $1) }
|
||||
| LPAR Exp RPAR { $2 }
|
||||
// TODO: task 1(b): replace this with a more general production
|
||||
| LET ID EQ Exp IN Exp %prec letprec
|
||||
{ Let (Dec (fst $2, $4, $3), $6, $1) }
|
||||
| ID LBRACKET Exp RBRACKET
|
||||
{ Index (fst $1, $3, (), $2) }
|
||||
;
|
||||
|
||||
Exps : Exp COMMA Exps { $1 :: $3 }
|
||||
| Exp { $1 :: [] }
|
||||
;
|
||||
|
||||
FunArg : ID { FunName (fst $1 ) }
|
||||
| FN Type LPAR RPAR ARROW Exp
|
||||
{ Lambda ($2, [], $6, $1) }
|
||||
| FN Type LPAR Params RPAR ARROW Exp
|
||||
{ Lambda ($2, $4, $7, $1) }
|
||||
;
|
||||
|
||||
%%
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,493 @@
|
||||
(* A register allocator for MIPS. *)
|
||||
|
||||
module RegAlloc
|
||||
|
||||
(* registerAlloc takes a list of MIPS instructions, a set of
|
||||
registers that are live at the end of the code, three register
|
||||
numbers:
|
||||
1) The lowest allocatable register (typically 2).
|
||||
2) The highest caller-saves register.
|
||||
3) The highest allocatable register (typically 25).
|
||||
and the number of already spilled variables. This should be 0 in the initial
|
||||
call unless some variables are forced to spill before register allocation.
|
||||
Registers up to (and including) the highest caller-saves
|
||||
register are assumed to be caller-saves. Those above are assumed to
|
||||
be callee-saves.
|
||||
|
||||
registerAlloc returns:
|
||||
a modified instruction list where null moves have been removed,
|
||||
a set of the variables that are live at entry,
|
||||
plus a number indicating the highest used register number.
|
||||
|
||||
The latter can be used for deciding which callee-saves registers
|
||||
need to be saved.
|
||||
|
||||
Limitations:
|
||||
|
||||
- Works for a single procedure body only.
|
||||
|
||||
- Assumes all JALs eventually return to the next instruction and
|
||||
preserve callee-saves registers when doing so.
|
||||
|
||||
- Does caller-saves preservation only by allocating variables that
|
||||
are live across procedure calls to callee-saves registers and
|
||||
variables not live across call preferably to caller-saves.
|
||||
|
||||
- Can only remove null moves if they are implemented by ORI (rx,ry,"0").
|
||||
Use the pseudo-instruction MOVE (rx,ry) for this.
|
||||
|
||||
*)
|
||||
|
||||
open Mips
|
||||
|
||||
exception MyError of string
|
||||
|
||||
exception Not_colourable of string
|
||||
|
||||
let spilledVars : Set<string> ref = ref (Set.empty)
|
||||
|
||||
let rec destRegs (lst : Instruction list) : Set<reg> =
|
||||
match lst with
|
||||
| [] -> Set.empty
|
||||
| (i::ilist) -> Set.union (destReg i) (destRegs ilist)
|
||||
|
||||
|
||||
(* variables and registers that can be overwritten *)
|
||||
and destReg (i : Instruction) : Set<reg> =
|
||||
match i with
|
||||
| LA (rt,v) -> Set.singleton rt
|
||||
| LUI (rt,v) -> Set.singleton rt
|
||||
| ADD (rd,rs,rt) -> Set.singleton rd
|
||||
| ADDI (rd,rs,v) -> Set.singleton rd
|
||||
| SUB (rd,rs,rt) -> Set.singleton rd
|
||||
| MUL (rd,rs,rt) -> Set.singleton rd
|
||||
| DIV (rd,rs,rt) -> Set.singleton rd
|
||||
| AND (rd,rs,rt) -> Set.singleton rd
|
||||
| ANDI (rd,rs,v) -> Set.singleton rd
|
||||
| OR (rd,rs,rt) -> Set.singleton rd
|
||||
| ORI (rd,rs,v) -> Set.singleton rd
|
||||
| XOR (rd,rs,rt) -> Set.singleton rd
|
||||
| XORI (rd,rs,v) -> Set.singleton rd
|
||||
| SLL (rd,rt,v) -> Set.singleton rd
|
||||
| SRA (rd,rt,v) -> Set.singleton rd
|
||||
| SLT (rd,rs,rt) -> Set.singleton rd
|
||||
| SLTI (rd,rs,v) -> Set.singleton rd
|
||||
| JAL (lab,argRegs) -> Set.add (RN 31) (Set.ofList argRegs)
|
||||
| LW (rd,rs,v) -> Set.singleton rd
|
||||
| LB (rd,rs,v) -> Set.singleton rd
|
||||
| SYSCALL -> Set.singleton (RN 2) (* return value is in $2 *)
|
||||
| _ -> Set.empty
|
||||
|
||||
(* variables and register that can be read by i *)
|
||||
let usedRegs (i : Instruction) : Set<reg> =
|
||||
match i with
|
||||
| ADD (rd,rs,rt) -> Set.ofList [rs;rt]
|
||||
| ADDI (rd,rs,v) -> Set.singleton rs
|
||||
| SUB (rd,rs,rt) -> Set.ofList [rs;rt]
|
||||
| MUL (rd,rs,rt) -> Set.ofList [rs;rt]
|
||||
| DIV (rd,rs,rt) -> Set.ofList [rs;rt]
|
||||
| AND (rd,rs,rt) -> Set.ofList [rs;rt]
|
||||
| ANDI (rd,rs,v) -> Set.singleton rs
|
||||
| OR (rd,rs,rt) -> Set.ofList [rs;rt]
|
||||
| ORI (rd,rs,v) -> Set.singleton rs
|
||||
| XOR (rd,rs,rt) -> Set.ofList [rs;rt]
|
||||
| XORI (rd,rs,v) -> Set.singleton rs
|
||||
| SLL (rd,rt,v) -> Set.singleton rt
|
||||
| SRA (rd,rt,v) -> Set.singleton rt
|
||||
| SLT (rd,rs,rt) -> Set.ofList [rs;rt]
|
||||
| SLTI (rd,rs,v) -> Set.singleton rs
|
||||
| BEQ (rs,rt,v) -> Set.ofList [rs;rt]
|
||||
| BNE (rs,rt,v) -> Set.ofList [rs;rt]
|
||||
| BGEZ (rs,v) -> Set.singleton rs
|
||||
| J lab -> Set.empty
|
||||
| JAL (lab,argRegs) -> Set.ofList argRegs
|
||||
(* argRegs are argument registers *)
|
||||
| JR (r,resRegs) -> Set.ofList (r::resRegs)
|
||||
(* r is jump register,
|
||||
resRegs are registers required to be live *)
|
||||
| LW (rd,rs,v) -> Set.singleton rs
|
||||
| SW (rd,rs,v) -> Set.ofList [rs;rd]
|
||||
| LB (rd,rs,v) -> Set.singleton rs
|
||||
| SB (rd,rs,v) -> Set.ofList [rs;rd]
|
||||
| SYSCALL -> Set.ofList [RN 2; RN 4; RN 5]
|
||||
(* $2 is control register and $4, $5 are arguments *)
|
||||
| _ -> Set.empty
|
||||
|
||||
|
||||
let live_step ilist llist liveAtEnd =
|
||||
let rec scan (is : Instruction list) =
|
||||
match is with
|
||||
| [] -> []
|
||||
| (i::is) ->
|
||||
let ls1 = scan is
|
||||
if List.isEmpty ls1
|
||||
then [instruct i liveAtEnd]
|
||||
else (instruct i (List.head ls1)) :: ls1
|
||||
|
||||
(* live variables and registers *)
|
||||
and instruct (i : Instruction) (live : Set<reg>) : Set<reg> =
|
||||
match i with
|
||||
| BEQ (rs,rt,v) -> Set.union (Set.ofList [rs;rt]) (Set.union live (live_at v))
|
||||
| BNE (rs,rt,v) -> Set.union (Set.ofList [rs;rt]) (Set.union live (live_at v))
|
||||
| BGEZ (rs,v) -> Set.union (Set.singleton rs) (Set.union live (live_at v))
|
||||
| J lab -> live_at lab
|
||||
| JR (r,resRegs) -> Set.ofList (r::resRegs)
|
||||
(* r is jump register, resRegs are registers required to be live *)
|
||||
| _ -> Set.union (usedRegs i) (Set.difference live (destReg i))
|
||||
|
||||
and live_at lab : Set<reg> = search ilist llist lab
|
||||
|
||||
and search a1 a2 a3 : Set<reg> =
|
||||
match (a1, a2, a3) with
|
||||
| ([], [], lab) -> Set.empty
|
||||
| (LABEL k :: is, l::ls, lab) ->
|
||||
if k = lab then l else search is ls lab
|
||||
| (_::is, _::ls, lab) -> search is ls lab
|
||||
| (a, b, l) -> raise (MyError "should not happen in RegAlloc.live_step.search!")
|
||||
|
||||
let res = scan ilist
|
||||
res
|
||||
|
||||
let rec iterate_live ilist llist liveAtEnd =
|
||||
let llist1 = live_step ilist llist liveAtEnd
|
||||
if llist1 = llist
|
||||
then llist
|
||||
else iterate_live ilist llist1 liveAtEnd
|
||||
|
||||
let rec init_list = function
|
||||
| [] -> []
|
||||
| (i::is) -> Set.empty :: init_list is
|
||||
|
||||
(* live_regs finds for each instruction those symbolic register names *)
|
||||
(* that are live at entry to this instruction *)
|
||||
|
||||
let live_regs ilist liveAtEnd =
|
||||
iterate_live ilist (init_list ilist) liveAtEnd
|
||||
|
||||
let rec regs lst (rs : Set<reg>) : Set<reg> =
|
||||
match lst with
|
||||
| [] -> rs
|
||||
| (l :: llist) -> Set.union l (regs llist rs)
|
||||
|
||||
let numerical r =
|
||||
match r with
|
||||
| RN _ -> true
|
||||
| RS _ -> false
|
||||
|
||||
let filterSymbolic rs = Set.filter (fun a -> not (numerical a)) rs
|
||||
|
||||
let rec findRegs llist = filterSymbolic (regs llist Set.empty)
|
||||
|
||||
(* conflicts ilist llist callerSaves r *)
|
||||
(* finds those variables that interferere with r *)
|
||||
(* in instructions ilist with live-out specified by llist *)
|
||||
(* callerSaves are the caller-saves registers *)
|
||||
|
||||
let rec conflicts = function
|
||||
| ([], [], callerSaves, RN r) -> Set.remove (RN r) callerSaves
|
||||
(* all numerical interfere with all other caller-saves *)
|
||||
| ([], [], callerSaves, RS _) -> Set.empty
|
||||
| (ORI (rd,rs,0) :: ilist, l :: llist, callerSaves, r) ->
|
||||
if r=rd (* if destination *)
|
||||
then Set.union (Set.remove rs (Set.remove r l)) (* interfere with live except rs *)
|
||||
(conflicts (ilist, llist, callerSaves, r))
|
||||
else if r=rs (* if source, no interference *)
|
||||
then conflicts (ilist, llist, callerSaves, r)
|
||||
else if Set.contains r l (* otherwise, live interfere with rd *)
|
||||
then Set.add rd (conflicts (ilist, llist, callerSaves, r))
|
||||
else conflicts (ilist, llist, callerSaves, r)
|
||||
| (JAL (f,argRegs) :: ilist, l :: llist, callerSaves, r) ->
|
||||
if (Set.contains r l) (* live vars interfere with caller-saves regs *)
|
||||
then Set.union (Set.remove r callerSaves)
|
||||
(conflicts (ilist, llist, callerSaves, r))
|
||||
else if Set.contains r callerSaves
|
||||
then Set.union (Set.remove r l)
|
||||
(conflicts (ilist, llist, callerSaves, r))
|
||||
else conflicts (ilist, llist, callerSaves, r)
|
||||
| (i :: ilist, l :: llist, callerSaves, r) ->
|
||||
if (Set.contains r (destReg i)) (* destination register *)
|
||||
then Set.union (Set.remove r l) (* conflicts with other live vars *)
|
||||
(conflicts (ilist, llist, callerSaves, r))
|
||||
else if Set.contains r l (* all live vars *)
|
||||
then Set.union (destReg i) (* conflict with destination *)
|
||||
(conflicts (ilist, llist, callerSaves, r))
|
||||
else conflicts (ilist, llist, callerSaves, r)
|
||||
| _ -> raise (MyError "conflicts used at undefined instance")
|
||||
|
||||
|
||||
|
||||
(* Interference graph is represented as a list of registers *)
|
||||
(* each paired with a list of the registers with which it conflicts *)
|
||||
|
||||
let graph ilist llist callerSaves =
|
||||
let rs = Set.union callerSaves (findRegs llist) |> Set.toList
|
||||
List.zip rs (List.map (fun r -> conflicts (ilist, ((List.tail llist)@[Set.empty]), callerSaves, r)) rs)
|
||||
|
||||
|
||||
|
||||
|
||||
(* finds move-related registers *)
|
||||
|
||||
let rec findMoves ilist llist =
|
||||
let rs = findRegs llist |> Set.toList
|
||||
List.zip rs (List.map (fun r -> findMoves1 r ilist) rs)
|
||||
|
||||
and findMoves1 r = function
|
||||
| [] -> Set.empty
|
||||
| (ORI (rd,rs,0) :: ilist) ->
|
||||
Set.union ( if rd=r then Set.singleton rs
|
||||
elif rs=r then Set.singleton rd
|
||||
else Set.empty)
|
||||
(findMoves1 r ilist)
|
||||
| (i::ilist) -> findMoves1 r ilist
|
||||
|
||||
|
||||
|
||||
(* sorts by number of conflicts, but with numeric registers last *)
|
||||
|
||||
let be4 (a, ac) (b, bc) =
|
||||
match (a, b) with
|
||||
| (RN i, RN j) -> i <= j
|
||||
| (RN _, RS _) -> false
|
||||
| (RS _, RN _) -> true
|
||||
| (RS sa, RS sb) ->
|
||||
match (Set.contains sa (!spilledVars), Set.contains sb (!spilledVars)) with
|
||||
| (false, false) -> Set.count ac <= Set.count bc
|
||||
| (true , false) -> false
|
||||
| (false, true ) -> true
|
||||
| (true , true ) -> Set.count ac <= Set.count bc
|
||||
|
||||
let rec sortByOrder = function
|
||||
| [] -> []
|
||||
| (g : (reg * Set<'b>) list) ->
|
||||
let rec split = function
|
||||
| [] -> ([],[])
|
||||
| (a::g) ->
|
||||
let (l, g1) = ascending a g []
|
||||
let (g2,g3) = split g1
|
||||
(rev2 l g3, g2)
|
||||
and ascending a g l =
|
||||
match g with
|
||||
| [] -> (a::l,[])
|
||||
| (b::g1) ->
|
||||
if be4 a b
|
||||
then ascending b g1 (a::l)
|
||||
else (a::l,g)
|
||||
and rev2 g l2 =
|
||||
match g with
|
||||
| [] -> l2
|
||||
| (a::l1) -> rev2 l1 (a::l2)
|
||||
|
||||
let rec merge = function
|
||||
| ([], l2) -> l2
|
||||
| (l1, []) -> l1
|
||||
| (a::r1, b::r2) ->
|
||||
if be4 a b
|
||||
then a :: merge (r1, b::r2)
|
||||
else b :: merge (a::r1, r2)
|
||||
|
||||
let (g1,g2) = split g
|
||||
if List.isEmpty g1 then g2
|
||||
elif List.isEmpty g2 then g1
|
||||
else merge (sortByOrder g1, sortByOrder g2)
|
||||
|
||||
|
||||
|
||||
(* n-colour graph using Briggs' algorithm *)
|
||||
|
||||
let rec colourGraph g rmin rmax moveRelated =
|
||||
select (simplify (sortByOrder g) [])
|
||||
(mList rmin rmax) moveRelated []
|
||||
|
||||
and simplify h l =
|
||||
match h with
|
||||
| [] -> l
|
||||
| (r,c) :: g ->
|
||||
simplify (sortByOrder (removeNode r g)) ((r,c)::l)
|
||||
|
||||
and removeNode r = function
|
||||
| [] -> []
|
||||
| ((r1,c)::g) ->
|
||||
(r1,Set.remove r c) :: removeNode r g
|
||||
|
||||
and select rcl regs moveRelated sl =
|
||||
match rcl with
|
||||
| [] -> sl
|
||||
| ((r,c)::l) ->
|
||||
let rnum =
|
||||
if numerical r then r
|
||||
else let possible = NotIn c sl regs
|
||||
let related = lookUp2 r moveRelated
|
||||
let related2 = Set.map (fun r -> lookUp r sl) related
|
||||
let mPossible= Set.intersect possible related2
|
||||
if Set.isEmpty possible then raise (Not_colourable (ppReg r))
|
||||
elif Set.isEmpty mPossible then Set.minElement possible //hd possible
|
||||
else Set.minElement mPossible //hd mPossible
|
||||
select l regs moveRelated ((r,rnum)::sl)
|
||||
|
||||
and NotIn rcs sl regs : Set<reg> =
|
||||
Set.fold (fun acc r -> Set.remove (lookUp r sl) acc) regs rcs
|
||||
|
||||
and lookUp r = function
|
||||
| [] -> RN 0
|
||||
| ((r1,n)::sl) ->
|
||||
if numerical r then r
|
||||
else if r=r1 then n else lookUp r sl
|
||||
|
||||
and lookUp2 r = function
|
||||
| [] -> Set.empty
|
||||
| ((r1,ms)::sl) -> if r=r1 then ms else lookUp2 r sl
|
||||
|
||||
and mList m n : Set<reg> =
|
||||
if m > n then Set.empty
|
||||
else Set.add (RN m) (mList (m+1) n)
|
||||
|
||||
|
||||
let rec filterNullMoves ilist allocs =
|
||||
match ilist with
|
||||
| [] -> []
|
||||
|
||||
| (ORI (rd,rs,0) :: ilist_tl) ->
|
||||
let rd1 = lookUp rd allocs
|
||||
let rs1 = lookUp rs allocs
|
||||
if rd1 = rs1 || rd1 = RN 0
|
||||
then COMMENT ("\tori\t"+ ppReg rd+","+ ppReg rs+",0")
|
||||
:: filterNullMoves ilist_tl allocs
|
||||
else ORI (rd,rs,0) :: filterNullMoves ilist_tl allocs
|
||||
|
||||
| (i :: ilist_tl) ->
|
||||
i :: filterNullMoves ilist_tl allocs
|
||||
|
||||
and printList = function
|
||||
| [] -> ""
|
||||
| (r :: rs) -> r+" "+ printList rs
|
||||
|
||||
let rec printGraph = function
|
||||
| [] -> []
|
||||
| ((r,rs) :: g) ->
|
||||
[COMMENT ("interferes: "+r+" with "+printList rs)]
|
||||
@ printGraph g
|
||||
|
||||
let renameReg allocs inst =
|
||||
let renTo inst1 = [inst1; COMMENT ("was:" + ppMips inst)]
|
||||
match inst with
|
||||
| LA (rt,l) ->
|
||||
renTo (LA (lookUp rt allocs, l))
|
||||
| LUI (rt,v) ->
|
||||
renTo (LUI (lookUp rt allocs, v))
|
||||
| ADD (rd,rs,rt) ->
|
||||
renTo (ADD (lookUp rd allocs, lookUp rs allocs, lookUp rt allocs))
|
||||
| ADDI (rd,rs,v) ->
|
||||
renTo (ADDI (lookUp rd allocs, lookUp rs allocs, v))
|
||||
| SUB (rd,rs,rt) ->
|
||||
renTo (SUB (lookUp rd allocs, lookUp rs allocs, lookUp rt allocs))
|
||||
| MUL (rd,rs,rt) ->
|
||||
renTo (MUL (lookUp rd allocs, lookUp rs allocs, lookUp rt allocs))
|
||||
| DIV (rd,rs,rt) ->
|
||||
renTo (DIV (lookUp rd allocs, lookUp rs allocs, lookUp rt allocs))
|
||||
| AND (rd,rs,rt) ->
|
||||
renTo (AND (lookUp rd allocs, lookUp rs allocs, lookUp rt allocs))
|
||||
| ANDI (rd,rs,v) ->
|
||||
renTo (ANDI (lookUp rd allocs, lookUp rs allocs, v))
|
||||
| OR (rd,rs,rt) ->
|
||||
renTo (OR (lookUp rd allocs, lookUp rs allocs, lookUp rt allocs))
|
||||
| ORI (rd,rs,v) ->
|
||||
renTo (ORI (lookUp rd allocs, lookUp rs allocs, v))
|
||||
| XOR (rd,rs,rt) ->
|
||||
renTo (XOR (lookUp rd allocs, lookUp rs allocs, lookUp rt allocs))
|
||||
| XORI (rd,rs,v) ->
|
||||
renTo (XORI (lookUp rd allocs, lookUp rs allocs, v))
|
||||
| SLL (rd,rt,v) ->
|
||||
renTo (SLL (lookUp rd allocs, lookUp rt allocs, v))
|
||||
| SRA (rd,rt,v) ->
|
||||
renTo (SRA (lookUp rd allocs, lookUp rt allocs, v))
|
||||
| SLT (rd,rs,rt) ->
|
||||
renTo (SLT (lookUp rd allocs, lookUp rs allocs, lookUp rt allocs))
|
||||
| SLTI (rd,rs,v) ->
|
||||
renTo (SLTI (lookUp rd allocs, lookUp rs allocs, v))
|
||||
| BEQ (rs,rt,l) ->
|
||||
renTo (BEQ (lookUp rs allocs, lookUp rt allocs, l))
|
||||
| BGEZ(rs,l) ->
|
||||
renTo (BGEZ(lookUp rs allocs, l))
|
||||
| BNE (rs,rt,l) ->
|
||||
renTo (BNE (lookUp rs allocs, lookUp rt allocs, l))
|
||||
| JAL (lab,argRegs) ->
|
||||
[JAL (lab, List.map (fun r -> lookUp r allocs) argRegs);
|
||||
COMMENT ("was:" + ppMips inst +
|
||||
", " + String.concat " " (List.map ppReg argRegs))]
|
||||
| JR (r, resRegs) ->
|
||||
[JR (lookUp r allocs, List.map (fun r -> lookUp r allocs) resRegs);
|
||||
COMMENT ("was:" + ppMips inst +
|
||||
", " + String.concat " " (List.map ppReg resRegs))]
|
||||
| LW (rd,rs,v) ->
|
||||
renTo (LW (lookUp rd allocs, lookUp rs allocs, v))
|
||||
| SW (rd,rs,v) ->
|
||||
renTo (SW (lookUp rd allocs, lookUp rs allocs, v))
|
||||
| LB (rd,rs,v) ->
|
||||
renTo (LB (lookUp rd allocs, lookUp rs allocs, v))
|
||||
| SB (rd,rs,v) ->
|
||||
renTo (SB (lookUp rd allocs, lookUp rs allocs, v))
|
||||
| _ -> [inst]
|
||||
|
||||
let spill1 i r offset =
|
||||
let d = destReg i
|
||||
let u = usedRegs i
|
||||
let hdlst = if Set.contains r u
|
||||
then [Mips.LW (r, RN 29, offset)]
|
||||
else []
|
||||
let tllst = if Set.contains r d
|
||||
then [Mips.SW (r, RN 29, offset)]
|
||||
else []
|
||||
hdlst @ [i] @ tllst
|
||||
|
||||
let rec spill ilist r offset =
|
||||
match ilist with
|
||||
| [] -> []
|
||||
| (i::is) -> spill1 i r offset @ spill is r offset
|
||||
|
||||
let rec maxreg lst m =
|
||||
match lst with
|
||||
| [] -> m
|
||||
| ((r,RN n)::rs) -> maxreg rs (if m < n then n else m)
|
||||
| ((_,RS _)::rs) -> raise (MyError "maxreg of non-numeric register")
|
||||
|
||||
(* arguments:
|
||||
ilist is list of MIPS instructions
|
||||
liveAtEnd is a set of variables that are live at the end of ilist
|
||||
rmin is first allocable register (caller-saves)
|
||||
callerMax is highest caller-saves register
|
||||
rmax is highest allocable register
|
||||
spilled is number of registers spilled so far -- should be 0 initially
|
||||
*)
|
||||
let rec registerAlloc (ilist : Mips.Instruction list)
|
||||
(liveAtEnd : Set<reg>)
|
||||
(rmin : int)
|
||||
(callerMax : int)
|
||||
(rmax : int)
|
||||
(spilled : int)
|
||||
: (Mips.Instruction list * Set<reg> * int * int) =
|
||||
try
|
||||
let llist = live_regs ilist liveAtEnd
|
||||
let callerSaves = mList rmin callerMax
|
||||
let iGraph = graph ilist llist callerSaves
|
||||
let moveRelated = findMoves ilist llist
|
||||
let allocs = colourGraph iGraph rmin rmax moveRelated
|
||||
let deadRegs = Set.difference (filterSymbolic (destRegs ilist))
|
||||
( (List.map (fun (x,_) -> x) allocs) |> Set.ofList )
|
||||
let allocs1 = allocs @ (List.map (fun r -> (r, RN 0)) (Set.toList deadRegs))
|
||||
let ilist1 = filterNullMoves ilist allocs1
|
||||
let ilist2 = List.concat (List.map (renameReg allocs1) ilist1)
|
||||
(ilist2, List.head llist, maxreg allocs 0, spilled)
|
||||
with
|
||||
| (Not_colourable sr) ->
|
||||
printfn "%s spilled\n" sr
|
||||
spilledVars := Set.add sr (!spilledVars)
|
||||
let offset = (4*spilled)
|
||||
let ilist' = spill ilist (RS sr) offset
|
||||
let ilist'' = [Mips.SW (RS sr, RN 29,offset)]
|
||||
@ ilist' @
|
||||
(if Set.contains (RS sr) liveAtEnd
|
||||
then [Mips.LW (RS sr, RN 29, offset)]
|
||||
else [])
|
||||
registerAlloc ilist'' liveAtEnd rmin callerMax rmax (spilled + 1)
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
(* A polymorphic symbol table. *)
|
||||
|
||||
module SymTab
|
||||
|
||||
open System
|
||||
|
||||
(*
|
||||
A symbol table is just a list of tuples identifiers and values. This allows for
|
||||
easy shadowing, as a shadowing binding can be quickly placed at the head of the
|
||||
list.
|
||||
*)
|
||||
type SymTab<'a> = SymTab of (string * 'a) list
|
||||
|
||||
let empty () = SymTab []
|
||||
|
||||
let rec lookup n tab =
|
||||
match tab with
|
||||
| SymTab [] -> None
|
||||
| SymTab ((n1,i1)::remtab) ->
|
||||
if n = n1
|
||||
then Some i1
|
||||
else lookup n (SymTab remtab)
|
||||
|
||||
let bind n i (SymTab stab) = SymTab ((n,i)::stab)
|
||||
|
||||
let remove n (SymTab stab) =
|
||||
SymTab (List.filter (fun (x, _) -> x <> n) stab)
|
||||
|
||||
let removeMany ns (SymTab stab) =
|
||||
SymTab (List.filter (fun (x, _) ->
|
||||
not (List.exists (fun y -> y = x) ns)) stab)
|
||||
|
||||
let combine (SymTab t1) (SymTab t2) = SymTab (t1 @ t2)
|
||||
|
||||
let fromList l = SymTab l
|
||||
|
||||
let toList (SymTab lst) = lst
|
||||
@@ -0,0 +1,38 @@
|
||||
(*
|
||||
A polymorphic symbol table.
|
||||
A symbol table is a data structure associating names (strings) with values. It
|
||||
is useful for keeping track of binidngs. Bindings can be shadowed --- the
|
||||
active binding is the one made most recently.
|
||||
*)
|
||||
|
||||
module SymTab
|
||||
(* A symbol table with values of type 'a. *)
|
||||
//type SymTab<'a> = SymTab of (string * 'a) list
|
||||
// when 'a : equality
|
||||
|
||||
(* Create an empty symbol table. *)
|
||||
val empty : unit -> SymTab<'a> when 'a : equality
|
||||
|
||||
(* Look up the active binding for the name. *)
|
||||
val lookup : string -> SymTab<'a> -> Option<'a>
|
||||
|
||||
(* Bind the name to a value, shadowing any existing
|
||||
binidngs with the same name. *)
|
||||
val bind : string -> 'a -> SymTab<'a> -> SymTab<'a>
|
||||
|
||||
(* Remove all existing bindings of the given name. *)
|
||||
val remove : string -> SymTab<'a > -> SymTab<'a>
|
||||
|
||||
(* Remove all existing bindings of all the given names. *)
|
||||
val removeMany : string list -> SymTab<'a > -> SymTab<'a >
|
||||
|
||||
(* Combine two symbol tables. The first table shadows the second. *)
|
||||
val combine : SymTab<'a > -> SymTab<'a > -> SymTab<'a >
|
||||
|
||||
(* Create a symbol table from a list of name-value pairs.
|
||||
In case of duplicates, the bindings are shadowed in reverse order from
|
||||
the head of the list. That is, the active binding will ne the one
|
||||
closest to the head of the list. *)
|
||||
val fromList : (string * 'a) list -> SymTab<'a >
|
||||
val toList : SymTab<'a > -> (string * 'a) list
|
||||
|
||||
@@ -0,0 +1,391 @@
|
||||
(* A type-checker for Fasto. *)
|
||||
|
||||
module TypeChecker
|
||||
|
||||
(*
|
||||
|
||||
A type-checker checks that all operations in a (Fasto) program are performed on
|
||||
operands of an appropriate type. Furthermore, a type-checker infers any types
|
||||
missing in the original program text, necessary for well-defined machine code
|
||||
generation.
|
||||
|
||||
The main function of interest in this module is:
|
||||
|
||||
val checkProg : Fasto.UnknownTypes.Prog -> Fasto.KnownTypes.Prog
|
||||
|
||||
*)
|
||||
|
||||
open AbSyn
|
||||
|
||||
(* An exception for reporting type errors. *)
|
||||
exception MyError of string * Position
|
||||
|
||||
type FunTable = SymTab.SymTab<(Type * Type list * Position)>
|
||||
type VarTable = SymTab.SymTab<Type>
|
||||
|
||||
|
||||
(* Table of predefined conversion functions *)
|
||||
let initFunctionTable : FunTable =
|
||||
SymTab.fromList
|
||||
[( "chr", (Char, [Int], (0,0)));
|
||||
( "ord", (Int, [Char], (0,0)))
|
||||
]
|
||||
|
||||
(* Pretty-printer for function types, for error messages *)
|
||||
let showFunType (args : Type list, res : Type) : string =
|
||||
match args with
|
||||
| [] -> " () -> " + ppType res
|
||||
| args -> (String.concat " * " (List.map ppType args))
|
||||
+ " -> " + ppType res
|
||||
|
||||
let reportError msg pos = raise (MyError (msg, pos))
|
||||
|
||||
let reportTypeWrong place tExp tFound pos =
|
||||
reportError ("Type mismatch in " + place + ": expected " +
|
||||
ppType tExp + ", but got " + ppType tFound) pos
|
||||
|
||||
let reportTypesDifferent place tFound1 tFound2 pos =
|
||||
reportError ("Type mismatch in " + place + ": expected " +
|
||||
"equal types, but got " + ppType tFound1 +
|
||||
" and " + ppType tFound2) pos
|
||||
|
||||
let reportTypeWrongKind place kExp tFound pos =
|
||||
reportError ("Type mismatch in " + place + ": expected a(n) " +
|
||||
kExp + " type, but got " + ppType tFound) pos
|
||||
|
||||
let reportArityWrong place nExp (args, res) pos =
|
||||
reportError ("Arity mismatch in " + place + ": expected " +
|
||||
"a function of arity " + string nExp + ", but got " +
|
||||
showFunType (args, res)) pos
|
||||
|
||||
let reportUnknownId kind name pos =
|
||||
reportError ("Unkown " + kind + " identifier: " + name) pos
|
||||
|
||||
let reportOther msg pos = reportError msg pos
|
||||
|
||||
(* Determine if a value of some type can be printed with write() *)
|
||||
let printable (tp : Type) : bool =
|
||||
match tp with
|
||||
| Int -> true
|
||||
| Bool -> true
|
||||
| Char -> true
|
||||
| Array Char -> true
|
||||
| _ -> false (* For all other array types *)
|
||||
|
||||
(* Type-check the two operands to a binary operator - they must both be
|
||||
of type 't'. Returns the decorated operands on success. *)
|
||||
let rec checkBinOp (ftab : FunTable)
|
||||
(vtab : VarTable)
|
||||
(pos : Position, t : Type, e1 : UntypedExp, e2 : UntypedExp)
|
||||
: (TypedExp * TypedExp) =
|
||||
let (t1, e1') = checkExp ftab vtab e1
|
||||
let (t2, e2') = checkExp ftab vtab e2
|
||||
if t1 <> t then
|
||||
reportTypeWrong "1st argument of binary operator" t t1 pos
|
||||
if t2 <> t then
|
||||
reportTypeWrong "2nd argument of binary operator" t t2 pos
|
||||
(e1', e2')
|
||||
|
||||
(* Determine the type of an expression. On the way, decorate each
|
||||
node in the syntax tree with inferred types. The result consists
|
||||
of a pair: the result type tupled with the type-decorated
|
||||
expression. An exception is raised immediately on the first type mismatch
|
||||
by reportError. (We could instead collect each error as part of the
|
||||
result of checkExp and report all errors at the end.) *)
|
||||
|
||||
and checkExp (ftab : FunTable)
|
||||
(vtab : VarTable)
|
||||
(exp : UntypedExp)
|
||||
: (Type * TypedExp) =
|
||||
match exp with
|
||||
| Constant (v, pos) -> (valueType v, Constant (v, pos))
|
||||
| StringLit (s, pos) -> (Array Char, StringLit (s, pos))
|
||||
| ArrayLit ([], _, pos) -> reportOther "Impossible empty array" pos
|
||||
| ArrayLit (exp::exps, _, pos) ->
|
||||
let (type_exp, exp_dec) = checkExp ftab vtab exp
|
||||
let exps_dec =
|
||||
List.map (fun ei -> let (ti, ei') = checkExp ftab vtab ei
|
||||
if ti <> type_exp then
|
||||
reportTypesDifferent "components of array literal"
|
||||
type_exp ti pos
|
||||
ei')
|
||||
exps
|
||||
(Array type_exp, ArrayLit (exp_dec :: exps_dec, type_exp, pos))
|
||||
|
||||
| Var (s, pos) ->
|
||||
match SymTab.lookup s vtab with
|
||||
| None -> reportUnknownId "variable" s pos
|
||||
| Some t -> (t, Var (s, pos))
|
||||
|
||||
| Plus (e1, e2, pos) ->
|
||||
let (e1_dec, e2_dec) = checkBinOp ftab vtab (pos, Int, e1, e2)
|
||||
(Int, Plus (e1_dec, e2_dec, pos))
|
||||
|
||||
| Minus (e1, e2, pos) ->
|
||||
let (e1_dec, e2_dec) = checkBinOp ftab vtab (pos, Int, e1, e2)
|
||||
(Int, Minus (e1_dec, e2_dec, pos))
|
||||
|
||||
(* TODO project task 1:
|
||||
Implement by pattern matching Plus/Minus above.
|
||||
See `AbSyn.fs` for the expression constructors of `Times`, ...
|
||||
*)
|
||||
| Times (e1, e2, pos) ->
|
||||
failwith "Unimplemented type check of multiplication"
|
||||
|
||||
| Divide (_, _, _) ->
|
||||
failwith "Unimplemented type check of division"
|
||||
|
||||
| And (_, _, _) ->
|
||||
failwith "Unimplemented type check of &&"
|
||||
|
||||
| Or (_, _, _) ->
|
||||
failwith "Unimplemented type check of ||"
|
||||
|
||||
| Not (_, _) ->
|
||||
failwith "Unimplemented type check of not"
|
||||
|
||||
| Negate (_, _) ->
|
||||
failwith "Unimplemented type check of negate"
|
||||
|
||||
(* The types for e1, e2 must be the same. The result is always a Bool. *)
|
||||
| Equal (e1, e2, pos) ->
|
||||
let (t1, e1') = checkExp ftab vtab e1
|
||||
let (t2, e2') = checkExp ftab vtab e2
|
||||
match (t1 = t2, t1) with
|
||||
| (false, _) -> reportTypesDifferent "arguments of == " t1 t2 pos
|
||||
| (true, Array _) -> reportTypeWrongKind "arguments of == " "base" t1 pos
|
||||
| _ -> (Bool, Equal (e1', e2', pos))
|
||||
|
||||
| Less (e1, e2, pos) ->
|
||||
let (t1, e1') = checkExp ftab vtab e1
|
||||
let (t2, e2') = checkExp ftab vtab e2
|
||||
match (t1 = t2, t1) with
|
||||
| (false, _) -> reportTypesDifferent "arguments of < " t1 t2 pos
|
||||
| (true, Array _) -> reportTypeWrongKind "arguments of < " "base" t1 pos
|
||||
| _ -> (Bool, Less (e1', e2', pos))
|
||||
|
||||
| If (pred, e1, e2, pos) ->
|
||||
let (pred_t, pred') = checkExp ftab vtab pred
|
||||
let (t1, e1') = checkExp ftab vtab e1
|
||||
let (t2, e2') = checkExp ftab vtab e2
|
||||
let target_type = if t1 = t2 then t1
|
||||
else reportTypesDifferent "branches of conditional"
|
||||
t1 t2 pos
|
||||
match pred_t with
|
||||
| Bool -> (target_type, If (pred', e1', e2', pos))
|
||||
| _ -> reportTypeWrong "predicate in conditional" Bool pred_t pos
|
||||
|
||||
(* special case for length *)
|
||||
| Apply ("length", [arg], pos) ->
|
||||
let (targ, arg') = checkExp ftab vtab arg
|
||||
match targ with
|
||||
| Array _ -> (Int, Apply("length", [arg'], pos))
|
||||
| _ -> reportTypeWrongKind "argument of length" "array" targ pos
|
||||
| Apply ("length", args, pos) ->
|
||||
reportOther ("Arity mismatch: length expects 1 argument, but got "
|
||||
+ string (List.length args)) pos
|
||||
|
||||
(* Look up f in function table, get a list of expected types for each
|
||||
function argument and an expected type for the return value. Check
|
||||
each actual argument. Ensure that each actual argument type has the
|
||||
expected type. *)
|
||||
| Apply (f, args, pos) ->
|
||||
let (result_type, expected_arg_types, _) =
|
||||
match SymTab.lookup f ftab with
|
||||
| Some tup -> tup (* 2-tuple *)
|
||||
| None -> reportUnknownId "function" f pos
|
||||
let nargs = List.length args
|
||||
let ntypes = List.length expected_arg_types
|
||||
if nargs <> ntypes then
|
||||
reportOther ("Arity mismatch: expected " + string ntypes +
|
||||
" argument(s), but got " + string nargs) pos
|
||||
let args_dec =
|
||||
List.mapi2 (fun i ti ai ->
|
||||
let (ti', ai') = checkExp ftab vtab ai
|
||||
if ti' <> ti then
|
||||
reportTypeWrong ("function argument #"+string (i+1))
|
||||
ti ti' pos
|
||||
ai')
|
||||
expected_arg_types args
|
||||
(result_type, Apply (f, args_dec, pos))
|
||||
|
||||
| Let (Dec (name, exp, pos1), exp_body, pos2) ->
|
||||
let (t1, exp_dec) = checkExp ftab vtab exp
|
||||
let new_vtab = SymTab.bind name t1 vtab
|
||||
let (t2, exp_body_dec) = checkExp ftab new_vtab exp_body
|
||||
(t2, Let (Dec (name, exp_dec, pos1), exp_body_dec, pos2))
|
||||
|
||||
| Read (t, pos) ->
|
||||
match t with
|
||||
| Array _ -> reportTypeWrongKind "argument of read" "base" t pos
|
||||
| _ -> (t, Read (t, pos))
|
||||
|
||||
| Write (e, _, pos) ->
|
||||
let (t, e') = checkExp ftab vtab e
|
||||
if printable t
|
||||
then (t, Write (e', t, pos))
|
||||
else reportTypeWrongKind "argument of write" "printable" t pos
|
||||
|
||||
| Index (s, i_exp, t, pos) ->
|
||||
let (e_type, i_exp_dec) = checkExp ftab vtab i_exp
|
||||
let arr_type =
|
||||
match SymTab.lookup s vtab with
|
||||
| Some (Array t) -> t
|
||||
| None -> reportUnknownId "indexed-variable" s pos
|
||||
| Some other -> reportTypeWrongKind ("indexed variable " + s) "array" other pos
|
||||
(arr_type, Index (s, i_exp_dec, arr_type, pos))
|
||||
|
||||
| Iota (n_exp, pos) ->
|
||||
let (e_type, n_exp_dec) = checkExp ftab vtab n_exp
|
||||
if e_type <> Int then
|
||||
reportTypeWrong "argument of iota" Int e_type pos
|
||||
(Array Int, Iota (n_exp_dec, pos))
|
||||
|
||||
| Map (f, arr_exp, _, _, pos) ->
|
||||
let (arr_type, arr_exp_dec) = checkExp ftab vtab arr_exp
|
||||
let elem_type =
|
||||
match arr_type with
|
||||
| Array t -> t
|
||||
| _ -> reportTypeWrongKind "second argument of map" "array" arr_type pos
|
||||
let (f', f_res_type, f_arg_type) =
|
||||
match checkFunArg ftab vtab pos f with
|
||||
| (f', res, [a1]) -> (f', res, a1)
|
||||
| (_, res, args) ->
|
||||
reportArityWrong "first argument of map" 1 (args,res) pos
|
||||
if elem_type <> f_arg_type then
|
||||
reportTypesDifferent "function-argument and array-element types in map"
|
||||
f_arg_type elem_type pos
|
||||
(Array f_res_type, Map (f', arr_exp_dec, elem_type, f_res_type, pos))
|
||||
|
||||
| Reduce (f, e_exp, arr_exp, _, pos) ->
|
||||
let (e_type , e_dec ) = checkExp ftab vtab e_exp
|
||||
let (arr_type, arr_dec) = checkExp ftab vtab arr_exp
|
||||
let elem_type =
|
||||
match arr_type with
|
||||
| Array t -> t
|
||||
| _ -> reportTypeWrongKind "third argument of reduce" "array" arr_type pos
|
||||
let (f', f_argres_type) =
|
||||
match checkFunArg ftab vtab pos f with
|
||||
| (f', res, [a1; a2]) ->
|
||||
if a1 <> a2 then
|
||||
reportTypesDifferent "argument types of operation in reduce"
|
||||
a1 a2 pos
|
||||
if res <> a1 then
|
||||
reportTypesDifferent "argument and return type of operation in reduce"
|
||||
a1 res pos
|
||||
(f', res)
|
||||
| (_, res, args) ->
|
||||
reportArityWrong "operation in reduce" 2 (args,res) pos
|
||||
if elem_type <> f_argres_type then
|
||||
reportTypesDifferent "operation and array-element types in reduce"
|
||||
f_argres_type elem_type pos
|
||||
if e_type <> f_argres_type then
|
||||
reportTypesDifferent "operation and start-element types in scan"
|
||||
f_argres_type e_type pos
|
||||
(f_argres_type, Reduce (f', e_dec, arr_dec, elem_type, pos))
|
||||
|
||||
(* TODO project task 2:
|
||||
See `AbSyn.fs` for the expression constructors of
|
||||
`Replicate`, `Filter`, `Scan`.
|
||||
|
||||
Hints for `replicate(n, a)`:
|
||||
- recursively type check `n` and `a`
|
||||
- check that `n` has integer type
|
||||
- assuming `a` is of type `t` the result type
|
||||
of replicate is `[t]`
|
||||
*)
|
||||
| Replicate (_, _, _, _) ->
|
||||
failwith "Unimplemented type check of replicate"
|
||||
|
||||
(* TODO project task 2: Hint for `filter(f, arr)`
|
||||
Look into the type-checking lecture slides for the type rule of `map`
|
||||
and think of what needs to be changed for filter (?)
|
||||
Use `checkFunArg` to get the signature of the function argument `f`.
|
||||
Check that:
|
||||
- `f` has type `ta -> Bool`
|
||||
- `arr` should be of type `[ta]`
|
||||
- the result of filter should have type `[tb]`
|
||||
*)
|
||||
| Filter (_, _, _, _) ->
|
||||
failwith "Unimplemented type check of filter"
|
||||
|
||||
(* TODO project task 2: `scan(f, ne, arr)`
|
||||
Hint: Implementation is very similar to `reduce(f, ne, arr)`.
|
||||
(The difference between `scan` and `reduce` is that
|
||||
scan's return type is the same as the type of `arr`,
|
||||
while reduce's return type is that of an element of `arr`).
|
||||
*)
|
||||
| Scan (_, _, _, _, _) ->
|
||||
failwith "Unimplemented type check of scan"
|
||||
|
||||
and checkFunArg (ftab : FunTable)
|
||||
(vtab : VarTable)
|
||||
(pos : Position)
|
||||
(ff : UntypedFunArg)
|
||||
: (TypedFunArg * Type * Type list) =
|
||||
match ff with
|
||||
| FunName fname ->
|
||||
match SymTab.lookup fname ftab with
|
||||
| None -> reportUnknownId "parameter function" fname pos
|
||||
| Some (ret_type, arg_types, _) -> (FunName fname, ret_type, arg_types)
|
||||
| Lambda (rettype, parms, body, funpos) ->
|
||||
let lambda = FunDec ("<lambda>", rettype, parms, body, funpos)
|
||||
let (FunDec (_, _, _, body', _)) =
|
||||
checkFunWithVtable ftab vtab pos lambda
|
||||
( Lambda (rettype, parms, body', pos)
|
||||
, rettype
|
||||
, List.map (fun (Param (_, ty)) -> ty) parms)
|
||||
|
||||
|
||||
(* Check a function declaration, but using a given vtable rather
|
||||
than an empty one. *)
|
||||
and checkFunWithVtable (ftab : FunTable)
|
||||
(vtab : VarTable)
|
||||
(pos : Position)
|
||||
(fdec : UntypedFunDec)
|
||||
: TypedFunDec =
|
||||
let (FunDec (fname, rettype, parms, body, funpos)) = fdec
|
||||
(* Expand vtable by adding the parameters to vtab. *)
|
||||
let addParam ptable (Param (pname, ty)) =
|
||||
match SymTab.lookup pname ptable with
|
||||
| Some _ -> reportOther ("Multiple parameters named " + pname)
|
||||
funpos
|
||||
| None -> SymTab.bind pname ty ptable
|
||||
let paramtable = List.fold addParam (SymTab.empty()) parms
|
||||
let vtab' = SymTab.combine paramtable vtab
|
||||
let (body_type, body') = checkExp ftab vtab' body
|
||||
if body_type = rettype
|
||||
then (FunDec (fname, rettype, parms, body', pos))
|
||||
else reportTypeWrong "function body" rettype body_type funpos
|
||||
|
||||
|
||||
(* Convert a funDec into the (fname, ([arg types], result type),
|
||||
pos) entries that the function table, ftab, consists of, and
|
||||
update the function table with that entry. *)
|
||||
let updateFunctionTable (ftab : FunTable)
|
||||
(fundec : UntypedFunDec)
|
||||
: FunTable =
|
||||
let (FunDec (fname, ret_type, args, _, pos)) = fundec
|
||||
let arg_types = List.map (fun (Param (_, ty)) -> ty) args
|
||||
match SymTab.lookup fname ftab with
|
||||
| Some (_, _, old_pos) -> reportOther ("Duplicate function " + fname) pos
|
||||
| None -> SymTab.bind fname (ret_type, arg_types, pos) ftab
|
||||
|
||||
(* Functions are guaranteed by syntax to have a known declared type. This
|
||||
type is checked against the type of the function body, taking into
|
||||
account declared argument types and types of other functions called.
|
||||
*)
|
||||
let checkFun (ftab : FunTable)
|
||||
(fundec : UntypedFunDec)
|
||||
: TypedFunDec =
|
||||
let (FunDec (_, _, _, _, pos)) = fundec
|
||||
checkFunWithVtable ftab (SymTab.empty()) pos fundec
|
||||
|
||||
let checkProg (funDecs : UntypedFunDec list) : TypedFunDec list =
|
||||
let ftab = List.fold updateFunctionTable initFunctionTable funDecs
|
||||
let decorated_funDecs = List.map (checkFun ftab) funDecs
|
||||
match SymTab.lookup "main" ftab with
|
||||
| None -> reportOther "No main function defined" (0,0)
|
||||
| Some (_, [], _) -> decorated_funDecs (* all fine! *)
|
||||
| Some (ret_type, args, mainpos) ->
|
||||
reportArityWrong "declaration of main" 0 (args,ret_type) mainpos
|
||||
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
@@ -0,0 +1,114 @@
|
||||
{
|
||||
"runtimeTarget": {
|
||||
"name": ".NETCoreApp,Version=v6.0",
|
||||
"signature": ""
|
||||
},
|
||||
"compilationOptions": {},
|
||||
"targets": {
|
||||
".NETCoreApp,Version=v6.0": {
|
||||
"Fasto/1.0.0": {
|
||||
"dependencies": {
|
||||
"FSharp.Core": "6.0.1",
|
||||
"FsLexYacc": "10.2.0"
|
||||
},
|
||||
"runtime": {
|
||||
"Fasto.dll": {}
|
||||
}
|
||||
},
|
||||
"FSharp.Core/6.0.1": {
|
||||
"runtime": {
|
||||
"lib/netstandard2.1/FSharp.Core.dll": {
|
||||
"assemblyVersion": "6.0.0.0",
|
||||
"fileVersion": "6.0.121.52202"
|
||||
}
|
||||
},
|
||||
"resources": {
|
||||
"lib/netstandard2.1/cs/FSharp.Core.resources.dll": {
|
||||
"locale": "cs"
|
||||
},
|
||||
"lib/netstandard2.1/de/FSharp.Core.resources.dll": {
|
||||
"locale": "de"
|
||||
},
|
||||
"lib/netstandard2.1/es/FSharp.Core.resources.dll": {
|
||||
"locale": "es"
|
||||
},
|
||||
"lib/netstandard2.1/fr/FSharp.Core.resources.dll": {
|
||||
"locale": "fr"
|
||||
},
|
||||
"lib/netstandard2.1/it/FSharp.Core.resources.dll": {
|
||||
"locale": "it"
|
||||
},
|
||||
"lib/netstandard2.1/ja/FSharp.Core.resources.dll": {
|
||||
"locale": "ja"
|
||||
},
|
||||
"lib/netstandard2.1/ko/FSharp.Core.resources.dll": {
|
||||
"locale": "ko"
|
||||
},
|
||||
"lib/netstandard2.1/pl/FSharp.Core.resources.dll": {
|
||||
"locale": "pl"
|
||||
},
|
||||
"lib/netstandard2.1/pt-BR/FSharp.Core.resources.dll": {
|
||||
"locale": "pt-BR"
|
||||
},
|
||||
"lib/netstandard2.1/ru/FSharp.Core.resources.dll": {
|
||||
"locale": "ru"
|
||||
},
|
||||
"lib/netstandard2.1/tr/FSharp.Core.resources.dll": {
|
||||
"locale": "tr"
|
||||
},
|
||||
"lib/netstandard2.1/zh-Hans/FSharp.Core.resources.dll": {
|
||||
"locale": "zh-Hans"
|
||||
},
|
||||
"lib/netstandard2.1/zh-Hant/FSharp.Core.resources.dll": {
|
||||
"locale": "zh-Hant"
|
||||
}
|
||||
}
|
||||
},
|
||||
"FsLexYacc/10.2.0": {
|
||||
"dependencies": {
|
||||
"FSharp.Core": "6.0.1",
|
||||
"FsLexYacc.Runtime": "10.2.0"
|
||||
}
|
||||
},
|
||||
"FsLexYacc.Runtime/10.2.0": {
|
||||
"dependencies": {
|
||||
"FSharp.Core": "6.0.1"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/netstandard2.0/FsLexYacc.Runtime.dll": {
|
||||
"assemblyVersion": "1.0.0.0",
|
||||
"fileVersion": "10.2.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"libraries": {
|
||||
"Fasto/1.0.0": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"FSharp.Core/6.0.1": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-VrFAiW8dEEekk+0aqlbvMNZzDvYXmgWZwAt68AUBqaWK8RnoEVUNglj66bZzhs4/U63q0EfXlhcEKnH1sTYLjw==",
|
||||
"path": "fsharp.core/6.0.1",
|
||||
"hashPath": "fsharp.core.6.0.1.nupkg.sha512"
|
||||
},
|
||||
"FsLexYacc/10.2.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-q7mhuEMm8rvFAJ9jaH1atYCRN96tMbjHarYIDooeMKFCbUuqvep+vA2ijGhA06GZ5BG+jg4TjG6dt/4gR2qHHA==",
|
||||
"path": "fslexyacc/10.2.0",
|
||||
"hashPath": "fslexyacc.10.2.0.nupkg.sha512"
|
||||
},
|
||||
"FsLexYacc.Runtime/10.2.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-d2+gguRIvsn1e7AycVc0r7L1QWptrnUOvQvJLbgkANcS5SjfM/FRgfUGwfqV2cJo3KOFQB5Mqmda/4YTQkkvdA==",
|
||||
"path": "fslexyacc.runtime/10.2.0",
|
||||
"hashPath": "fslexyacc.runtime.10.2.0.nupkg.sha512"
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"runtimeOptions": {
|
||||
"tfm": "net6.0",
|
||||
"framework": {
|
||||
"name": "Microsoft.NETCore.App",
|
||||
"version": "6.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,3 @@
|
||||
namespace Microsoft.BuildSettings
|
||||
[<System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v6.0", FrameworkDisplayName="")>]
|
||||
do ()
|
||||
@@ -0,0 +1,17 @@
|
||||
// <auto-generated>
|
||||
// Generated by the FSharp WriteCodeFragment class.
|
||||
// </auto-generated>
|
||||
namespace FSharp
|
||||
|
||||
open System
|
||||
open System.Reflection
|
||||
|
||||
|
||||
[<assembly: System.Reflection.AssemblyCompanyAttribute("Fasto")>]
|
||||
[<assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")>]
|
||||
[<assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")>]
|
||||
[<assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")>]
|
||||
[<assembly: System.Reflection.AssemblyProductAttribute("Fasto")>]
|
||||
[<assembly: System.Reflection.AssemblyTitleAttribute("Fasto")>]
|
||||
[<assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")>]
|
||||
do()
|
||||
@@ -0,0 +1 @@
|
||||
87b9cc0b5fae546ac1375c9e8703b89da9781f13
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
5352b7ee7a7d6d80e8fae3a019b63e6f4899b1e3
|
||||
@@ -0,0 +1,27 @@
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W1/fasto/Fasto/bin/Debug/net6.0/Fasto
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W1/fasto/Fasto/bin/Debug/net6.0/Fasto.deps.json
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W1/fasto/Fasto/bin/Debug/net6.0/Fasto.runtimeconfig.json
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W1/fasto/Fasto/bin/Debug/net6.0/Fasto.dll
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W1/fasto/Fasto/bin/Debug/net6.0/Fasto.pdb
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W1/fasto/Fasto/bin/Debug/net6.0/FSharp.Core.dll
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W1/fasto/Fasto/bin/Debug/net6.0/FsLexYacc.Runtime.dll
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W1/fasto/Fasto/bin/Debug/net6.0/cs/FSharp.Core.resources.dll
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W1/fasto/Fasto/bin/Debug/net6.0/de/FSharp.Core.resources.dll
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W1/fasto/Fasto/bin/Debug/net6.0/es/FSharp.Core.resources.dll
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W1/fasto/Fasto/bin/Debug/net6.0/fr/FSharp.Core.resources.dll
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W1/fasto/Fasto/bin/Debug/net6.0/it/FSharp.Core.resources.dll
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W1/fasto/Fasto/bin/Debug/net6.0/ja/FSharp.Core.resources.dll
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W1/fasto/Fasto/bin/Debug/net6.0/ko/FSharp.Core.resources.dll
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W1/fasto/Fasto/bin/Debug/net6.0/pl/FSharp.Core.resources.dll
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W1/fasto/Fasto/bin/Debug/net6.0/pt-BR/FSharp.Core.resources.dll
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W1/fasto/Fasto/bin/Debug/net6.0/ru/FSharp.Core.resources.dll
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W1/fasto/Fasto/bin/Debug/net6.0/tr/FSharp.Core.resources.dll
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W1/fasto/Fasto/bin/Debug/net6.0/zh-Hans/FSharp.Core.resources.dll
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W1/fasto/Fasto/bin/Debug/net6.0/zh-Hant/FSharp.Core.resources.dll
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W1/fasto/Fasto/obj/Debug/net6.0/Fasto.fsproj.AssemblyReference.cache
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W1/fasto/Fasto/obj/Debug/net6.0/Fasto.AssemblyInfoInputs.cache
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W1/fasto/Fasto/obj/Debug/net6.0/Fasto.AssemblyInfo.fs
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W1/fasto/Fasto/obj/Debug/net6.0/Fasto.fsproj.CopyComplete
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W1/fasto/Fasto/obj/Debug/net6.0/Fasto.dll
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W1/fasto/Fasto/obj/Debug/net6.0/Fasto.pdb
|
||||
/home/nikolaj/Code/Datalogi/2022B4-IPS/IPS_W-assignments/W1/fasto/Fasto/obj/Debug/net6.0/Fasto.genruntimeconfig.cache
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user