PicoC: A very small C interpreter
github.com
github.com
PicoC runs ok in 64KB although it is a bit cramped. I like that you can write scripts in C on the actual device without needing a host computer of any kind. It's also been fairly popular for embedding as a scripting language in desktop applications, mostly because it's small and easy to integrate. It's really designed for scripting so don't expect it to be fast though.
Basically, I was going to compile fastcomp to js then run the commands emscripten would normally run via "arguments" function in the modules corresponding to the tool I needed (clang, llc, llvm-link and opt IIRC). But I stopped short of getting clang to work correctly with the flags I needed it to use.
I know it's possible I just needed to work around a few system dependencies like posix_spawn. I was going to trace it's use using a macro to replace calls to it with a function that prints the file and line number instead. But I got fed up with the system I was using (Amazon Linux / ssh / tablet) to do all of this on and by extension everything else that has to do with programming or trouble shooting.
One of my goals is to make the entire toolchain rapid to port and hack on. I am pretty sick of gcc and llvm taking 20 mins just to build from source.
I would love to find serious collaborators.
I love C so considered using 8cc as a base for expansion, but there is a reason llvm and gcc are in C++ and not C. I dislike C++ for many logical and illogical reasons, and think Go is a fair compromise with keeping close to C roots.
The code is heavily inspired by https://github.com/rui314/8cc as well as http://bellard.org/tcc/. I recommend studying the source code of 8cc before contributing here, as 8cc is currently far more mature.
That sounds very condescending and off-putting.
edit: I have tweaked the readme, don't let it put you off
0: http://pp.ipd.kit.edu/firm/ 1: https://github.com/MatzeB/cparser
Unfortunately, function pointers aren't supported, and it's 10x slower than equivalent compiled C, if not more, and perhaps slower than Lua (and we aren't even talking about LuaJIT). There also appear to be some issues yet to be dealt with, as can be seen on the previous project page at Google Code: https://code.google.com/p/picoc/issues/list
Not Lua itself, but at least Luajit's FFI does: http://luajit.org/ext_ffi.html
I stopped using the file name at all in my include guards a few years ago, and use a GUID instead. For example:
#ifndef HEADER_6AFF21D71B5B43DEB079AA612E4118B4
#define HEADER_6AFF21D71B5B43DEB079AA612E4118B4
#endif//HEADER_6AFF21D71B5B43DEB079AA612E4118B4
Also consider the use of #pragma once - though as far as I can tell, this (still) isn't ISO, so I've decided to avoid it.Depends on your target platform. GCC, clang/LLVM, Visual C++, and many proprietary compilers all support it. What platform are you targeting that doesn't support it?
Because if you're writing any non-trivial useful code, it's highly likely that your code is not pure ISO C; you're using some library with support for various platforms, or a system call interface, or some other interface to a real system. Once you do that, universal portability no longer applies, so you might as well think about which specific target platforms you care about.
The other factor is that the code as it stands is designed to be as readable as possible. I'm conscious that prefixing every identifier with "PicoC" will make the whole thing a bit less easy to read. I'm not sure if maximising readability is something that people really care about though. I'd be interested in hearing people's opinions on whether they'd prefer "struct ValueType" or "struct PicoCValueType" in a thousand places throughout the code.
It was relatively complete K&R C except for no floating point support. It comfortably ran in under 64K bytes of memory. That's 64 kilobytes, or as they now say kibibytes!
It was quite fast to compile. It was also quite fast to run, since it generated true object code, no run-time interpreter needed.
It's now open source and public domain. http://www.bdsoft.com/resources/bdsc.html
It's (of course) less complete than PicoC, but it might be the single most useful introduction to compiler construction I've read.
It's written in a very limited dialect of C --- most notably, it doesn't use structs --- because it compiles itself. The expression parser in particular would be clearer with structs rather than array offsets. But once you realize that's why it's so gnarly in places, it's straightforward to mentally translate.
It's a very simple design: a simple lexer with a "pull" API (next()) feeds a precedence-climbing expression parser that spits out bytecode for a simple stack machine.
If you grok expr(), you grok the whole thing.
I wish I had this back in the day when I first learnt C and was doing all this by hand with pencil and paper. The VCR-style rewind is a nice touch.
The "peacock" interpretation is funny and went unnoticed by me. Cheers!
Hmm, someone tried to resurrect it on SourceForge a couple of years ago, it seems, but it's dead again.
http://sourceforge.net/projects/eic/
Someone threw it on GitHub:
https://github.com/kungfooman/EiC-C-Interpreter
PDF of doc [2009]:
http://www.mirrorservice.org/sites/downloads.sourceforge.net...
No pointers to functions, I see.. not nitpicking, just playing :) I like what you've done here. I'm going to have to go through the code and hopefully learn something new.