Related articles |
---|
Trouble implementing a standard library -- Calling C functions from wi noitalmost@cox.net (noitalmost) (2014-03-19) |
Re: Trouble implementing a standard library -- Calling C functions fro DrDiettrich1@aol.com (Hans-Peter Diettrich) (2014-03-20) |
Re: Trouble implementing a standard library -- Calling C functions fro alexfrunews@gmail.com (2014-03-19) |
Re: Trouble implementing a standard library -- Calling C functions fro noitalmost@cox.net (noitalmost) (2014-03-21) |
From: | noitalmost <noitalmost@cox.net> |
Newsgroups: | comp.compilers |
Date: | Fri, 21 Mar 2014 14:49:23 -0400 |
Organization: | Compilers Central |
References: | 14-03-049 <fqWX1n00a1AptjU01qWZHX> |
Keywords: | C, code |
Posted-Date: | 22 Mar 2014 00:19:41 EDT |
On Thursday, March 20, 2014 12:41:16 AM alexfrunews@gmail.com wrote:
> In my C compiler I represent C types in a kind of AST that has them
> deconvoluted and straightened out, e.g.:
Yeah, maybe I should do something like that. I need to think about this some
more. I don't think I quite know what I want. I think I need to rework my
genC() methods so that they generate a C-like AST.
> But if you're translating your language into compilable C, you need more
> than just invoking a function. Where do you actually take function
> parameters from? They must be C expressions, containing constants,
> variables, other function calls and operators.
>
> Perhaps, you need to naturally generate C code out of all your expressions
> and other building blocks of your source language? If each of them is
> already parsed into a (sub)tree or a (sub)stack (e.g. containing the
> expression in the Reverse Polish Notation, ready for evaluation or code
> generation), it's not much of a problem and it's likely easier than doing
> the same for the purpose of generating assembly code.
The nodes of my AST are instances of C++ classes. Each node has a (virtual)
genC() method that returns C source code as a string. It returns the code for
itself and all its children. With a lot of details omitted, I have something
like:
class AstNode {
virtual string genC(AstNode *parent);
};
class Expr : public AstNode {
string genC(AstNode *parent);
};
class Call : public Expr {
Call(string name);
void addArg(Expr *arg);
string genC(AstNode *parent);
string m_name; // procedure name
vector<Expr*> m_args;
Type *m_retType; // type checker fills this in
};
string Call::genC(AstNode *parent) {
string s = m_name + "(";
for (arg : m_args) s += arg->genC(this) + ", ";
s += ")";
return s;
}
class SymDef : public AstNode {
// a named symbol, which goes into a symbol table
Type* dataType();
virtual string genCDecl();
};
string SymDef::genCDecl() {
// return C declaration
string s = dataType()->genC(this);
s += " " + m_name;
return s;
// extra stuff to handle arrays has been omitted
}
class ProcDef : public SymDef {
ProcDef(string name, Type *retType, SymTab *parent);
void addParam(VarDef *p);
SymDef* get(string name);
string genC(AstNode *parent);
SymTab m_symTab;
vector<AstNode*> m_stmts;
};
string ProcDef::genC(AstNode *parent) {
string s = m_retType->genC(this);
s += " " + m_name + "(";
for (p : params()) { // for each parameter
s += p->dataType()->genC(this) + " ";
s += p->genC(this) + ", ";
}
s += ") {\n";
for (decl : decls()) { // for each local declaration
// excludes parameters
s += decl->genCDecl(this) + ";\n";
}
for (stmt : stmts()) { // for each statement
s += stmt->genC(this) + ";\n";
}
s += "}\n";
return s;
}
ProcDef is a procedure definition. It has a symbol table of local declarations
(which includes the procedure parameters), and a list of statements.
Each Type is also an AstNode. Int, Float, etc, are predeclared. Static
instances for predeclared types are created at compile time and are in the
global symbol table.
string Type::genC(AstNode *parent) {
if (this == &Int) return "long";
if (this == &Float) return "double";
}
Array, Record, and Pointer derive from Type; Pointers essentially just add "
*", while arrays and records become "char *".
And I just found a bug in my code. I've ignored alignment of record fields in
the translation to intermediate form. :[
Return to the
comp.compilers page.
Search the
comp.compilers archives again.