diff --git a/fco2/GenerateC.hs b/fco2/GenerateC.hs index a56b27b..2748258 100644 --- a/fco2/GenerateC.hs +++ b/fco2/GenerateC.hs @@ -386,12 +386,23 @@ genFuncDyadic s e f genExpression f tell [")"] +genEitherDyadic :: String -> (A.Expression -> A.Expression -> CGen ()) -> A.Expression -> A.Expression -> CGen () +genEitherDyadic s const e f + = do ps <- get + -- If both arms of the expression are constant, then use an + -- unchecked implementation of the operator. + -- FIXME We might want to check that it doesn't overflow at + -- compile time. + if isConstExpression ps e && isConstExpression ps f + then const e f + else genFuncDyadic s e f + genDyadic :: A.DyadicOp -> A.Expression -> A.Expression -> CGen () -genDyadic A.Add e f = genFuncDyadic "occam_add" e f -genDyadic A.Subtr e f = genFuncDyadic "occam_subtr" e f -genDyadic A.Mul e f = genFuncDyadic "occam_mul" e f -genDyadic A.Div e f = genFuncDyadic "occam_div" e f -genDyadic A.Rem e f = genFuncDyadic "occam_rem" e f +genDyadic A.Add e f = genEitherDyadic "occam_add" (genSimpleDyadic "+") e f +genDyadic A.Subtr e f = genEitherDyadic "occam_subtr" (genSimpleDyadic "-") e f +genDyadic A.Mul e f = genEitherDyadic "occam_mul" (genSimpleDyadic "*") e f +genDyadic A.Div e f = genEitherDyadic "occam_div" (genSimpleDyadic "/") e f +genDyadic A.Rem e f = genEitherDyadic "occam_rem" (genSimpleDyadic "%") e f genDyadic A.Plus e f = genSimpleDyadic "+" e f genDyadic A.Minus e f = genSimpleDyadic "-" e f genDyadic A.Times e f = genSimpleDyadic "*" e f @@ -406,7 +417,8 @@ genDyadic A.Less e f = genSimpleDyadic "<" e f genDyadic A.More e f = genSimpleDyadic ">" e f genDyadic A.LessEq e f = genSimpleDyadic "<=" e f genDyadic A.MoreEq e f = genSimpleDyadic ">=" e f -genDyadic A.After e f = genFuncDyadic "occam_after" e f +genDyadic A.After e f + = genEitherDyadic "occam_after" (genFuncDyadic "occam_unchecked_after") e f --}}} --{{{ input/output items diff --git a/fco2/TODO b/fco2/TODO index 058be36..a94adf6 100644 --- a/fco2/TODO +++ b/fco2/TODO @@ -11,9 +11,17 @@ unchecked +. Parallel assignment should be handled by a simplification pass, not by GenerateC. (Then things get proper names and we can write a genAssignment function that handles different types.) + - and then array assignment can be made to work properly. Have a final pass that checks all the mangling has been done -- i.e. function calls have been removed, and so on. Multidimensional array literals won't work. +We do need to have a constant folding pass -- irritatingly -- because C won't do it. + +ALT needs to detect when it's being used over timers, and calculate when the +next timeout fires. + +Array indexing needs to be checked against the bounds (which'll do away with a +lot of the "_sizes unused" warnings). diff --git a/fco2/fco_support.h b/fco2/fco_support.h index eaebe11..dbbf5f3 100644 --- a/fco2/fco_support.h +++ b/fco2/fco_support.h @@ -59,5 +59,7 @@ static int occam_rem (int a, int b) { static bool occam_after (int a, int b) { return (a - b) > 0; } +#define occam_unchecked_after (a, b) \ + (((a) - (b)) > 0) #endif diff --git a/fco2/testcases/constants.occ b/fco2/testcases/constants.occ index 0a77b5f..bd28a84 100644 --- a/fco2/testcases/constants.occ +++ b/fco2/testcases/constants.occ @@ -11,14 +11,16 @@ PROC P () VAL INT e IS d[2]: VAL INT32 f RETYPES a: VAL INT g IS BYTESIN (a): + VAL BOOL aft IS a AFTER b: -- ... and these shouldn't. INT A: - VAL INT B IS A: - VAL INT C IS X: + VAL INT B IS A + 1: + VAL INT C IS X + B: VAL []INT D IS [1, 2, X, 4]: VAL INT E IS D[2]: -- technically the others should be OK, but I think that's excessive analysis! INT32 F RETYPES A: VAL INT G IS BYTESIN (E): + VAL BOOL AFT IS A AFTER B: SKIP :