From bee62a7f1ac399fa1641711ecbbca46b66adcfc4 Mon Sep 17 00:00:00 2001 From: Tom Smeding Date: Wed, 20 Nov 2019 22:51:12 +0100 Subject: Move compiler macro's to separate module (from Compiler) --- CompilerMacros.hs | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 CompilerMacros.hs (limited to 'CompilerMacros.hs') diff --git a/CompilerMacros.hs b/CompilerMacros.hs new file mode 100644 index 0000000..610e659 --- /dev/null +++ b/CompilerMacros.hs @@ -0,0 +1,51 @@ +module CompilerMacros(compilerMacros) where + +import AST + + +compilerMacros :: Program -> Program +compilerMacros (Program values) = Program (map process values) + +process :: Value -> Value +process (VList [VName "define", VName name, VList args, body]) + | Just names <- mapM fromVName args = process (VList [VName "define", VName name, VLambda names body]) + | otherwise = error "Invalid 'define' shorthand syntax: Invalid argument list" +process (VList [VName "define", VName name, value]) = VDefine name (process value) +process (VList (VName "define" : _)) = error "Invalid 'define' syntax" + +process (VList [VName "lambda", VList args, body]) + | Just names <- mapM fromVName args = process (VLambda names body) + | otherwise = error "Invalid 'lambda' syntax: Invalid argument list" +process (VList (VName "lambda" : _)) = error "Invalid 'lambda' syntax" + +process (VList [VName "lambdarec", VName recname, VList args, body]) + | Just names <- mapM fromVName args = process (VLambdaRec recname names body) + | otherwise = error "Invalid 'lambdarec' syntax: Invalid argument list" +process (VList (VName "lambdarec" : _)) = error "Invalid 'lambdarec' syntax" + +-- process (VList [VName "let", VList args, body]) = +-- case sequence [case p of { [n, v] -> Just (n, v); _ -> Nothing } | VList p <- args] of +-- Just pairs -> +-- process (VList (VList [VName "lambda", VList (map fst pairs), body] : map snd pairs)) +-- Nothing -> +-- error "Invalid 'let' syntax: Invalid variable list (not all pairs)" +process (VList [VName "let", VList args, body]) = + case sequence [case p of { [VName n, v] -> Just (n, v); _ -> Nothing } | VList p <- args] of + Just pairs -> + process (VLet pairs body) + Nothing -> + error "Invalid 'let' syntax: Invalid variable list (not all pairs)" +process (VList (VName "let" : _)) = error "Invalid 'let' syntax: Invalid argument list" + +process (VList values) = VList (map process values) + +process (VDefine name body) = VDefine name (process body) +process (VLambda args body) = VLambda args (process body) +process (VLambdaRec recname args body) = VLambdaRec recname args (process body) +process (VLet args body) = VLet [(name, process value) | (name, value) <- args] (process body) +process v@(VNum _) = v +process v@(VString _) = v +process v@(VName _) = v +process v@(VQuoted _) = v +process v@(VBuiltin _) = v +process v@VEllipsis = v -- cgit v1.2.3-70-g09d2