Path: csiph.com!v102.xanadu-bbs.net!xanadu-bbs.net!feeder.erje.net!us.feeder.erje.net!news.linkpendium.com!news.linkpendium.com!news.iecc.com!.POSTED!nerds-end From: noitalmost Newsgroups: comp.compilers Subject: Trouble implementing a standard library -- Calling C functions from within my language Date: Wed, 19 Mar 2014 18:28:13 -0400 Organization: Compilers Central Lines: 41 Sender: news@iecc.com Approved: comp.compilers@iecc.com Message-ID: <14-03-049@comp.compilers> NNTP-Posting-Host: news.iecc.com Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Trace: miucha.iecc.com 1395274395 77973 2001:470:1f07:1126:0:676f:7373:6970 (20 Mar 2014 00:13:15 GMT) X-Complaints-To: abuse@iecc.com NNTP-Posting-Date: Thu, 20 Mar 2014 00:13:15 +0000 (UTC) Keywords: code, question Posted-Date: 19 Mar 2014 20:13:14 EDT X-submission-address: compilers@iecc.com X-moderator-address: compilers-request@iecc.com X-FAQ-and-archives: http://compilers.iecc.com Xref: csiph.com comp.compilers:1171 I need some small-scale examples, like a toy compiler would do if it needed access to some libc functions. Let's say I have a module (library) called Std that provides procedure ln (x : float) float; procedure open(fname : string; mode : int) int; procedure read(fd : int; buf : ^byte; cnt : int) bool; On a Linux system, I want to just wrap the libc functions double log(double x); int open(const char *fname, int mode); ssize_t read(int fd, void *buf, int cnt); In prior projects, I always output assembly and just did system calls. This time it's different. First, I have an intermediate form that can produce C source code. Second, I want to be able to access functions (say from math.h) that aren't Linux system calls. I don't think the intermediate form matters for this discussion. It can be assumed that module Std gets parsed into an AST, and that I can walk the AST to generate C code. How is this usually handled? I could put a CCall node in my AST and have the parser recognize procedure ln (x : float) : return CCall( ln, x ); end ln; And then have class CCall : public Expr { CCall(string name, vector params); string genC(); ... } where, Expr is a AstNode. But CCall::genC() would be a really complicated list of special cases. Maybe I also need to pass the C return type and the C types of the parameters? And I'm on my way toward an Ada-style foreign-function interface. Eek! Isn't there a simpler way?