diff options
Diffstat (limited to 'assignment-13/uFPL/C.icl')
-rw-r--r-- | assignment-13/uFPL/C.icl | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/assignment-13/uFPL/C.icl b/assignment-13/uFPL/C.icl new file mode 100644 index 0000000..763774c --- /dev/null +++ b/assignment-13/uFPL/C.icl @@ -0,0 +1,107 @@ +implementation module uFPL.C + +from StdFunc import id, o, twice +import StdList +import StdOrdList +import StdString +import StdTuple + +from Data.Func import $ +import Data.Generics.GenDefault +import Data.List +import Data.Maybe +import Data.Tuple + +import uFPL.Arduino +import uFPL.Util + +(`seq`) infix 0 :: CBody CBody -> CBody +(`seq`) CBEmpty cb = cb +(`seq`) cb CBEmpty = cb +(`seq`) a b = CBSeq a b + +gDefault{|UNIT|} = UNIT +gDefault{|RECORD|} f = RECORD f +gDefault{|Bool|} = False +gDefault{|Char|} = '\x00' +gDefault{|Maybe|} _ = Nothing + +derive gDefault Button, Signedness, CType, CExpr, CBody, CFun + +instance print Signedness +where + print Sig = print "signed" + print Unsig = print "unsigned" + +instance print CType +where + print (CTChar s) = print s o print " char" + print CTBool = print "bool" + print (CTInt s) = print s o print " int" + print (CTLong s) = print s o print " long" + print CTVoid = print "void" + print (CTArray t) = print "*" o print t + print (CTStruct s) = print "struct " o print s + +instance print (Int,CType) // Variable +where + print (i,t) = print t o print " v" o print i + +instance print CExpr +where + print (CEButton b) = print b + print (CEGlobal g) = print g + print (CEInfix op a b) = print "(" o print a o print ") " o print op o print " (" o print b o print ")" + print (CEApp f ps) = print f o print "(" o prsperse ", " ps o print ")" + print (CEBool b) = print (if b "true" "false") + print (CEInt i) = print i + print (CEChar c) = print "'" o print (toString c) o print "'" + print (CEIf b t e) = print "(" o print b o print " ? " o print t o print " : " o print e o print ")" + print (CERef e) = print "&(" o print e o print ")" + print (CEDeref e) = print "*(" o print e o print ")" + print (CEStruct m) = print "{" o indent o nl o prsperse (print "," o nl) (map pr m) o unindent o nl o print "}" + where + pr :: (String, CExpr) -> String + pr (s, e) = "." +++ s +++ " = " +++ printToString e + +instance print CBody +where + print (CBReturn Nothing) = print "return;" + print (CBReturn (Just e)) = print "return " o print e o print ";" + print (CBIf c t e) = print "if (" o print c o print ") {" o indent o nl + o print t o unindent o nl + o print "} else {" o indent o nl + o print e o unindent o nl o print "}" + print (CBWhile e b) = print "while (" o print e o print ") {" o nl o print b o nl o print "}" + print (CBAssign v e) = print v o print " = " o print e o print ";" + print (CBSeq a b) = print a o nl o print b + print CBEmpty = id + print (CBExpr e) = print e o print ";" + +instance print CVar +where + print v = print v.CVar.type o print " " o print v.CVar.name o print " = " o print v.value o print ";" + +instance print CFun +where + print cf = print cf.CFun.type o print " " o print cf.CFun.name + o print "(" o prsperse ", " cf.params o print ") {" o indent o nl + o print cf.body o unindent o nl o print "}" + +instance print CProg +where + print prog = print prog.bootstrap o twice nl + o prsperse (twice nl) prog.globals o twice nl + o prsperse (twice nl) prog.funs + +combinePrograms :: CProg CProg -> CProg +combinePrograms a b = + { bootstrap = if (a.bootstrap == b.bootstrap) id ((+++) a.bootstrap) b.bootstrap + , globals = sortBy varLt $ nubBy varEq (a.globals ++ b.globals) + , funs = sortBy funLt $ nubBy funEq (a.funs ++ b.funs) + } +where + varEq a b = a.CVar.name == b.CVar.name + varLt a b = a.CVar.name < b.CVar.name + funEq a b = a.CFun.name == b.CFun.name + funLt a b = a.CFun.name < b.CFun.name |