Commit ab41c5db authored by Pascal J. Bourguignon's avatar Pascal J. Bourguignon

Some cleanup in linc.

parent fb1ba629
c-syntax
A layer of CLOS classes to generate C++ syntax.
Also, we could have a C++ parser producing a parse tree using these
objects.
Note: identical terminals or non-terminals may correspond to
different C-syntax classes, depending on their use in
production:
(char*)42 * --> pointer
4*2 * --> times
*str * --> deref
char *a; * --> defptr ?
c-sexp
A S-expr syntax for C++ code. Parsing (evaluating?) these
S-expressions will produce a C-syntax object tree.
linc
Mon Jul 2 19:28:51 CEST 2012
This project is published as-is.
It is far from finished.
Tue Oct 4 16:14:25 CEST 2005
Let's start a linc project.
LINC IS NOT C
=============
Well, almost not.
The objective is to be able to write programs in a lisp environment
that will be generated as C sources, human readable and human
maintenable, with no obvious hint of being generated from a lisp
environment.
Scheme to C: http://www-swiss.ai.mit.edu/~jaffer/Docupage/schlep.html
C# pretty-printer: http://depni.sinp.msu.ru/~ivan_iv/lisp/sharpclass.lisp
LinJ: http://www.evaluator.pt/linj.html
http://www.evaluator.pt/downloads/tutorial.html
git clone https://github.com/xach/linj
SC: http://super.para.media.kyoto-u.ac.jp/~tasuku/sc/index-e.html
~/src/lisp/src/sc080709b
CLiCC http://www.cliki.net/CLiCC starts from:
;;---------------------------------------------------------------------
;; TAILP sublist list
;;---------------------------------------------------------------------
(defun tailp (sublist list)
(cond
((eql sublist list) t)
((atom list) nil)
(t (tailp sublist (cdr list)))))
and generates:
void Ftailp(CL_FORM *base)
{
M1_1:;
if(EQL(ARG(0), ARG(1)))
{
LOAD_SYMBOL(SYMBOL(Slisp, 48), ARG(0)); /* T */
}
else
{
if(CL_ATOMP(ARG(1)))
{
LOAD_NIL(ARG(0));
}
else
{
COPY(GET_CDR(ARG(1)), ARG(2));
COPY(ARG(2), ARG(1));
goto M1_1;
}
}
goto RETURN1;
RETURN1:;
}
We want to generate something like:
/*---------------------------------------------------------------------*/
/* TAILP sublist list */
/*---------------------------------------------------------------------*/
bool tailp(object_t* sublist,object_t* list){
if(sublist==list){
return(true);
}else if(atom(list)){
return(false);
}else{
return(tailp(sublist,list_rest((list_t*)list)));
}
}
Or, starting from:
(defun fact (x)
(if (<= x 1)
1
(* x (fact (1- x)))))
we want to generate something like:
unsigned int fact(unsigned int x){
if(x<=1){
return(1);
}else{
return(x*fact(x-1));
}
}
A good thing in CLiCC: it defines a Common Lisp subset translatable to C.
This subset could be a upper bound for our project.
MODULES
=======
Let's start with a bottom up approach.
First we define a s-expr syntax for C, with a direct generation to C.
Then we remove progressively more and more C from it, implementing at
the same time the translator:
- type inference to remove the need for most declarations.
- mapping of packages to source files, or definition of a module construct.
- FFI with Verrazano http://common-lisp.net/project/fetter/
URLs
====
http://www.unmutual.info/software/scexp/scexp-0.9.tar.gz
......@@ -6,7 +6,7 @@
;;;;USER-INTERFACE: NONE
;;;;DESCRIPTION
;;;;
;;;; This file defines classes to generate C++ syntax.
;;;; This file defines classes to generate C syntax.
;;;;
;;;;AUTHORS
;;;; <PJB> Pascal J. Bourguignon <pjb@informatimago.com>
......@@ -53,24 +53,23 @@
(defvar *indent* 0)
(defvar *naked* t)
(let ((bol t))
(defun emit (&rest args)
(loop
:for arg :in args
:do (cond
((eq :newline arg)
(terpri *c-out*)
(setf bol t))
((eq :fresh-line arg)
(unless bol
(terpri *c-out*)
(setf bol t)))
(t
(if bol
(format *c-out* "~VA~A" (* *indent* 4) "" arg)
(princ arg *c-out*))
(setf bol nil))))))
(defvar *bol* t)
(defun emit (&rest args)
(loop
:for arg :in args
:do (cond
((eq :newline arg)
(terpri *c-out*)
(setf *bol* t))
((eq :fresh-line arg)
(unless *bol*
(terpri *c-out*)
(setf *bol* t)))
(t
(if *bol*
(format *c-out* "~VA~A" (* *indent* 4) "" arg)
(princ arg *c-out*))
(setf *bol* nil)))))
(defmacro with-indent (&body body)
......@@ -603,26 +602,16 @@ exclusive, but one must be given when :arguments is not given.")
(expr-predecr 1 "--")
(expr-lognot 1 "!")
(expr-bitnot 1 "~")
(expr-deref 1 "*")
(expr-address 1 "&")
(expr-pos 1 "+")
(expr-neg 1 "-")
(expr-sizeof 1
(lambda (argument)
(emit "sizeof") (with-parens "()" (generate argument))))
(expr-new 1
(lambda (argument)
(emit "new" " ") (generate argument)))
(expr-new[] 1
(lambda (argument)
(emit "new" "[]" " ") (generate argument)))
(expr-delete 1
(lambda (argument)
(emit "delete" " ") (generate argument)))
(expr-delete[] 1
(lambda (argument)
(emit "delete" "[]" " ") (generate argument)))
(cpp-stringify 1 "#"))
(expr-deref 1 (lambda (argument) (with-parens "()" (emit "*") (with-parens "()" (generate argument)))))
(expr-address 1 (lambda (argument) (with-parens "()" (emit "&") (with-parens "()" (generate argument)))))
(expr-pos 1 (lambda (argument) (with-parens "()" (emit "+") (with-parens "()" (generate argument)))))
(expr-neg 1 (lambda (argument) (with-parens "()" (emit "-") (with-parens "()" (generate argument)))))
(expr-sizeof 1 (lambda (argument) (emit "sizeof") (with-parens "()" (generate argument))))
(expr-new 1 (lambda (argument) (emit "new" " ") (generate argument)))
(expr-new[] 1 (lambda (argument) (emit "new" "[]" " ") (generate argument)))
(expr-delete 1 (lambda (argument) (emit "delete" " ") (generate argument)))
(expr-delete[] 1 (lambda (argument) (emit "delete" "[]" " ") (generate argument)))
(cpp-stringify 1 "#"))
(:post
(expr-postincr 1
(lambda (expr)
......@@ -650,7 +639,7 @@ exclusive, but one must be given when :arguments is not given.")
(when (rest expressions)
(generate
(make-instance 'expr-callargs
:arguments (rest expressions))))))))))
:arguments (rest expressions))))))))))
(:left
(absolute-scope 1
(lambda (name) (emit "::") (generate name))))
......@@ -758,7 +747,7 @@ exclusive, but one must be given when :arguments is not given.")
(defun ,cl-name (&rest args)
(apply (function make-instance) ',cl-name
(loop
(loop
:for key :in (initargs-in-order ',cl-name)
:for val :in args
:nconc (list key val))))))
......
......@@ -33,7 +33,7 @@
;;;;**************************************************************************
(cl:in-package :com.informatimago.linc.c)
(cl:in-package :com.informatimago.languages.linc.c)
(cl:defpackage :bc-mem
(:use)
......@@ -43,6 +43,7 @@
n-data
copy
n-length))
(declare-function '(bc-mem:allocate
bc-mem:deallocate
bc-mem:copy))
......
This diff is collapsed.
This diff is collapsed.
......@@ -33,17 +33,21 @@
;;;;**************************************************************************
(eval-when (:compile-toplevel :load-toplevel :execute)
(setf *readtable* (copy-readtable nil)))
(defpackage "COM.INFORMATIMAGO.LANGUAGES.LINC.C"
(:nicknames "COM.INFORMATIMAGO.LANGUAGES.LINC.C++")
(:use))
(defpackage "COM.INFORMATIMAGO.LANGUAGES.LINC"
(:use "COMMON-LISP"
"COM.INFORMATIMAGO.COMMON-LISP.CESARUM.UTILITY"
"COM.INFORMATIMAGO.COMMON-LISP.CESARUM.LIST"
"COM.INFORMATIMAGO.COMMON-LISP.CESARUM.STRING"
"COM.INFORMATIMAGO.COMMON-LISP.CESARUM.SYMBOL"
"COM.INFORMATIMAGO.COMMON-LISP.LISP-SEXP.SOURCE-FORM")
(:shadow "DECLARATION" "THROW")
(:export
"COMPILE-LINC-FILE"))
(defpackage "COM.INFORMATIMAGO.LANGUAGES.LINC.C"
(:nicknames "COM.INFORMATIMAGO.LANGUAGES.LINC.C++")
(:use))
;;;; THE END ;;;;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment