Intrinsic functions (SQRT and DSQRT)
This commit is contained in:
parent
2d88249408
commit
1932ae534a
|
@ -109,6 +109,7 @@ data Expression =
|
||||||
| True Meta
|
| True Meta
|
||||||
| False Meta
|
| False Meta
|
||||||
| FunctionCall Meta Name [Expression]
|
| FunctionCall Meta Name [Expression]
|
||||||
|
| IntrinsicFunctionCall Meta String [Expression]
|
||||||
| SubscriptedExpr Meta Subscript Expression
|
| SubscriptedExpr Meta Subscript Expression
|
||||||
| BytesInExpr Meta Expression
|
| BytesInExpr Meta Expression
|
||||||
| BytesInType Meta Type
|
| BytesInType Meta Type
|
||||||
|
|
|
@ -394,6 +394,7 @@ genExpression (A.ExprLiteral m l) = genLiteral l
|
||||||
genExpression (A.True m) = tell ["true"]
|
genExpression (A.True m) = tell ["true"]
|
||||||
genExpression (A.False m) = tell ["false"]
|
genExpression (A.False m) = tell ["false"]
|
||||||
--genExpression (A.FunctionCall m n es)
|
--genExpression (A.FunctionCall m n es)
|
||||||
|
genExpression (A.IntrinsicFunctionCall m s es) = genIntrinsicFunction m s es
|
||||||
--genExpression (A.SubscriptedExpr m s e)
|
--genExpression (A.SubscriptedExpr m s e)
|
||||||
--genExpression (A.BytesInExpr m e)
|
--genExpression (A.BytesInExpr m e)
|
||||||
genExpression (A.BytesInType m t) = genBytesInType t
|
genExpression (A.BytesInType m t) = genBytesInType t
|
||||||
|
@ -405,6 +406,13 @@ genTypeSymbol s t
|
||||||
= case scalarType t of
|
= case scalarType t of
|
||||||
Just ct -> tell ["occam_", s, "_", ct]
|
Just ct -> tell ["occam_", s, "_", ct]
|
||||||
Nothing -> missing $ "genTypeSymbol " ++ show t
|
Nothing -> missing $ "genTypeSymbol " ++ show t
|
||||||
|
|
||||||
|
genIntrinsicFunction :: Meta -> String -> [A.Expression] -> CGen ()
|
||||||
|
genIntrinsicFunction m s es
|
||||||
|
= do tell ["occam_", s, " ("]
|
||||||
|
sequence [genExpression e >> genComma | e <- es]
|
||||||
|
genMeta m
|
||||||
|
tell [")"]
|
||||||
--}}}
|
--}}}
|
||||||
|
|
||||||
--{{{ operators
|
--{{{ operators
|
||||||
|
|
16
fco2/Intrinsics.hs
Normal file
16
fco2/Intrinsics.hs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
-- | Definitions of intrinsic FUNCTIONs and PROCs.
|
||||||
|
module Intrinsics where
|
||||||
|
|
||||||
|
import qualified AST as A
|
||||||
|
|
||||||
|
intrinsicFunctions :: [(String, ([A.Type], [(A.Type, String)]))]
|
||||||
|
intrinsicFunctions =
|
||||||
|
[ ("SQRT", ([A.Real32], [(A.Real32, "value")]))
|
||||||
|
, ("DSQRT", ([A.Real64], [(A.Real64, "value")]))
|
||||||
|
]
|
||||||
|
|
||||||
|
intrinsicProcs :: [(String, [(A.AbbrevMode, A.Type, String)])]
|
||||||
|
intrinsicProcs =
|
||||||
|
[ ("ASSERT", [(A.ValAbbrev, A.Bool, "value")])
|
||||||
|
]
|
||||||
|
|
|
@ -12,4 +12,6 @@ what gets inlined).
|
||||||
|
|
||||||
Intrinsics:
|
Intrinsics:
|
||||||
- ASSERT
|
- ASSERT
|
||||||
|
- SQRT
|
||||||
|
- DSQRT
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ sources = \
|
||||||
EvalLiterals.hs \
|
EvalLiterals.hs \
|
||||||
GenerateC.hs \
|
GenerateC.hs \
|
||||||
Indentation.hs \
|
Indentation.hs \
|
||||||
|
Intrinsics.hs \
|
||||||
Main.hs \
|
Main.hs \
|
||||||
Metadata.hs \
|
Metadata.hs \
|
||||||
Parse.hs \
|
Parse.hs \
|
||||||
|
|
114
fco2/Parse.hs
114
fco2/Parse.hs
|
@ -18,6 +18,7 @@ import Errors
|
||||||
import EvalConstants
|
import EvalConstants
|
||||||
import EvalLiterals
|
import EvalLiterals
|
||||||
import Indentation
|
import Indentation
|
||||||
|
import Intrinsics
|
||||||
import Metadata
|
import Metadata
|
||||||
import ParseState
|
import ParseState
|
||||||
import Pass
|
import Pass
|
||||||
|
@ -746,41 +747,9 @@ character
|
||||||
<?> "character"
|
<?> "character"
|
||||||
--}}}
|
--}}}
|
||||||
--{{{ expressions
|
--{{{ expressions
|
||||||
functionNameSingle :: OccParser A.Name
|
|
||||||
functionNameSingle
|
|
||||||
= do n <- functionName
|
|
||||||
rts <- returnTypesOfFunction n
|
|
||||||
case rts of
|
|
||||||
[_] -> return n
|
|
||||||
_ -> pzero
|
|
||||||
<?> "function with single return value"
|
|
||||||
|
|
||||||
functionNameMulti :: OccParser A.Name
|
|
||||||
functionNameMulti
|
|
||||||
= do n <- functionName
|
|
||||||
rts <- returnTypesOfFunction n
|
|
||||||
case rts of
|
|
||||||
[_] -> pzero
|
|
||||||
_ -> return n
|
|
||||||
<?> "function with multiple return values"
|
|
||||||
|
|
||||||
functionActuals :: A.Name -> OccParser [A.Expression]
|
|
||||||
functionActuals func
|
|
||||||
= do A.Function _ _ fs _ <- specTypeOfName func
|
|
||||||
let ats = [t | A.Formal _ t _ <- fs]
|
|
||||||
sLeftR
|
|
||||||
es <- intersperseP (map expressionOfType ats) sComma
|
|
||||||
sRightR
|
|
||||||
return es
|
|
||||||
|
|
||||||
expressionList :: [A.Type] -> OccParser A.ExpressionList
|
expressionList :: [A.Type] -> OccParser A.ExpressionList
|
||||||
expressionList types
|
expressionList types
|
||||||
= do m <- md
|
= functionMulti types
|
||||||
n <- try functionNameMulti
|
|
||||||
as <- functionActuals n
|
|
||||||
rts <- returnTypesOfFunction n
|
|
||||||
matchTypes types rts
|
|
||||||
return $ A.FunctionCallList m n as
|
|
||||||
<|> do m <- md
|
<|> do m <- md
|
||||||
es <- intersperseP (map expressionOfType types) sComma
|
es <- intersperseP (map expressionOfType types) sComma
|
||||||
return $ A.ExpressionList m es
|
return $ A.ExpressionList m es
|
||||||
|
@ -870,6 +839,73 @@ operandOfType wantT
|
||||||
matchType wantT t
|
matchType wantT t
|
||||||
return o
|
return o
|
||||||
--}}}
|
--}}}
|
||||||
|
--{{{ functions
|
||||||
|
functionNameValued :: Bool -> OccParser A.Name
|
||||||
|
functionNameValued isMulti
|
||||||
|
= do n <- functionName
|
||||||
|
rts <- returnTypesOfFunction n
|
||||||
|
case (rts, isMulti) of
|
||||||
|
([_], False) -> return n
|
||||||
|
((_:_:_), True) -> return n
|
||||||
|
_ -> pzero
|
||||||
|
<?> "function name"
|
||||||
|
|
||||||
|
functionActuals :: [A.Formal] -> OccParser [A.Expression]
|
||||||
|
functionActuals fs
|
||||||
|
= do let actuals = [expressionOfType t <?> "actual for " ++ show n
|
||||||
|
| A.Formal _ t n <- fs]
|
||||||
|
es <- intersperseP actuals sComma
|
||||||
|
return es
|
||||||
|
|
||||||
|
functionSingle :: OccParser A.Expression
|
||||||
|
functionSingle
|
||||||
|
= do m <- md
|
||||||
|
n <- tryVX (functionNameValued False) sLeftR
|
||||||
|
A.Function _ _ fs _ <- specTypeOfName n
|
||||||
|
as <- functionActuals fs
|
||||||
|
sRightR
|
||||||
|
return $ A.FunctionCall m n as
|
||||||
|
<?> "single-valued function call"
|
||||||
|
|
||||||
|
functionMulti :: [A.Type] -> OccParser A.ExpressionList
|
||||||
|
functionMulti types
|
||||||
|
= do m <- md
|
||||||
|
n <- tryVX (functionNameValued True) sLeftR
|
||||||
|
A.Function _ _ fs _ <- specTypeOfName n
|
||||||
|
as <- functionActuals fs
|
||||||
|
sRightR
|
||||||
|
rts <- returnTypesOfFunction n
|
||||||
|
matchTypes types rts
|
||||||
|
return $ A.FunctionCallList m n as
|
||||||
|
<?> "multi-valued function call"
|
||||||
|
--}}}
|
||||||
|
--{{{ intrinsic functions
|
||||||
|
intrinsicFunctionName :: Bool -> OccParser (String, [A.Type], [A.Formal])
|
||||||
|
intrinsicFunctionName isMulti
|
||||||
|
= do n <- anyName A.FunctionName
|
||||||
|
let s = A.nameName n
|
||||||
|
case (lookup s intrinsicFunctions, isMulti) of
|
||||||
|
(Nothing, _) -> pzero
|
||||||
|
(Just ([_], _), True) -> pzero
|
||||||
|
(Just ((_:_:_), _), False) -> pzero
|
||||||
|
(Just (rts, tns), _) ->
|
||||||
|
return (s, rts, [A.Formal A.ValAbbrev t (A.Name emptyMeta A.VariableName n)
|
||||||
|
| (t, n) <- tns])
|
||||||
|
<?> "intrinsic function name"
|
||||||
|
|
||||||
|
intrinsicFunctionSingle :: OccParser A.Expression
|
||||||
|
intrinsicFunctionSingle
|
||||||
|
= do m <- md
|
||||||
|
(s, _, fs) <- tryVX (intrinsicFunctionName False) sLeftR
|
||||||
|
as <- functionActuals fs
|
||||||
|
sRightR
|
||||||
|
return $ A.IntrinsicFunctionCall m s as
|
||||||
|
<?> "single-valued intrinsic function call"
|
||||||
|
|
||||||
|
-- No support for multi-valued intrinsic functions, because I don't think there
|
||||||
|
-- are likely to be any, and supporting them in the C backend is slightly
|
||||||
|
-- tricky.
|
||||||
|
--}}}
|
||||||
|
|
||||||
monadicOperator :: OccParser A.MonadicOp
|
monadicOperator :: OccParser A.MonadicOp
|
||||||
monadicOperator
|
monadicOperator
|
||||||
|
@ -965,7 +1001,8 @@ operandNotTable'
|
||||||
<|> do { m <- md; l <- literal; return $ A.ExprLiteral m l }
|
<|> do { m <- md; l <- literal; return $ A.ExprLiteral m l }
|
||||||
<|> do { sLeftR; e <- expression; sRightR; return e }
|
<|> do { sLeftR; e <- expression; sRightR; return e }
|
||||||
-- XXX value process
|
-- XXX value process
|
||||||
<|> do { m <- md; n <- try functionNameSingle; as <- functionActuals n; return $ A.FunctionCall m n as }
|
<|> functionSingle
|
||||||
|
<|> intrinsicFunctionSingle
|
||||||
<|> do m <- md
|
<|> do m <- md
|
||||||
sBYTESIN
|
sBYTESIN
|
||||||
sLeftR
|
sLeftR
|
||||||
|
@ -1720,11 +1757,6 @@ actual (A.Formal am t n)
|
||||||
an = A.nameName n
|
an = A.nameName n
|
||||||
--}}}
|
--}}}
|
||||||
--{{{ intrinsic PROC call
|
--{{{ intrinsic PROC call
|
||||||
intrinsicProcs :: [(String, [(A.AbbrevMode, A.Type, String)])]
|
|
||||||
intrinsicProcs =
|
|
||||||
[ ("ASSERT", [(A.ValAbbrev, A.Bool, "value")])
|
|
||||||
]
|
|
||||||
|
|
||||||
intrinsicProcName :: OccParser (String, [A.Formal])
|
intrinsicProcName :: OccParser (String, [A.Formal])
|
||||||
intrinsicProcName
|
intrinsicProcName
|
||||||
= do n <- anyName A.ProcName
|
= do n <- anyName A.ProcName
|
||||||
|
@ -1737,11 +1769,11 @@ intrinsicProcName
|
||||||
intrinsicProc :: OccParser A.Process
|
intrinsicProc :: OccParser A.Process
|
||||||
intrinsicProc
|
intrinsicProc
|
||||||
= do m <- md
|
= do m <- md
|
||||||
(n, fs) <- tryVX intrinsicProcName sLeftR
|
(s, fs) <- tryVX intrinsicProcName sLeftR
|
||||||
as <- actuals fs
|
as <- actuals fs
|
||||||
sRightR
|
sRightR
|
||||||
eol
|
eol
|
||||||
return $ A.IntrinsicProcCall m n as
|
return $ A.IntrinsicProcCall m s as
|
||||||
<?> "intrinsic PROC instance"
|
<?> "intrinsic PROC instance"
|
||||||
--}}}
|
--}}}
|
||||||
--{{{ preprocessor directives
|
--{{{ preprocessor directives
|
||||||
|
|
|
@ -11,6 +11,7 @@ import Data.Maybe
|
||||||
import qualified AST as A
|
import qualified AST as A
|
||||||
import Errors
|
import Errors
|
||||||
import EvalLiterals
|
import EvalLiterals
|
||||||
|
import Intrinsics
|
||||||
import ParseState
|
import ParseState
|
||||||
import Metadata
|
import Metadata
|
||||||
|
|
||||||
|
@ -143,6 +144,7 @@ typeOfExpression e
|
||||||
A.True m -> return A.Bool
|
A.True m -> return A.Bool
|
||||||
A.False m -> return A.Bool
|
A.False m -> return A.Bool
|
||||||
A.FunctionCall m n es -> liftM head $ returnTypesOfFunction n
|
A.FunctionCall m n es -> liftM head $ returnTypesOfFunction n
|
||||||
|
A.IntrinsicFunctionCall _ s _ -> liftM head $ returnTypesOfIntrinsic s
|
||||||
A.SubscriptedExpr m s e ->
|
A.SubscriptedExpr m s e ->
|
||||||
typeOfExpression e >>= subscriptType s
|
typeOfExpression e >>= subscriptType s
|
||||||
A.BytesInExpr m e -> return A.Int
|
A.BytesInExpr m e -> return A.Int
|
||||||
|
@ -166,6 +168,12 @@ returnTypesOfFunction n
|
||||||
checkJust "not defined as a function" $
|
checkJust "not defined as a function" $
|
||||||
lookup (A.nameName n) (psFunctionReturns ps)
|
lookup (A.nameName n) (psFunctionReturns ps)
|
||||||
|
|
||||||
|
returnTypesOfIntrinsic :: (PSM m, Die m) => String -> m [A.Type]
|
||||||
|
returnTypesOfIntrinsic s
|
||||||
|
= case lookup s intrinsicFunctions of
|
||||||
|
Just (rts, _) -> return rts
|
||||||
|
Nothing -> die $ "unknown intrinsic function " ++ s
|
||||||
|
|
||||||
-- | Get the items in a channel's protocol (for typechecking).
|
-- | Get the items in a channel's protocol (for typechecking).
|
||||||
-- Returns Left if it's a simple protocol, Right if it's tagged.
|
-- Returns Left if it's a simple protocol, Right if it's tagged.
|
||||||
protocolItems :: (PSM m, Die m) => A.Variable -> m (Either [A.Type] [(A.Name, [A.Type])])
|
protocolItems :: (PSM m, Die m) => A.Variable -> m (Either [A.Type] [(A.Name, [A.Type])])
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// C99 support definitions for FCO.
|
// C99 support definitions for FCO.
|
||||||
|
// vim:set foldmethod=marker:
|
||||||
|
|
||||||
#ifndef FCO_SUPPORT_H
|
#ifndef FCO_SUPPORT_H
|
||||||
#define FCO_SUPPORT_H
|
#define FCO_SUPPORT_H
|
||||||
|
@ -9,9 +10,11 @@
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#include <cifccsp.h>
|
#include <cifccsp.h>
|
||||||
|
|
||||||
|
//{{{ mostneg/mostpos
|
||||||
#define occam_mostneg_bool false
|
#define occam_mostneg_bool false
|
||||||
#define occam_mostpos_bool true
|
#define occam_mostpos_bool true
|
||||||
#define occam_mostneg_char CHAR_MIN
|
#define occam_mostneg_char CHAR_MIN
|
||||||
|
@ -28,7 +31,9 @@
|
||||||
#define occam_mostpos_float FLT_MAX
|
#define occam_mostpos_float FLT_MAX
|
||||||
#define occam_mostneg_double -DBL_MAX
|
#define occam_mostneg_double -DBL_MAX
|
||||||
#define occam_mostpos_double DBL_MAX
|
#define occam_mostpos_double DBL_MAX
|
||||||
|
//}}}
|
||||||
|
|
||||||
|
//{{{ compiler-specific attributes
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#define occam_struct_packed __attribute__ ((packed))
|
#define occam_struct_packed __attribute__ ((packed))
|
||||||
#define occam_unused __attribute__ ((unused))
|
#define occam_unused __attribute__ ((unused))
|
||||||
|
@ -37,7 +42,9 @@
|
||||||
#define occam_struct_packed
|
#define occam_struct_packed
|
||||||
#define occam_unused
|
#define occam_unused
|
||||||
#endif
|
#endif
|
||||||
|
//}}}
|
||||||
|
|
||||||
|
//{{{ runtime check functions
|
||||||
#define occam_stop(pos, format, args...) \
|
#define occam_stop(pos, format, args...) \
|
||||||
do { \
|
do { \
|
||||||
EXTERNAL_CALLN (fprintf, stderr, "Program stopped at %s: " format "\n", pos, ##args); \
|
EXTERNAL_CALLN (fprintf, stderr, "Program stopped at %s: " format "\n", pos, ##args); \
|
||||||
|
@ -59,7 +66,9 @@ static int occam_check_index (int i, int limit, const char *pos) {
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
//}}}
|
||||||
|
|
||||||
|
//{{{ type-specific runtime checks
|
||||||
#define MAKE_RANGE_CHECK(type, format) \
|
#define MAKE_RANGE_CHECK(type, format) \
|
||||||
static type occam_range_check_##type (type, type, type, const char *) occam_unused; \
|
static type occam_range_check_##type (type, type, type, const char *) occam_unused; \
|
||||||
static type occam_range_check_##type (type lower, type upper, type n, const char *pos) { \
|
static type occam_range_check_##type (type lower, type upper, type n, const char *pos) { \
|
||||||
|
@ -163,5 +172,20 @@ MAKE_DIV(double)
|
||||||
#undef MAKE_MUL
|
#undef MAKE_MUL
|
||||||
#undef MAKE_DIV
|
#undef MAKE_DIV
|
||||||
#undef MAKE_REM
|
#undef MAKE_REM
|
||||||
|
//}}}
|
||||||
|
|
||||||
|
//{{{ intrinsics
|
||||||
|
// FIXME These should do range checks.
|
||||||
|
|
||||||
|
static float occam_SQRT (float, const char *) occam_unused;
|
||||||
|
static float occam_SQRT (float v, const char *pos) {
|
||||||
|
return sqrtf (v);
|
||||||
|
}
|
||||||
|
|
||||||
|
static double occam_DSQRT (double, const char *) occam_unused;
|
||||||
|
static double occam_DSQRT (double v, const char *pos) {
|
||||||
|
return sqrt (v);
|
||||||
|
}
|
||||||
|
//}}}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
PROC P ()
|
PROC P ()
|
||||||
|
REAL32 r:
|
||||||
|
REAL64 d:
|
||||||
SEQ
|
SEQ
|
||||||
ASSERT (TRUE)
|
ASSERT (TRUE)
|
||||||
-- check we can override an intrinsic
|
-- check we can override an intrinsic
|
||||||
|
@ -6,4 +8,8 @@ PROC P ()
|
||||||
SKIP
|
SKIP
|
||||||
:
|
:
|
||||||
ASSERT (FALSE)
|
ASSERT (FALSE)
|
||||||
|
|
||||||
|
r := SQRT (3.141)
|
||||||
|
r := 41.5 + SQRT (SQRT (SQRT (4.0)))
|
||||||
|
d := DSQRT (3.141 (REAL64))
|
||||||
:
|
:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user