summaryrefslogtreecommitdiff
path: root/Build/source/utils/asymptote/fundec.h
blob: 98ff2e3f51ff282affe42448c1e39b7b15b17683 (plain)
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*****
 * fundec.h
 * Andy Hammerlindl 2002/8/29
 *
 * Defines the semantics for defining functions.  Both the newexp syntax, and
 * the abbreviated C-style function definition.
 *****/

#ifndef FUNDEC_H
#define FUNDEC_H

#include "dec.h"
#include "exp.h"

namespace absyntax {

class formal : public absyn {
  ty *base;
  decidstart *start;
  bool Explicit;
  varinit *defval;

public:
  formal(position pos, ty *base, decidstart *start=0, varinit *defval=0,
         bool Explicit= false)
    : absyn(pos), base(base), start(start), Explicit(Explicit),
      defval(defval) {}

  virtual void prettyprint(ostream &out, Int indent);

  // Build the corresponding types::formal to put into a signature.
  types::formal trans(coenv &e, bool encodeDefVal, bool tacit=false);
  
  // Add the formal parameter to the environment to prepare for the
  // function body's translation.
  virtual void transAsVar(coenv &e, Int index);

  types::ty *getType(coenv &e, bool tacit=false);

  virtual void addOps(coenv &e, record *r);

  varinit *getDefaultValue() {
    return defval;
  }

  symbol *getName() {
    return start ? start->getName() : 0;
  }

  bool getExplicit() {
    return Explicit;
  }
};

class formals : public absyn {
  //friend class funheader;

  mem::list<formal *> fields;
  formal *rest;

  void addToSignature(types::signature& sig,
                      coenv &e, bool encodeDefVal, bool tacit);
public:
  formals(position pos)
    : absyn(pos), rest(0) {}

  virtual ~formals() {}

  virtual void prettyprint(ostream &out, Int indent);

  virtual void add(formal *f) {
    fields.push_back(f);
  }

  virtual void addRest(formal *f) {
    rest = f;
  }

  // Returns the types of each parameter as a signature.
  // encodeDefVal means that it will also encode information regarding
  // the default values into the signature
  types::signature *getSignature(coenv &e,
                                 bool encodeDefVal = false,
                                 bool tacit = false);

  // Returns the corresponding function type, assuming it has a return
  // value of "result."
  types::function *getType(types::ty *result, coenv &e,
                           bool encodeDefVal = false,
                           bool tacit = false);

  virtual void addOps(coenv &e, record *r);

  // Add the formal parameters to the environment to prepare for the
  // function body's translation.
  virtual void trans(coenv &e);
};

class fundef : public exp {
  ty *result;
  formals *params;
  stm *body;

  // If the fundef is part of a fundec, the name of the function is stored
  // here for debugging purposes.
  symbol *id;

  friend class fundec;
  
public:
  fundef(position pos, ty *result, formals *params, stm *body)
    : exp(pos), result(result), params(params), body(body), id(0) {}

  virtual void prettyprint(ostream &out, Int indent);

  varinit *makeVarInit(types::function *ft);
  virtual void baseTrans(coenv &e, types::function *ft);
  virtual types::ty *trans(coenv &e);

  virtual types::function *transType(coenv &e, bool tacit);
  virtual types::function *transTypeAndAddOps(coenv &e, record *r, bool tacit);
  virtual types::ty *getType(coenv &e) {
    return transType(e, true);
  }
};

class fundec : public dec {
  symbol *id;
  fundef fun;

public:
  fundec(position pos, ty *result, symbol *id, formals *params, stm *body)
    : dec(pos), id(id), fun(pos, result, params, body)
  { fun.id = id; }

  void prettyprint(ostream &out, Int indent);

  void trans(coenv &e);

  void transAsField(coenv &e, record *r);
};
  
} // namespace absyntax

#endif