-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuiltin.c
127 lines (112 loc) · 3.73 KB
/
builtin.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// Compiler implementation of the D programming language
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <assert.h>
#include <math.h>
#if __FreeBSD__
extern "C"
{
long double sinl(long double);
long double cosl(long double);
long double tanl(long double);
long double sqrtl(long double);
}
#endif
#include "mars.h"
#include "declaration.h"
#include "attrib.h"
#include "expression.h"
#include "scope.h"
#include "mtype.h"
#include "aggregate.h"
#include "identifier.h"
#include "id.h"
#include "module.h"
#if DMDV2
/**********************************
* Determine if function is a builtin one that we can
* evaluate at compile time.
*/
enum BUILTIN FuncDeclaration::isBuiltin()
{
static const char FeZe [] = "FNaNbNfeZe"; // @safe pure nothrow real function(real)
static const char FeZe2[] = "FNaNbNeeZe"; // @trusted pure nothrow real function(real)
//printf("FuncDeclaration::isBuiltin() %s, %d\n", toChars(), builtin);
if (builtin == BUILTINunknown)
{
builtin = BUILTINnot;
if (parent && parent->isModule())
{
// If it's in the std.math package
if (parent->ident == Id::math &&
parent->parent && (parent->parent->ident == Id::std || parent->parent->ident == Id::core) &&
!parent->parent->parent)
{
//printf("deco = %s\n", type->deco);
if (strcmp(type->deco, FeZe) == 0 || strcmp(type->deco, FeZe2) == 0)
{
if (ident == Id::sin)
builtin = BUILTINsin;
else if (ident == Id::cos)
builtin = BUILTINcos;
else if (ident == Id::tan)
builtin = BUILTINtan;
else if (ident == Id::_sqrt)
builtin = BUILTINsqrt;
else if (ident == Id::fabs)
builtin = BUILTINfabs;
//printf("builtin = %d\n", builtin);
}
// if float or double versions
else if (strcmp(type->deco, "FNaNbNfdZd") == 0 ||
strcmp(type->deco, "FNaNbNffZf") == 0)
{
if (ident == Id::_sqrt)
builtin = BUILTINsqrt;
}
}
}
}
return builtin;
}
/**************************************
* Evaluate builtin function.
* Return result; NULL if cannot evaluate it.
*/
Expression *eval_builtin(enum BUILTIN builtin, Expressions *arguments)
{
assert(arguments && arguments->dim);
Expression *arg0 = arguments->tdata()[0];
Expression *e = NULL;
switch (builtin)
{
case BUILTINsin:
if (arg0->op == TOKfloat64)
e = new RealExp(0, sinl(arg0->toReal()), arg0->type);
break;
case BUILTINcos:
if (arg0->op == TOKfloat64)
e = new RealExp(0, cosl(arg0->toReal()), arg0->type);
break;
case BUILTINtan:
if (arg0->op == TOKfloat64)
e = new RealExp(0, tanl(arg0->toReal()), arg0->type);
break;
case BUILTINsqrt:
if (arg0->op == TOKfloat64)
e = new RealExp(0, sqrtl(arg0->toReal()), arg0->type);
break;
case BUILTINfabs:
if (arg0->op == TOKfloat64)
e = new RealExp(0, fabsl(arg0->toReal()), arg0->type);
break;
}
return e;
}
#endif