a simple DSL to generate simple C programs
Alternative title:
A magical DSL to generate C code from CoffeeScript
node-cello is a work-in-progress DSL and template engine for generating C programs.
This is an experimental project, and should be used with care.
For the moment only basic C code can be generated using this library.
The code is a bit messy, and architecture/syntax is not fixed yet.
However it is already on NPM repository because:
- it basically works
- it's a dependency of another project
Thank you for your understanding!
You can pass parameters to cello. For the moment only a few are supported:
- indent: the indentation string to use (eg. " " or "\t")
- debug: some debug messages - for development only
- evaluate: a func which return a list of JS references to interpret BEFORE code generation
- ignore: a func which return a list of JS references to ignore (won't be translated to C)
Example:
src = C(indent: " ", debug: yes) ->
main = ->
Experimental support of gcc is implemented:
{C, run} = require 'cello'
src = C -> main = -> printf "hello world"
run src, (output) -> console.log "output: #{output}"
You can execute a program, and read/write from it, as it was a bi-directional stream:
{C, Program} = require 'cello'
src = C -> main = ->
# put code that reads from STDIN and write to
# STDOUT here (see examples/pipeline.coffee)
program = new Program src
program.run process.argv[1..], ->
# bind to output events
program.on 'stdout', (buff) -> console.log buff.toString()
program.on 'stderr', (buff) -> console.log buff.toString()
program.on 'close', ({code, signal}) -> console.log code
# do stuff
program.write "hello world"
program.close()
{ C, run } = require 'cello'
src = C ->
include 'stdio.h'
int x = 40
main = ->
int y = 43 + x
printf "hello"
# compile & run
run src, console.log
Will generate this code:
#include <stdio.h>
int x = 40;
int main() {
int y = (43 + x);
printf("hello");
return 0;
}
Then it will run and print 'hello'. Magic? yes.
{C, run} = require 'cello'
options =
indent: " "
evaluate: -> [ Math.random, Math.round ]
ignore: -> []
debug: no
src = C(options) ->
include 'stdio.h'
include 'stdlib.h'
int x = 40
main = ->
printf "hello, "
int y = 43 + x / 10
printf "result is %i", y
int a = [ 0, 0, 0, 1, 0 ]
int b[5] = [ 0 ]
float seed = Math.round Math.random() * 1000
#int compute = (a=int, b=int) -> a + b
char p1 = 127
char $p2 = malloc sizeof char
int i = 0
while i < 10000
++i
while i > 10000
i--
0
console.log "#{src}"
run src, (err, output) ->
if err
throw new Error err
else
console.log "#{output}"
will generate:
#include <stdio.h>
#include <stdlib.h>
int x = 40;
int main() {
printf("hello, ");
int y = 43 + x / 10;
printf("result is %i",y);
int a = {0, 0, 0, 1, 0};
int b[5] = {0};
float seed = 926;
char p1 = 127;
char *p2 = malloc(sizeof(char));
int i = 0;
while (i < 10000) {
++i;
}
while (i > 10000) {
i--;
}
return 0;
}
with output:
hello
This demo shows how to communicate with the sub C program:
{C, Program} = require 'cello'
program = new Program C() ->
include 'stdio.h'
int main = ->
setbuf stdout, NULL
char c = fgetc stdin
while c isnt EOF
printf "%c", c
c = fgetc stdin
0
# call the program, here with an empty argument list
program.run [], ->
console.log "demo.program started"
program.write "hello"
program.write "world"
program.close ({code, signal}) -> console.log "closed: #{code}"
program.on 'stdout', (buff) -> console.log "output: " + buff.toString()
program.on 'stderr', (buff) -> console.log "demo.stderr: " + buff.toString()
- support for inline C statements, as lone strings (eg. """(void *) i;""")
- support for Class: http://stackoverflow.com/a/840703
- support for new (either malloc, or just ignore it?, but at least it will feel a bit more natural)
- support for function pointers allocation
- support for &? (altough it's mostly used for func pointers, and it is implicit)
- find a more elegant solution than using 'Void' as alias of 'void'?
- find an elegant solution to support const (which is forbidden in Coffee/JavaScript)
- support typedef
- support struct
- add more doc (eg. the if / while example)
- support for loops (by not translating directly but generating boilerplate)
- support pointer casting
- Type inference (eg. that "i = 0" will convert to "int i = 0")
- Implement ALL C language features
- more unit tests
- more CoffeeScript magic (eg. doing more implicit stuff such as: x = y for x in [0...2])
- just fixed typo and the doc, to have a better page on NPM's website
- added a new Program class
- support for bi-directional communication using unix pipes
- Support for include 'test.h' and include '<stdlib.h>'
- Added support for break and continue
- added support for functions (eg. main) args
- added support for command line args (when calling run())
- fixed a bug with missing parameters in the options
- Added support for "if" expressiion
- Simplified "while" expression
- Support for blocks "{}"
- Added basic unit tests
- Rewrote nearly everything from scratch
- should be f***ing more robust now
- moved debug scripts to /examples
- experimenting with OpenCL kernel generation (yeah for node-evolve!)
Added basic support for:
- array declaration and initialization
- pointers (using $ instead of *)
- while loops
Also fixed a few bugs around
- basic support for gcc compilation and execution
- added some options
- Removed debug console.logs
- forgot to add uglify-js as dependency in the package.json!
- removed useless dependencies in code
- Basic features are supported