I'm trying to work my way through Compilers: Backend to Frontend (and Back to Front Again) by Abdulaziz Ghuloum. It seems abbreviated from what one would expect in a full course/seminar, so I'm trying to fill in the pieces myself.
For instance, I have tried to use his testing framework in the R5RS flavor of DrScheme, but it doesn't seem to like the macro stuff:
src/ghuloum/tests/tests-driver.scm:6:4: read: illegal use of open square bracket
I've read his intro paper on the course, An Incremental Approach to Compiler Construction, which gives a great overview of the techniques used, and mentions a couple of Schemes with features one might want to implement for 'extra credit', but he doesn't mention the Scheme he uses in the course.
Update
I'm still digging into the original question (investigating options such as Petit Scheme suggested by Eli below), but found an interesting link relating to Gholoum's work, so I am including it here.
[Ikarus Scheme](http://en.wikipedia.org/wiki/Ikarus_(Scheme_implementation)) is the actual implementation of Ghuloum's ideas, and appears to have been part of his Ph.D. work. It's supposed to be one of the first implementations of R6RS. I'm trying to install Ikarus now, but the configure script doesn't want to recognize my system's install of libgmp.so, so my problems are still unresolved.
Example
The following example seems to work in PLT 2.4.2 running in DrEd using the Pretty Big
(require lang/plt-pretty-big)
(load "/Users/donaldwakefield/ghuloum/tests/tests-driver.scm")
(load "/Users/donaldwakefield/ghuloum/tests/tests-1.1-req.scm")
(define (emit-program x)
(unless (integer? x) (error "---"))
(emit " .text")
(emit " .globl scheme_entry")
(emit " .type scheme_entry, #function")
(emit "scheme_entry:")
(emit " movl $~s, %eax" x)
(emit " ret")
)
Attempting to replace the require directive with #lang scheme results in the error message
foo.scm:7:3: expand: unbound identifier in module in: emit
which appears to be due to a failure to load tests-driver.scm. Attempting to use #lang r6rs disables the REPL, which I'd really like to use, so I'm going to try to continue with Pretty Big.
My thanks to Eli Barzilay for his patient help.
The language he uses is most likely Chez Scheme. Regardless, the R5RS language in PLT is a pretty strict version of R5RS, with extensions like square brackets throwing errors -- and you may get more mileage using the default #lang scheme language. (Or, if that fails, try and see if you can work with Petit -- the free version of Chez.)
You can see setup instructions for running it here on Ubuntu x86.
The installation download for Petite Scheme are here.
Related
I'm trying to use the racket CLI to run a file but I need a specific language (pretty-big) features to be available and I'm struggling with that.
As far as I know, if I run $ racket <file_name> then it requires the file as a module. In order to do that, I need to add #lang <some_lang> at the top of my file, but I just can't find any equiv to #lang pretty-big. Any idea how to ask for pretty-big this way?
The other option, is to run the code in load-mode (from the racket CLI manual) but on this case I'm getting no results back which obviously isn't good.
Any suggestions?
I know the solution to this will be super easy, just can't find it.
A search of the Racket docs for "pretty big" turned up this result, which says that the module lang/plt-pretty-big corresponds to DrRacket's "Pretty Big" legacy language.
Unfortunately, putting
#lang lang/plt-pretty-big
at the top of your file won't work, because that module doesn't specify a reader. But you can tell it to use the usual S-expression reader by using the s-exp "meta-language" as follows:
#lang s-exp lang/plt-pretty-big
If you want Racket to print out the results of top-level expressions in your file, it looks like the lang/plt-pretty-big language still won't do it, and I don't think there's an easy fix. Consider porting the program to #lang racket, which has that behavior. Or add println around the things you want printed.
(define read-eval-print (sllgen:make-rep-loop "--> "
(lambda (pgm) (eval-program pgm))
(sllgen:make-stream-parser
the-lexical-spec
the-grammar)))
Is anyone familiar with this type of error?
Help please.
You need to use the right language. According to the documentation, it looks like you need to start your source file with #lang eopl:
#lang eopl
(define read-eval-print
(sllgen:make-rep-loop
"--> "
(lambda (pgm)
(eval-program pgm))
(sllgen:make-stream-parser
the-lexical-spec
the-grammar)))
Once you do this, of course, you'll start getting some other errors, e.g., that eval-program isn't defined. If you define a dummy one, e.g.,
(define (eval-program pgm)
(values))
You'll then get an error that
sllgen:make-stream-parser: bad scanner specification in: the-lexical-spec
You'll need to replace that lexical specification with an actual specification, and similarly (I expect, though I didn't explore this far) with the-grammar. The documentation linked above might (or might not) help you out with those. It looks like you can get the code for the book that this is based on, Essentials of Programming Languages, from the book's website.
What really looks the most promising, though, are results like
Environment-Passing Interpreters, Programming Language Essentials, 2nd edition, Appendix: The SLLGEN Parsing System (PDF)
SLLGEN tutorial (PDF)
sllgen source (sllgen.scm) (a somewhat older version)
other sources (I found the above just by searching with Google for sslgen)
I'm trying to implement some of SICP graphic programs in Racket, but there are 2 problems:
When I need to use 'let' I can't use beginner language.
When I try to change language, or open new file while using "advanced" language, I get this error:
module: identifier already imported from a different source
error when I try to load image module by (require 2htdp/image).
What's going on? Also, are there better ways to train with images in Scheme?
It's not clear why you want to use 2htdp/image in the first place. A much more useful package to use would be Neil Van Dyke's SICP Support page, it provides a language with support for the book and includes the graphical language. That should be enough to solve both of your problems.
As Óscar mentions, you are better off with using #lang planet neil/sicp, However, if you want to import somethng that exports identical symbols you can prefix them:
(require (prefix-in hi: 2htdp/image))
Then all exported from that have prefix hi:, eg. (hi:circle 30 "outline" "red"). The colon isn't anything special. The prefix could have been xxx and it would be xxxcircle.
Also, you can only import the symbols you want:
; you only want circle and eclipse
(require (only-in 2htdp/image circle ellipse))
Or you can import everything except some symbols:
; everything except circle and ellipse
(require (except-in 2htdp/image circle))
And there is no reason not using racket or racket/base as language when you know this.
I just started learning a little Scheme, and I'm using Dorai Sitaram's Teach Yourself Scheme in Fixnum Days. In said work it is stated:
Scheme numbers can be integers (eg, 42) ... or complex (2+3i).
Emphasis mine. Note the form.
Using the principles I had been taught so far I tried writing a few different programs that dealt with the different kinds of numbers. I ended up writing this extremely simple snippet to test complex numbers:
(begin
(display 3+4i)
(newline)
)
Testing this on codepad.org (which uses MzScheme) and Ideone.com (which uses guile) worked perfectly.
Now, when I tried it with Chicken Scheme (my local development environment), it compiles fine, but when run, crashes and gives me the error:
Error: unbound variable: 3+4i
Call history:
main.scm:2: 3+4i <--
Apperently there's an unbound variable error, but with my limited Scheme I don't even know what that means (yet.)
Has anyone else experienced this? I know Chicken Scheme is supposed to be pretty standards compliant, and so it seems wierd that it wouldn't support something simple like this. I Googled through their documentation, but I couldn't find anything specific (although I think there is an external complex number library available, so perhaps that's a hint.)
If anyone has any suggestions, they'd be greatly appreciated. Thanks in advance! :)
I believe you need to install the numbers extension for dealing with complex numbers in Chicken Scheme. Do this:
> chicken-install numbers
And don't forget to load it:
(use numbers)
I've got a bunch of "legacy" Guile Scheme code that I want to get running in the Racket Scheme IDE. There appear to be enough differences to make this a non-trivial exercise. (My level of Scheme knowledge is the level to complete the The Little Schemer).
My question is:
What are the differences between Guile Scheme and Standard Scheme (in the Racket IDE)?
In light of these differences, in general, what are the steps I'll need to take to convert some Guile Scheme Code to standard Scheme?
Additional: (happy with divergence between Racket Scheme and R5RS/R6RS) - what I want is to get 'something' to run in the Racket IDE - rather than the Racket language.
If by "Standard Scheme (in the Racket IDE)," you mean the Racket language, i.e., what you get when you prefix your code with #lang racket, then the top four differences to look out for are:
a different module system
a different macro system (depending on how old your code is)
immutable cons-cells (unless you import mutable ones)
no one-armed ifs in Racket (use when)
To port code from Guile to Racket, find out which files are "at the bottom" of your dependencies, i.e., find the files that do not depend on other files.
Open such a file in Racket, add the line #lang racket at the top, and try to run it.
You will most likely encounter some "unbound identifier" errors.
If you are lucky, the function is present in Racket, but not included in the "racket" language. Search for the name in the Racket documentation, and if you find it, then use (require ...) to import the name into your program.
Then run the program again to find the next error.
Some function are named differently in Guile and Racket, so look up the name in the Guile documentation and see what it does. Then open the Racket documentation on the same subject, and see what it is called in Racket.
In some cases you may have to make bigger changes. If you can't find some piece of functionality in the Racket documentation, then try asking the mailing list. It could be that it simply has a different name, or that somebody implemented it and put it on PLaneT (thus it will no appear in the documentation until you have installed the package).
Example of importing srfi/1 into the R5RS language.
#lang r5rs
(#%require srfi/1)
(xcons 1 2)
Differences from R4RS code to modern Scheme?
One thing to look out for is that in R4RS the empty list '() counted as false, not it is interpreted as true.
See this question for more things to look out for:
Running SICP Pattern Matching Rule Based Substitution Code
See also this list of changes from the R5RS standard:
List of changes from R4RS to R5RS