ssm-lang / sslang

A language built atop the Sparse Synchronous Model
BSD 3-Clause "New" or "Revised" License
18 stars 0 forks source link

Add list literal syntax #119

Closed max-acebal closed 1 year ago

max-acebal commented 1 year ago

Hi @EmilySillars I am still getting this error: stack exec sslc -- tests/lists_sample.ssl > out/lists_sample.c sslc: src/IR/LowerAst.hs:(119,1)-(164,63): Non-exhaustive patterns in function lowerExpr when trying to run my sample test. As we discussed last week I have been reading through the IR to get an idea of how App, and DConId work. I think my next steps should be adding the code for the ListExpr so that it can be generated by the IR in the way we have been discussing on slack, but unsure where that code should even go since the error is in LowerAst.

EmilySillars commented 1 year ago

Hi Max, Thank you for your comment and apologies on the late reply -- Restating compiler pipeline here for context: Scanner --> Parser --> Lowering --> Type Inference --> Optimization --> Code Generation --> C code

Lowering Stage: The ouput of the parser gives us a representation of our input sslang program as a tree. Nodes in the tree represents parts of the input program. The "lowering" pass implemented in LowerAst.hs transforms every AST node into an equivalient IR node. After performing lowering, we are still representing our input sslang program as a tree in the compiler. The difference is that after lowering, there are fewer kinds of nodes in our tree, and each node is augmented with space for a type, t.

// an AST Expr Node     ----- LowerAst.hs ---->     // an IR Expr Node

data Expr                                            data Expr t              
  = Id Identifier                                      = Var VarId t
  | Lit Literal                                        | Data DConId t
  | Apply Expr Expr                                    | Lit Literal t
  | Lambda [Pat] Expr                                  | App (Expr t) (Expr t) t
  | OpRegion Expr OpRegion                             | Let [(Binder, Expr t)] (Expr t) t
  | NoExpr                                             | Lambda Binder (Expr t) t
  | Let [Definition] Expr                              | Match (Expr t) [(Alt, Expr t)] t
  | While Expr Expr                                    | Prim Primitive [Expr t] t
  | Loop Expr                                          deriving (Eq, Show, Typeable, Data, Functor, Foldable, Traversable)
  | Par [Expr]
  | IfElse Expr Expr Expr
  | After Expr Expr Expr
  | Assign Expr Expr
  | Constraint Expr TypAnn
  | Wait [Expr]
  | Seq Expr Expr
  | Break
  | Match Expr [(Pat, Expr)]
  | CQuote String
  | CCall Identifier [Expr]
  | ListExpr [Expr]
  deriving (Eq, Show)

The function lowerExpr inside lowerAst.hs has the type signature lowerExpr :: A.Expr -> Compiler.Pass (I.Expr I.Annotations) which means it transforms something of type A.Expr to into a monadic I.Expr. Compiler.Pass is the monad that wraps most all our compiler computations on/transformations of our representation of a sslang prorgam.

Current Compiler Error: You are getting a non-exhaustive pattern match warning because the function lowerExpr does not have a case for matching on an A.Expr of instance ListExpr.

You need to add a case to LowerExpr that transforms a ListExpr instance of A.Expr into an App instance of I.Expr.

ListExpr [Expr] ---- needs to turn into ----> App (Expr t) (Expr t) t

How to do this???

Here is an exercise to get you started thinking about this. Write down your answers and comment them on this draft PR before our next meeting. Also comment any questions you have (or slack message me, whichever you prefer) if you get stuck!

Exercise:

  type List
    Cons Int 
    Nil

  main cin cout = 
   let y = (Cons 1 (Cons 2 (Cons 3 Nil)))
   let x = [1, 2, 3]
   ()

1) What does y look like as an AST node? 2) What does x look like as an AST node?

3) What should y look like as an IR node? 4) What should x look like as an IR node?

I'm writing up a worked example + solution for a similar exercise, and will post that here as soon as I'm finished with it.

EmilySillars commented 1 year ago

Here is an example of a similar exercise with solutions: https://github.com/ssm-lang/sslang/blob/9604ebd88607152fd36c154dcd532b9f43f2bcd9/doc/lang-design/lowering-example.md

EmilySillars commented 1 year ago

Hi @j-hui ,

EmilySillars commented 1 year ago

I believe Max's lists_sample2 test case is failing because of a bug on main #125

EmilySillars commented 1 year ago

Hi Max, Great work so far! We're in the home stretch! 1) merge main into your branch 2) once your branch is up to date with main, replace this line in front.hs with let astTuple = insertTypeDef pairDef astL to make sure the string and list desugaring gets threaded through. 3) replace lines 19 and 20 desugarLists.hs with

    desugarDef (DefFn v bs t e) = DefFn v bs t $ everywhere (mkT desugarExpr) e
    desugarDef (DefPat b e    ) = DefPat b $ everywhere (mkT desugarExpr) e

You will likely need to import Data.Generics for this to work. This change allows you to bypass matching on all the different instance of an Expr when you only care about the ListExpr instance - it uses generics from a haskell library called SYBP.

4) At this point your lists_sample.ssl test should pass, but doesn't output anything meaningful. Change this test case to print out the contents of your list so that it's outputting something meaningful (instead of nothing). Change the corresponding lists_sample.out file to match your new output. Don't worry about the unescaped string error from lists_sample2.ssl. Delete that test or change it so it doesn't use character literals. 5) resolve all your build warnings/ redundant pattern matches etc.

After you complete these steps I will take a final pass over your code for style/ other nits.