This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
geda:gnetlist_scheme_tutorial [2012/02/20 15:14] 127.0.0.1 external edit |
geda:gnetlist_scheme_tutorial [2015/10/17 17:53] (current) svennb |
||
---|---|---|---|
Line 1: | Line 1: | ||
+ | //Translations of this page are also available in the following languages:// [[gnetlist_scheme_tutorial.ru|Русский]]. | ||
+ | |||
====== Scripting a gnetlist backend in Scheme ====== | ====== Scripting a gnetlist backend in Scheme ====== | ||
**by John Doty** | **by John Doty** | ||
- | (this was [[http://archives.seul.org/geda/user/Jul-2009/msg00235.html|originally posted]] to the gEDA-user mailing list in July 2009) | + | (this was [[http://archives.seul.org/geda/user/Jul-2009/msg00235.html|originally posted]] to the gEDA-user mailing list in July 2009) |
Don't Panic! | Don't Panic! | ||
- | If you've never written a program in Lisp, it looks daunting. But it's a lot easier than it looks. Wrap a little bit of "syntactic | + | If you've never written a program in Lisp, it looks daunting. But it's a lot easier than it looks. Wrap a little bit of "syntactic |
sugar" around Lisp, and it becomes Logo, which elementary school children can learn. | sugar" around Lisp, and it becomes Logo, which elementary school children can learn. | ||
- | And, just to make it clear what some of the funny words mean, [[wp>Lisp_(programming_language)|Lisp]] is a computer language, [[wp>Scheme_(programming_language)|Scheme]] is a dialect of Lisp, and [[wp>GNU_Guile|Guile]] is an | + | And, just to make it clear what some of the funny words mean, [[wp>Lisp_(programming_language)|Lisp]] is a computer language, [[wp>Scheme_(programming_language)|Scheme]] is a dialect of Lisp, and [[wp>GNU_Guile|Guile]] is an |
- | implementation of Scheme. Guile is used for "scripting" gEDA. In particular, the gnetlist front end, written in C, extracts topology | + | implementation of Scheme. Guile is used for "scripting" gEDA. In particular, the gnetlist front end, written in C, extracts topology |
and attribute information from schematics, and then presents that data to "back end" Guile scripts for processing and output. | and attribute information from schematics, and then presents that data to "back end" Guile scripts for processing and output. | ||
- | This tutorial is specifically about programming gnetlist back ends in Scheme. If you don't already know Scheme, you should probably look at | + | This tutorial is specifically about programming gnetlist back ends in Scheme. If you don't already know Scheme, you should probably look at |
other material too, such as: | other material too, such as: | ||
Line 29: | Line 31: | ||
OK, let's get started. Here's a particularly simple back end: | OK, let's get started. Here's a particularly simple back end: | ||
- | <code scheme> | + | <code lisp> |
;; gnetlist development playground | ;; gnetlist development playground | ||
Line 40: | Line 42: | ||
</code> | </code> | ||
- | To use this, put it in a file called ''gnet-devel.scm''. Copy this file | + | To use this, put it in a file called ''gnet-devel.scm''. Copy this file |
- | to wherever gnetlist Scheme files are kept on your system. On the | + | to wherever gnetlist Scheme files are kept on your system. On the |
machine I'm using today, the command is: | machine I'm using today, the command is: | ||
Line 70: | Line 72: | ||
You should see: | You should see: | ||
- | <code scheme> | + | <code lisp> |
("Q3" "R5" "Q2" "R4" "Q1" "C6" "R3" "L2" "A1" "bat(+3v)" "lamp(1)" "R2" "C5" "L1" "R1" "C4" "lamp(2)" "C3" "C2" "C1" "D1" "bat(0v)" "R7" "Q4" "R6") | ("Q3" "R5" "Q2" "R4" "Q1" "C6" "R3" "L2" "A1" "bat(+3v)" "lamp(1)" "R2" "C5" "L1" "R1" "C4" "lamp(2)" "C3" "C2" "C1" "D1" "bat(0v)" "R7" "Q4" "R6") | ||
</code> | </code> | ||
- | ''"packages"'' is a handy variable, containing a list of all unique ''"refdes="'' attribute values. By typing it, you fed it to the "REPL", | + | ''"packages"'' is a handy variable, containing a list of all unique ''"refdes="'' attribute values. By typing it, you fed it to the "REPL", |
the Read, Evaluate, Print Loop. So, the REPL read it, evaluated it (getting a list), and printed it. | the Read, Evaluate, Print Loop. So, the REPL read it, evaluated it (getting a list), and printed it. | ||
Line 84: | Line 86: | ||
</code> | </code> | ||
- | What happened here? Here, the REPL evaluated the list | + | What happened here? Here, the REPL evaluated the list |
- | <code scheme> | + | <code lisp> |
(length packages) | (length packages) | ||
</code> | </code> | ||
Line 112: | Line 114: | ||
The readline stuff in our ''gnet-devel.scm'' back end allows you to use the cursor keys on your keyboard to move around through the history and edit input. Very handy when interacting. Try it. | The readline stuff in our ''gnet-devel.scm'' back end allows you to use the cursor keys on your keyboard to move around through the history and edit input. Very handy when interacting. Try it. | ||
- | Another useful variable gnetlist defines is ''"all-unique-nets"'' (type it). Just as ''"(length packages)"'' tells you how many packages you | + | Another useful variable gnetlist defines is ''"all-unique-nets"'' (type it). Just as ''"(length packages)"'' tells you how many packages you |
have, ''"(length all-unique-nets)"'' will tell you how many nets you have. | have, ''"(length all-unique-nets)"'' will tell you how many nets you have. | ||
Line 145: | Line 147: | ||
(apply p x) calls procedure p once, with all of the elements of x as arguments. So the expression above winds up evaluating: | (apply p x) calls procedure p once, with all of the elements of x as arguments. So the expression above winds up evaluating: | ||
- | <code scheme> | + | <code lisp> |
(+ 3 3 2 2 2 2 2 2 2 2 2 2 2 2 1 1 2 3 3 1 2 3 2 1 1) | (+ 3 3 2 2 2 2 2 2 2 2 2 2 2 2 1 1 2 3 3 1 2 3 2 1 1) | ||
</code> | </code> | ||
Line 171: | Line 173: | ||
Now we can put our statistics collection together into a back end. First, define a procedure to write a line of output: | Now we can put our statistics collection together into a back end. First, define a procedure to write a line of output: | ||
- | <code scheme> | + | <code lisp> |
(define format-line | (define format-line | ||
(lambda (name value) | (lambda (name value) | ||
Line 183: | Line 185: | ||
We're using two new builtin procedures here, ''"display"'' and ''"newline"'', which should be self-explanatory. Now: | We're using two new builtin procedures here, ''"display"'' and ''"newline"'', which should be self-explanatory. Now: | ||
- | <code scheme> | + | <code lisp> |
(define display-stats | (define display-stats | ||
(lambda () ; no arguments | (lambda () ; no arguments | ||
Line 202: | Line 204: | ||
To finish off a back end, we need a "main program". By convention, that has the name of the back end. It has the responsibility of opening the output file, too. So, for a "stats" back end for collecting the stats, the entire file looks like: | To finish off a back end, we need a "main program". By convention, that has the name of the back end. It has the responsibility of opening the output file, too. So, for a "stats" back end for collecting the stats, the entire file looks like: | ||
- | <code scheme> | + | <code lisp> |
;; gnetlist back end for extracting design statistics | ;; gnetlist back end for extracting design statistics | ||
;; | ;; | ||
Line 235: | Line 237: | ||
</code> | </code> | ||
- | Put this in a file named ''gnet-stats.scm'', copy it to where it belongs with something like | + | Put this in a file named ''gnet-stats.scm'', copy it to where it belongs with something like |
<code bash> | <code bash> | ||
$ sudo cp gnet-stats.scm /sw/share/gEDA/scheme/ | $ sudo cp gnet-stats.scm /sw/share/gEDA/scheme/ | ||
</code> | </code> | ||
- | and then ''"gnetlist -g stats"'' followed by the usual other arguments and schematic pathnames will put your design's statistics in the | + | and then ''"gnetlist -g stats"'' followed by the usual other arguments and schematic pathnames will put your design's statistics in the |
output file (default ''output.net''). | output file (default ''output.net''). | ||
- | Pretty easy, huh? Useful, too. Lately I've been designing systems that consist of stacks of boards: statistics like these are helpful | + | Pretty easy, huh? Useful, too. Lately I've been designing systems that consist of stacks of boards: statistics like these are helpful |
in figuring out which subsystems I should combine on each board. | in figuring out which subsystems I should combine on each board. | ||
+ | ====== See also ====== | ||
+ | |||
+ | * [[geda:guile_scripting]] | ||
+ | * [[geda:gnetlist_scheme_primitives]] | ||