diff --git a/ast.hs b/ast.hs index 0175454..64aa245 100644 --- a/ast.hs +++ b/ast.hs @@ -16,6 +16,7 @@ data AST = Add AST AST | Lambda [(Pattern, [AST])] | Call String [AST] | UnitConst + | Cons AST AST | ListConst [AST] | StrConst String | IntConst Integer diff --git a/interp.hs b/interp.hs index a90c98b..4635d32 100644 --- a/interp.hs +++ b/interp.hs @@ -90,6 +90,13 @@ eval UnitConst = return UnitV eval (Block body) = foldr1 (>>) $ map eval body +eval (Cons a b) = do + a' <- eval a + b' <- eval b + case b' of + ListV v' -> return $ ListV $ a':v' + _ -> error "cons: RHS must be a list" + eval (ListConst v) = mapM eval v >>= \xs -> return $ ListV xs diff --git a/parser.hs b/parser.hs index 2c44ac0..f660a28 100644 --- a/parser.hs +++ b/parser.hs @@ -110,7 +110,13 @@ call = do symbol ")" return $ Call name args' -term = try block +consExpr = do + x <- expr' + symbol "::" + y <- exprparser + return $ Cons x y + +expr' = try block <|> try funDef <|> try call <|> parens exprparser @@ -119,6 +125,9 @@ term = try block <|> fmap StrConst stringLiteral <|> fmap IntConst integer +term = try consExpr + <|> expr' + seqStmt = sepBy1 statement semi program =