summaryrefslogtreecommitdiff
path: root/graphics/asymptote/fundec.h
diff options
context:
space:
mode:
Diffstat (limited to 'graphics/asymptote/fundec.h')
-rw-r--r--graphics/asymptote/fundec.h173
1 files changed, 173 insertions, 0 deletions
diff --git a/graphics/asymptote/fundec.h b/graphics/asymptote/fundec.h
new file mode 100644
index 0000000000..5dd0dab85b
--- /dev/null
+++ b/graphics/asymptote/fundec.h
@@ -0,0 +1,173 @@
+/*****
+ * 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;
+ bool keywordOnly;
+
+public:
+ formal(position pos, ty *base, decidstart *start=0, varinit *defval=0,
+ bool Explicit= false, bool keywordOnly=false)
+ : absyn(pos), base(base), start(start), Explicit(Explicit),
+ defval(defval), keywordOnly(keywordOnly) {}
+
+ 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() : symbol::nullsym;
+ }
+
+ bool getExplicit() {
+ return Explicit;
+ }
+
+ bool isKeywordOnly() {
+ return keywordOnly;
+ }
+};
+
+class formals : public absyn {
+ //friend class funheader;
+
+ mem::list<formal *> fields;
+ formal *rest;
+
+ // If the list of formals contains at least one keyword-only formal.
+ bool keywordOnly;
+
+ void addToSignature(types::signature& sig,
+ coenv &e, bool encodeDefVal, bool tacit);
+public:
+ formals(position pos)
+ : absyn(pos), rest(0), keywordOnly(false) {}
+
+ virtual ~formals() {}
+
+ virtual void prettyprint(ostream &out, Int indent);
+
+ virtual void add(formal *f) {
+ if (f->isKeywordOnly()) {
+ keywordOnly = true;
+ }
+ else if (rest) {
+ em.error(f->getPos());
+ em << "normal parameter after rest parameter";
+ }
+ else if (keywordOnly) {
+ em.error(f->getPos());
+ em << "normal parameter after keyword-only parameter";
+ }
+
+ fields.push_back(f);
+ }
+
+ virtual void addRest(formal *f) {
+ if (rest) {
+ em.error(f->getPos());
+ em << "additional rest parameter";
+ }
+ else if (f->isKeywordOnly()) {
+ em.error(f->getPos());
+ em << "rest parameter declared as keyword-only";
+ }
+ 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() {}
+
+ 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