Merge branch 'master' of uhsure.com:webapps/git/bang

This commit is contained in:
2011-01-30 22:16:08 -08:00
6 changed files with 233 additions and 160 deletions

View File

@@ -25,7 +25,7 @@ export length(ls :: [a]) :: Int
{ {
case ls of case ls of
[] -> 0 [] -> 0
_:rest -> length rest _:rest -> length(rest)
}; };
export reverse(ls :: [a]) :: [a] export reverse(ls :: [a]) :: [a]
@@ -33,10 +33,10 @@ export reverse(ls :: [a]) :: [a]
helper(xs,acc) = { helper(xs,acc) = {
case xs of case xs of
[] -> acc [] -> acc
(a:rest) -> helper rest (a:acc) (a:rest) -> helper(rest, (a:acc))
} }
helper ls []; helper(ls, []);
}; };
export restrict(Eq a) find(f :: a -> Bool, ls :: [a]) :: Maybe a export restrict(Eq a) find(f :: a -> Bool, ls :: [a]) :: Maybe a

View File

@@ -1,5 +1,7 @@
module Syntax.AST where module Syntax.AST where
import Syntax.ParserCore
data Show a => Module a = Module { data Show a => Module a = Module {
modName :: QualifiedName modName :: QualifiedName
, modImports :: [Import] , modImports :: [Import]
@@ -13,6 +15,11 @@ data QualifiedName = QualifiedName {
} }
deriving (Show) deriving (Show)
gensym :: Parser QualifiedName
gensym = do
name <- genstr
return (QualifiedName [] name)
data Import = Import { data Import = Import {
imName :: QualifiedName imName :: QualifiedName
, imQualified :: Bool , imQualified :: Bool
@@ -31,7 +38,7 @@ data Show a => Decl a =
| DeclNewtype a [Type] | DeclNewtype a [Type]
| DeclClass a [Type] | DeclClass a [Type]
| DeclInstance a [Type] | DeclInstance a [Type]
| DeclValue a [Type] Type QualifiedName [Stmt a] | DeclValue a [Type] Type (Expr a)
| DeclExport a (Decl a) | DeclExport a (Decl a)
deriving (Show) deriving (Show)
@@ -41,7 +48,7 @@ addTypeRestrictions rs (DeclType s _) = DeclType s rs
addTypeRestrictions rs (DeclNewtype s _) = DeclNewtype s rs addTypeRestrictions rs (DeclNewtype s _) = DeclNewtype s rs
addTypeRestrictions rs (DeclClass s _) = DeclClass s rs addTypeRestrictions rs (DeclClass s _) = DeclClass s rs
addTypeRestrictions rs (DeclInstance s _) = DeclInstance s rs addTypeRestrictions rs (DeclInstance s _) = DeclInstance s rs
addTypeRestrictions rs (DeclValue s _ a b c) = DeclValue s rs a b c addTypeRestrictions rs (DeclValue s _ a b) = DeclValue s rs a b
addTypeRestrictions rs (DeclExport s d) = addTypeRestrictions rs (DeclExport s d) =
DeclExport s (addTypeRestrictions rs d) DeclExport s (addTypeRestrictions rs d)
@@ -51,16 +58,32 @@ data DataClause a = DataClause a QualifiedName [Maybe QualifiedName] [Type]
data Show a => Expr a = data Show a => Expr a =
Const a ConstVal Const a ConstVal
| VarRef a QualifiedName | VarRef a QualifiedName
| Cond a (Expr a) (Expr a) | Cond a (Expr a) (Expr a) (Expr a)
| App a (Expr a) (Expr a) | App a (Expr a) [Expr a]
| Block a [Expr a] | Block a [Stmt a]
| Lambda a [QualifiedName] (Expr a) | Lambda a [QualifiedName] (Expr a)
deriving (Show) deriving (Show)
getSpecial :: Show a => Expr a -> a
getSpecial (Const a _) = a
getSpecial (VarRef a _) = a
getSpecial (Cond a _ _ _) = a
getSpecial (App a _ _) = a
getSpecial (Block a _) = a
getSpecial (Lambda a _ _) = a
data Show a => Stmt a = data Show a => Stmt a =
SExpr a (Expr a) SExpr a (Expr a)
| SBind a QualifiedName (Stmt a) | SBind a QualifiedName (Stmt a)
| SCase a | SCase a (Expr a) [(Pattern,Maybe (Expr a),Expr a)]
deriving (Show)
data Pattern =
ListNull
| PConst ConstVal
| PVar QualifiedName
| PNamed QualifiedName Pattern
| PAp Pattern Pattern
deriving (Show) deriving (Show)
data Kind = Star | KFun Kind Kind data Kind = Star | KFun Kind Kind

View File

@@ -58,6 +58,7 @@ $escape_char = [abfnrtv'\"\\]
"|" { emitT Bar } "|" { emitT Bar }
";" { emitT Semi } ";" { emitT Semi }
"," { emitT Comma } "," { emitT Comma }
"`" { emitT BTick }
{ {

View File

@@ -34,7 +34,7 @@ import qualified Codec.Binary.UTF8.Generic as UTF8
-- symbols -- symbols
'=' { Lexeme $$ (TokOpIdent "=") } '=' { Lexeme $$ (TokOpIdent "=") }
'->' { Lexeme $$ (TokOpIdent "->") } '->' { Lexeme $$ (TokOpIdent "->") }
'=>' { Lexeme $$ (TokOpIdent "=>") } '@' { Lexeme $$ (TokOpIdent "@") }
'::' { Lexeme $$ (TokOpIdent "::") } '::' { Lexeme $$ (TokOpIdent "::") }
'\\' { Lexeme $$ (TokOpIdent "\\") } '\\' { Lexeme $$ (TokOpIdent "\\") }
'(' { Lexeme $$ LParen } '(' { Lexeme $$ LParen }
@@ -46,17 +46,18 @@ import qualified Codec.Binary.UTF8.Generic as UTF8
'|' { Lexeme $$ Bar } '|' { Lexeme $$ Bar }
';' { Lexeme $$ Semi } ';' { Lexeme $$ Semi }
',' { Lexeme $$ Comma } ',' { Lexeme $$ Comma }
'`' { Lexeme $$ BTick }
-- identifiers -- identifiers
TYPE_IDENT { Lexeme _ (TokTypeIdent $$) } TYPE_IDENT { Lexeme _ (TokTypeIdent _) }
VAL_IDENT { Lexeme _ (TokValIdent $$) } VAL_IDENT { Lexeme _ (TokValIdent _) }
OP_IDENT { Lexeme _ (TokOpIdent $$) } OP_IDENT { Lexeme _ (TokOpIdent _) }
-- values -- values
INTVAL { Lexeme _ (TokInt $$) } INTVAL { Lexeme _ (TokInt _) }
FLOATVAL { Lexeme _ (TokFloat $$) } FLOATVAL { Lexeme _ (TokFloat _) }
CHARVAL { Lexeme _ (TokChar $$) } CHARVAL { Lexeme _ (TokChar _) }
STRVAL { Lexeme _ (TokString $$) } STRVAL { Lexeme _ (TokString _) }
%monad { Parser } { (>>=) } { return } %monad { Parser } { (>>=) } { return }
%name parseModule top_module %name parseModule top_module
@@ -164,7 +165,9 @@ data_clauses :: { [DataClause Position] }
| data_clauses '|' data_clause { $1 ++ [$3] } | data_clauses '|' data_clause { $1 ++ [$3] }
data_clause :: { DataClause Position } data_clause :: { DataClause Position }
: constructor_name '(' constructor_args ')' : constructor_name '(' ')'
{ DataClause $2 $1 [] [] }
| constructor_name '(' constructor_args ')'
{ DataClause $2 $1 (map fst $3) (map snd $3) } { DataClause $2 $1 (map fst $3) (map snd $3) }
constructor_name :: { QualifiedName } constructor_name :: { QualifiedName }
@@ -202,7 +205,9 @@ instance_decl :: { Decl Position }
-- Value Declaration -------------------------------------------------------- -- Value Declaration --------------------------------------------------------
value_decl :: { Decl Position } value_decl :: { Decl Position }
: value_ident optional_args optional_type { undefined } : value_ident optional_args optional_type value_body
{% postProcessDeclVal $1 $2 $3 $4 }
optional_args :: { Maybe [(QualifiedName, Maybe Type)] } optional_args :: { Maybe [(QualifiedName, Maybe Type)] }
: '(' optional_args2 ')' { Just $2 } : '(' optional_args2 ')' { Just $2 }
@@ -223,147 +228,156 @@ value_ident :: { QualifiedName }
: VAL_IDENT { makeQualified $1 } : VAL_IDENT { makeQualified $1 }
| '(' OP_IDENT ')' { makeQualified $2 } | '(' OP_IDENT ')' { makeQualified $2 }
value_body :: { (Position, Expr Position) }
: '=' expression { ($1, $2) }
| '{' statements '}' { ($1, Block $1 $2) }
-- Types in Bang ------------------------------------------------------------ -- Types in Bang ------------------------------------------------------------
bang_type :: { Type } primary_type :: { Type }
: TYPE_IDENT { TVar (makeQualified $1) Star } : TYPE_IDENT { TVar (makeQualified $1) Star }
| VAL_IDENT { TVar (makeQualified $1) Star }
| '(' bang_type ')' { $2 }
-- type_application_type :: { Type }
-- data_decl :: { Decl Position } : type_application_type primary_type
-- : 'datatype' mqualifiers TYPE_IDENT data_args dataclauses { TAp $1 $2 }
-- { DeclData $2 (makeQualified $3) $4 $5 } | primary_type
-- { $1 }
-- mqualifiers :: { [Type] }
-- : { [] } function_type :: { Type }
-- | '(' tqualifiers ')' '=>' { $2 } : function_type '->' type_application_type
-- { TAp (TVar (QualifiedName ["--INTERNAL--"] "->") Star) $3 }
-- tqualifiers :: { [Type] } | type_application_type
-- : tqualifier { [$1] } { $1 }
-- | tqualifiers ',' tqualifier { $1 ++ [$3] }
-- list_type :: { Type }
-- tqualifier :: { Type } : '[' list_type ']'
-- : TYPE_IDENT VAL_IDENT { TAp (TVar (QualifiedName ["Data","List"] "List") Star) $2 }
-- { TAp (TCon (makeQualified $1) Star) (TVar (makeQualified $2) Star) } | function_type
-- | tqualifier VAL_IDENT { $1 }
-- { TAp $1 (TVar (makeQualified $2) Star) }
-- bang_type :: { Type }
-- data_args :: { [QualifiedName] } : list_type { $1 }
-- : { [] }
-- | data_args VAL_IDENT { $1 ++ [makeQualified $2] } -- Statements in bang
--
-- dataclauses :: { [DataClause] } statements :: { [Stmt Position] }
-- : '=' dataclause { [$2] } : { [] }
-- | dataclauses '|' dataclause { $1 ++ [$3] } | statements statement { $1 ++ [$2] }
--
-- dataclause :: { DataClause } statement :: { Stmt Position }
-- : constructor_id { DataClause $1 [] } : assignment_statement ';' { $1 }
-- | dataclause bangtype3 { let DataClause name items = $1 | case_statement ';' { $1 }
-- in DataClause name (items ++ [$2]) } | expression ';' { SExpr $2 $1 }
--
-- constructor_id :: { QualifiedName } assignment_statement :: { Stmt Position }
-- : TYPE_IDENT { makeQualified $1 } : value_ident '=' expression -- FIXME: Too restrictive!
-- | '(' OP_IDENT ')' { makeQualified $2 } { SBind $2 $1 (SExpr $2 $3) }
--
-- -- Type alias Declarations -------------------------------------------------- case_statement :: { Stmt Position }
-- : 'case' expression 'of' case_items
-- type_decl :: { Decl Position } { SCase $1 $2 $4 }
-- : 'type' { DeclType }
-- case_items :: { [(Pattern,Maybe (Expr Position),(Expr Position))] }
-- -- Newtype Declarations ----------------------------------------------------- : case_item { [$1] }
-- | case_items case_item { $1 ++ [$2] }
-- newtype_decl :: { Decl Position }
-- : 'newtype' { DeclNewtype } case_item :: { (Pattern, Maybe (Expr Position), (Expr Position)) }
-- : pattern mguard '->' expression { ($1, $2, $4) }
-- -- Type class Declarations --------------------------------------------------
-- mguard :: { Maybe (Expr Position) }
-- class_decl :: { Decl Position } : { Nothing }
-- : 'class' { DeclClass } | '|' expression { Just $2 }
--
-- -- Instance Declarations ---------------------------------------------------- -- Patterns for pattern matching
--
-- instance_decl :: { Decl Position } infix_operator :: { QualifiedName }
-- : 'instance' { DeclInstance } : OP_IDENT { makeQualified $1 }
-- | '`' VAL_IDENT '`' { makeQualified $2 }
-- -- Data value Declarations --------------------------------------------------
-- pattern_primary :: { Pattern }
-- value_decl :: { Decl Position } : TYPE_IDENT { PVar (makeQualified $1) }
-- : value_name '=' expr { DeclValue Nothing $1 (Just $3) } | VAL_IDENT { PVar (makeQualified $1) }
-- | '[' ']' { PVar (QualifiedName ["Data","List"] "NULL") }
-- value_name :: { QualifiedName } | INTVAL { let (Lexeme _ (TokInt (base, val))) = $1
-- : VAL_IDENT { makeQualified $1 } in PConst (ConstInteger base val) }
-- | '(' OP_IDENT ')' { makeQualified $2 } | FLOATVAL { let (Lexeme _ (TokFloat val)) = $1
-- in PConst (ConstFloat val) }
-- -- Data value type Declarations --------------------------------------------- | CHARVAL { let (Lexeme _ (TokChar val)) = $1
-- in PConst (ConstChar val) }
-- vtype_decl :: {Decl Position } | STRVAL { let (Lexeme _ (TokString val)) = $1
-- : value_name '::' bangtype { DeclValue (Just $3) $1 Nothing } in PConst (ConstString val) }
-- | '(' pattern ')' { $2 }
-- -- Types --------------------------------------------------------------------
-- pattern_infix :: { Pattern }
-- bangtype :: { Type } : pattern_infix infix_operator pattern_primary { PAp (PAp $1 (PVar $2)) $3 }
-- : bangtype1 { $1 } | pattern_primary { $1 }
--
-- bangtype1 :: { Type } pattern_ap :: { Pattern }
-- : bangtype1 VAL_IDENT { TAp $1 (TVar (makeQualified $2) Star) } : pattern_ap pattern_infix { PAp $1 $2 }
-- | bangtype2 { $1 } | pattern_infix { $1 }
--
-- bangtype2 :: { Type } pattern_name :: { Pattern }
-- : bangtype2 '->' bangtype3 : value_ident '@' pattern_name { PNamed $1 $3 }
-- { TAp (TAp (TCon (QualifiedName [] "->") Star) $1) $3 } | pattern_ap { $1 }
-- | bangtype3 { $1 }
-- pattern :: { Pattern }
-- bangtype3 :: { Type } : pattern_name { $1 }
-- : '[' bangtype3 ']'
-- { TAp (TVar (QualifiedName ["Data","List"] "List") Star) $2 } -- Expressions in bang
-- | bangtype4 { $1 }
-- primary_expression :: { Expr Position }
-- bangtype4 :: { Type } : '(' expression ')' { $2 }
-- : TYPE_IDENT { TVar (makeQualified $1) Star } | '[' ']' { VarRef $1 (QualifiedName ["Data","List"] "NULL") }
-- | '(' bangtype ')' { $2 } | INTVAL { let (Lexeme src (TokInt (base, val))) = $1
-- in Const src (ConstInteger base val) }
-- -- Statements --------------------------------------------------------------- | FLOATVAL { let (Lexeme src (TokFloat val)) = $1
-- in Const src (ConstFloat val) }
-- statement :: { Statement } | CHARVAL { let (Lexeme src (TokChar val)) = $1
-- : expr ';' { } in Const src (ConstChar val) }
-- | 'case' expr 'of' { } | STRVAL { let (Lexeme src (TokString val)) = $1
-- in Const src (ConstString val) }
-- -- Expressions -------------------------------------------------------------- | VAL_IDENT { let l@(Lexeme src (TokValIdent name)) = $1
-- in VarRef src (makeQualified l) }
-- expr :: { Expr Position }
-- : '\\' arglist '->' expr1 { Lambda Position $2 $4 } conditional_expression :: { Expr Position }
-- | expr1 { $1 } : primary_expression { $1 }
--
-- arglist :: { [QualifiedName] } infix_expression :: { Expr Position }
-- : VAL_IDENT { [makeQualified $1] } : infix_expression infix_operator conditional_expression
-- | arglist VAL_IDENT { $1 ++ [makeQualified $2] } { App (getSpecial $1) (VarRef (getSpecial $1) $2) [$1, $3] }
-- | conditional_expression
-- expr1 :: { Expr Position } { $1 }
-- : '{' exprs '}' { Block Position $2 }
-- | expr2 { $1 } lambda_expression :: { Expr Position }
-- : '\\' arguments '->' infix_expression
-- exprs :: { [Expr Position] } { Lambda $1 $2 $4 }
-- : expr ';' { [$1] } | infix_expression
-- | exprs expr ';' { $1 ++ [$2] } { $1 }
--
-- expr2 :: { Expr Position } arguments :: { [QualifiedName] }
-- : '[' list_exprs ']' { unwindList $2 } : value_ident { [$1] }
-- | expr3 { $1 } | arguments ',' value_ident { $1 ++ [$3] }
--
-- list_exprs :: { [Expr Position] } application_expression :: { Expr Position }
-- : { [] } : application_expression '(' app_args ')'
-- | list_exprs ',' expr3 { $1 ++ [$3] } { App $2 $1 $3 }
-- | application_expression '(' ')'
-- expr3 :: { Expr Position } { App $2 $1 [] }
-- : bottom_expr { $1 } | lambda_expression
-- { $1 }
-- bottom_expr :: { Expr Position }
-- : INTVAL { let (b,v) = $1 in Const () (ConstInteger b v) } app_args :: { [Expr Position] }
-- | FLOATVAL { Const Position (ConstFloat $1) } : expression { [$1] }
-- | CHARVAL { Const Position (ConstChar $1) } | app_args ',' expression { $1 ++ [$3] }
-- | STRVAL { Const Position (ConstString $1) }
-- | VAL_IDENT { VarRef Position (makeQualified $1) } block_expression :: { Expr Position }
-- | '[' ']' { VarRef () (QualifiedName ["Data","List"] "Null") } : '{' statements '}' { Block $1 $2 }
-- | '(' expr ')' { $2 } | application_expression { $1 }
expression :: { Expr Position }
: block_expression { $1 }
{ {
lexer :: (Lexeme -> Parser a) -> Parser a lexer :: (Lexeme -> Parser a) -> Parser a
@@ -375,8 +389,14 @@ happyError = raiseP "Parse Error"
pappend :: ([a],[b]) -> ([a],[b]) -> ([a],[b]) pappend :: ([a],[b]) -> ([a],[b]) -> ([a],[b])
pappend (a,b) (c,d) = (a++c,b++d) pappend (a,b) (c,d) = (a++c,b++d)
makeQualified :: String -> QualifiedName makeQualified :: Lexeme -> QualifiedName
makeQualified str = QualifiedName prefixes name makeQualified (Lexeme _ (TokTypeIdent str)) = makeQualified' str
makeQualified (Lexeme _ (TokValIdent str)) = makeQualified' str
makeQualified (Lexeme _ (TokOpIdent str)) = makeQualified' str
makeQualified _ = error "makeQualified bad arg"
makeQualified' :: String -> QualifiedName
makeQualified' str = QualifiedName prefixes name
where where
(prefixes,name) = loop str (prefixes,name) = loop str
loop val = loop val =
@@ -385,5 +405,26 @@ makeQualified str = QualifiedName prefixes name
then ([], pre) then ([], pre)
else let (pres, name) = loop rest else let (pres, name) = loop rest
in (pre:pres, name) in (pre:pres, name)
postProcessDeclVal :: QualifiedName ->
Maybe [(QualifiedName, Maybe Type)] ->
Maybe Type ->
(Position, Expr Position) ->
Parser (Decl Position)
postProcessDeclVal name margs mrettype (src, body) = do
final_type <- case mrettype of
Nothing -> do
name <- gensym
return (TVar name Star)
Just x ->
return x
case margs of
Nothing ->
return (DeclValue src [] final_type body)
Just [] ->
fail "Need to figure out empty arg items."
Just args ->
fail "Need to figure out non-empty arg items."
} }

View File

@@ -37,7 +37,7 @@ pprtPosition p = posFile p ++ ":" ++ show (posLine p) ++ ":" ++ show (posCol p)
data Token = LParen | RParen data Token = LParen | RParen
| LSquare | RSquare | LSquare | RSquare
| LBrace | RBrace | LBrace | RBrace
| Bar | Semi | Comma | Bar | Semi | Comma | BTick
| TokTypeIdent String | TokTypeIdent String
| TokValIdent String | TokValIdent String
| TokOpIdent String | TokOpIdent String
@@ -90,6 +90,7 @@ data ParserState = ParserState {
, psChar :: !Char , psChar :: !Char
, psPos :: !Position , psPos :: !Position
, psLexCode :: !Int , psLexCode :: !Int
, psGenNum :: !Int
} }
deriving (Show) deriving (Show)
@@ -99,6 +100,7 @@ initParserState path bs = ParserState {
, psChar = '\n' , psChar = '\n'
, psPos = initPosition path , psPos = initPosition path
, psLexCode = 0 , psLexCode = 0
, psGenNum = 0
} }
-- -------------------------------------------------------------------------- -- --------------------------------------------------------------------------
@@ -138,3 +140,9 @@ runParser path bs (Parser m) =
Right (a,_) -> Right a Right (a,_) -> Right a
Left err -> Left err Left err -> Left err
genstr :: Parser String
genstr = do
st <- get
set st{ psGenNum = psGenNum st + 1 }
return $ "--gen" ++ show (psGenNum st)

View File

@@ -22,7 +22,7 @@ cmd_ghc_d_hs = $(GHC) $(GHC_FLAGS) -M -dep-makefile $@ $<
quiet_cmd_ghc_d_hs = DEPEND $(notdir $@) quiet_cmd_ghc_d_hs = DEPEND $(notdir $@)
%.d : %.hs %.d : %.hs
$(call cmd,ghc_d_hs) $(call cmd,ghc_d_hs)
@$(SED) -i"" "s|: hsrc|: $(TOPDIR)/hsrc|g" $@ @$(SED) -i"" -e "s|: hsrc|: $(TOPDIR)/hsrc|g" $@
# ghc-ld # ghc-ld
cmd_ghc_ld = $(GHC) -o $@ $^ cmd_ghc_ld = $(GHC) -o $@ $^