This forum is closed to new posts due to low activity and a deluge of spam. It is kept online as a static historical record. If you want to read about or discuss esoteric programming languages, the Esolang wiki is the place to go. An archive of the forum is available.

csexp (5)

1 Name: RatFucker!!zuL1K2Ii : 2007-10-19 19:06 ID:f+swvqM8

I think I'll use this forum to post my ideas about my version of C in which the source code is written with s-expressions. If someone happens to reply with something I don't like, I'll just call them an idiot and ignore them. Warned.

So I've written some really basic parser in Scheme which you pass a list of s-expressions and from that it produces C code.

[u]Example:[/u]

[code](c->string '(printf "Number: %d" (+ 2 54)) #t) →
printf("%d", (2+54));[/code]

(The [code]#t[/code] parameter is just some flag to say whether the expression needs a [code];[/code] or whether it's a subexpression.)

[u]Semantics[/u]

The semantics are no different than C. The essence of this project is to change the syntax of C, while retaining the low-level semantics.

[u]Syntax[/u]

The syntax is essentially a straight conversion from sexprs to C syntax. The advantage to all this is that we can now write macros that manipulate the source code as lists. The macro language is simply Scheme. Your csexp code is passed as a list to some Scheme function which plays with it and returns a new list of csexp code. It's pretty straight-forward, but here's an example:

[b]Input:[/b]
[code]
(defmacro (with-drawing-context forms)
(let ((hdc (caar forms))

    (hwnd (cadar forms))
(ps (caddar forms))
(body (cadr forms)))
`(block
(declare (HDC ,hdc))
(declare (PAINTSTRUCT ,ps))
(set! ,hdc (BeginPaint ,hwnd (address-of ,ps)))
(begin ,body)
(EndPaint ,hwnd (address-of ,ps)))))

(with-drawing-context (hdc hwnd ps)
(Rectangle hdc 0 0 50 50))
[/code]
(The whole of this example is passed as a list to the parser.)

[b]Output:[/b]
[code]
{
HDC hdc;
PAINTSTRUCT ps;
hdc = BeginPaint(hwnd, (&ps));
Rectangle(hdc, 0, 0, 50, 50);
EndPaint(hwnd, (&ps));
}
[/code]

The parser first recognises defmacro and then creates a Scheme closure from the body of the macro and stores it in a Scheme hashtable of macros (the name being the key, of course).

Then, when it comes across [code]with-drawing-context[/code] and recognises that this is a macro in the macros hashtable, the rest of the s-expression is passed to the Scheme closure to return some new csexp source code to be parsed again, eventually producing the above output.

[u]Conclusion[/u]

All of the above works. It's a pretty damn easy thing to write. Now I am considering implementing some high-level things as if they were built into the C language, using syntactic abstraction. Some things I might try are; in-built lists, and resultingly, rudimentary gargage collection; objects with multiple inheritance; or whatever else I feel like trying. I haven't given much thought to these, yet. I'll try simple ref-count-based garbage collection first.

2 Name: RatFucker!!zuL1K2Ii : 2007-10-19 19:07 ID:f+swvqM8

Oh, no BBCode. Lame.

3 Name: RatFucker!!zuL1K2Ii : 2007-10-19 19:10 ID:f+swvqM8

I'll try again.

4 Name: RatFucker!!zuL1K2Ii : 2007-10-19 19:18 ID:f+swvqM8

So I've written some really basic parser in Scheme which you pass a list of s-expressions and from that it produces C code.

Example:

 (c->string '(printf "Number: %d" (+ 2 54)) #t) →
printf("%d", (2+54));

(The #t parameter is just some flag to say whether the expression needs a ; or whether it's a subexpression.)

Semantics

The semantics are no different than C. The essence of this project is to change the syntax of C, while retaining the low-level semantics.

Syntax

The syntax is essentially a straight conversion from sexprs to C syntax. The advantage to all this is that we can now write macros that manipulate the source code as lists. The macro language is simply Scheme. Your csexp code is passed as a list to some Scheme function which plays with it and returns a new list of csexp code. It's pretty straight-forward, but here's an example:

Input:

 (defmacro (with-drawing-context forms)
(let ((hdc (caar forms))

(hwnd (cadar forms))
(ps (caddar forms))
(body (cadr forms)))
`(block
(declare (HDC ,hdc))
(declare (PAINTSTRUCT ,ps))
(set! ,hdc (BeginPaint ,hwnd (address-of ,ps)))
(begin ,body)
(EndPaint ,hwnd (address-of ,ps)))))
 (with-drawing-context (hdc hwnd ps)
(Rectangle hdc 0 0 50 50))

(The whole of this example is passed as a list to the parser.)

Output:

 {
HDC hdc;
PAINTSTRUCT ps;
hdc = BeginPaint(hwnd, (&ps));
Rectangle(hdc, 0, 0, 50, 50);
EndPaint(hwnd, (&ps));
}

The parser first recognises defmacro and then creates a Scheme closure from the body of the macro and stores it in a Scheme hashtable of macros (the name being the key, of course).

Then, when it comes across with-drawing-context and recognises that this is a macro in the macros hashtable, the rest of the s-expression is passed to the Scheme closure to return some new csexp source code to be parsed again, eventually producing the above output.

Conclusion

All of the above works. It's a pretty damn easy thing to write. Now I am considering implementing some high-level things as if they were built into the C language, using syntactic abstraction. Some things I might try are; in-built lists, and resultingly, rudimentary gargage collection; objects with multiple inheritance; or whatever else I feel like trying. I haven't given much thought to these, yet. I'll try simple ref-count-based garbage collection first.

5 Name: Anonymous : 2007-10-20 04:05 ID:sUks/g9Q

Thanks for posting!

Name: Link:
Leave these fields empty (spam trap):
More options...
Verification: