parsing lambdas
authorpimjager <pim@pimjager.nl>
Thu, 26 May 2016 13:00:59 +0000 (15:00 +0200)
committerpimjager <pim@pimjager.nl>
Thu, 26 May 2016 13:00:59 +0000 (15:00 +0200)
AST.dcl
AST.icl
examples/tempTest.spl
gen.icl
grammar/grammar.txt
lex.dcl
lex.icl
parse.icl
sem.icl

diff --git a/AST.dcl b/AST.dcl
index 4a5a6cb..e9afa4f 100644 (file)
--- a/AST.dcl
+++ b/AST.dcl
@@ -27,6 +27,7 @@ from StdOverloaded import class toString, class ==, class zero, class <
        | FunExpr Pos String [Expr] [FieldSelector]
        | EmptyListExpr Pos 
        | TupleExpr Pos (Expr, Expr)
+    | LambdaExpr Pos [String] Expr
 :: VarDef = VarDef String [FieldSelector]
 :: FieldSelector = FieldHd | FieldTl | FieldFst | FieldSnd
 :: Op1 = UnNegation | UnMinus
diff --git a/AST.icl b/AST.icl
index 6436619..774e158 100644 (file)
--- a/AST.icl
+++ b/AST.icl
@@ -110,6 +110,7 @@ instance print Expr where
        print (FunExpr _ id as fs) = printFunCall id as fs
        print (EmptyListExpr _) = ["[]"]
        print (TupleExpr _ (e1, e2)) = ["(":print e1] ++ [",":print e2] ++ [")"]
+    print (LambdaExpr _ args e) = ["\\":args] ++ ["->": print e]
 instance toString Expr where
     toString e = concat $ print e
 
index 23421f0..21545ae 100644 (file)
@@ -11,6 +11,7 @@ main() {
     [Int] x = [];
     [Int] y = [];
     Int z = a();
+    var f = \x -> x+1;
     x = mapP1(x);
     y = mapP1(x);
     return a() + 5;
diff --git a/gen.icl b/gen.icl
index e92954c..f96840b 100644 (file)
--- a/gen.icl
+++ b/gen.icl
@@ -176,6 +176,7 @@ instance g Expr where
                        [Instr "ldc" [Lit fn] ""
                        ,Instr "ldc" [Lit 0] ""
                        ,Instr "stmh" [Lit 2] ""]
+    g (LambdaExpr _ _ _) = liftT $ Left $ Error "PANIC: Lambdas should be transformed"
     g (FunExpr _ k es fs) = getAdressbook >>= \ab->case 'Map'.get k ab of
                //Identifier points to function
                Just (LAB l arity fn) = if (arity <> (length es))
index e63a3f6..b399311 100644 (file)
@@ -11,6 +11,7 @@
                  | 'return' [<Expr>] ';'
 <VarDecl>      ::= <Type> <id> '=' <Expr> ';'
 <Expr>         ::= <BinOrExpr> [':' <Expr>]
+                 | <LambdaExpr>
 <BinOrExpr>    ::= <BinAndExpr> ['||' <BinOrExpr>]
 <BinAndExpr>   ::= <CompareExpr> ['&&' <BinAndExpr>]
 <CompareExpr>  ::= <PlusMinExpr> [('==' | '<' | '>' | '<=' | '>=' | '!=') <CompareExpr>]
@@ -26,6 +27,7 @@
                  | '[]' <Expr>
                  | '(' <Expr> ',' <Expr> ')'
                  | '"' <char> '"'
+<LamdaExpr>    ::= '\'<id>+ '->' <Expr>
 <FieldSels>    ::= ('.' ('hd'|'tl'|'fst'|'snd))*
 <FunCall>      ::= <id> ['(' <ActArgs>+ ')']
 <ActArgs>      ::= <Expr> [',' ActArgs]
diff --git a/lex.dcl b/lex.dcl
index dd7d28e..f524047 100644 (file)
--- a/lex.dcl
+++ b/lex.dcl
@@ -54,6 +54,7 @@ from AST import :: Pos
        | LesserToken       // <
        | BiggerToken       // >
        | ExclamationToken  // !
+    | BackslashToken    // \
 
 :: LexerOutput :== Either Error [Token]
 
diff --git a/lex.icl b/lex.icl
index 6072bce..6cb2e92 100644 (file)
--- a/lex.icl
+++ b/lex.icl
@@ -67,7 +67,7 @@ lexToken =
        lexWord "/" SlashToken <|> lexWord "%" PercentToken <|>
        lexWord "=" AssignmentToken <|> lexWord "<" LesserToken <|>
        lexWord ">" BiggerToken <|> lexWord "!" ExclamationToken <|>
-       lexWord "-" DashToken <|>
+       lexWord "-" DashToken <|> lexWord "\\" BackslashToken <|>
        //Number and identifier tokens
        lexString <|> lexNumber <|> lexIdentifier <|>
        (item '\n' >>| pure LexNL) <|>
index 30a13a9..a79ad2f 100644 (file)
--- a/parse.icl
+++ b/parse.icl
@@ -113,7 +113,9 @@ parseType =
        (IdType <$> parseIdent)
 
 parseExpr :: Parser Token Expr
-parseExpr = //Operators in order of binding strength
+parseExpr = parseValueExpr <|> parseLambda
+parseValueExpr :: Parser Token Expr
+parseValueExpr = //Operators in order of binding strength
        parseOpR (trans1 ColonToken BiCons) $
        parseOpR (trans1 PipesToken BiOr) $
        parseOpR (trans1 AmpersandsToken BiAnd) $
@@ -154,6 +156,11 @@ parseExpr = //Operators in order of binding strength
                                pure $ FunExpr pos ident args fs) <|>
                        (VarExpr pos <$> parseVarDef)
 
+parseLambda :: Parser Token Expr
+parseLambda = LambdaExpr <$> peekPos 
+                        <*> (satTok BackslashToken *> some parseIdent)
+                        <*> (satTok ArrowToken *> parseExpr)
+
 makeStrExpr :: Pos [Char] -> Expr
 makeStrExpr p [] = EmptyListExpr p
 makeStrExpr p [x:xs] = Op2Expr p (CharExpr zero x) BiCons (makeStrExpr p xs)
diff --git a/sem.icl b/sem.icl
index 484430d..5cf0520 100644 (file)
--- a/sem.icl
+++ b/sem.icl
@@ -225,6 +225,8 @@ instance infer Expr where
         infer e2 >>= \(s2, t2, e2_) ->
         pure (compose s2 s1, TupleType (t1,t2), TupleExpr p (e1_,e2_))
 
+    LambdaExpr _ _ _ = liftT $ Left $ Error "PANIC: lambdas should be tasnformed"
+
     FunExpr p f args fs =
         lookup f >>= \expected ->
         let accST = (\(s,ts,es) e->infer e >>= \(s_,et,e_)-> pure (compose s_ s,ts++[et],es++[e_])) in