├── test
└── com
│ └── github
│ └── chungkwong
│ └── jschememin
│ ├── to_include.scm
│ ├── lib-dec.scm
│ ├── lib-content.scm
│ ├── EmbedTest.java
│ ├── SchemeAssert.java
│ └── lib-example.scm
├── doc
├── .gitignore
├── checkindex.sh
├── repository.tex
├── Makefile
├── genstdmod.pl
├── features.tex
├── r7rs.tex
├── r7rs-ebook.tex
├── overview.tex
├── extract.scm
└── example.tex
├── .gitignore
├── manifest.mf
├── src
└── com
│ └── github
│ └── chungkwong
│ └── jschememin
│ ├── lib
│ ├── null.scm
│ ├── hashtables_derive.scm
│ ├── file_derive.scm
│ ├── case-lambda.scm
│ ├── NativeProcedure.java
│ ├── Lazy.java
│ ├── jschememin_derive.scm
│ ├── REPL.java
│ ├── lazy.scm
│ ├── Read.java
│ ├── Time.java
│ ├── Eval.java
│ ├── cxr.scm
│ ├── NativeEvaluable.java
│ ├── NativeEvaluableMulti.java
│ ├── Complex.java
│ ├── NativeProcedureDefault.java
│ ├── JSchemeMin.java
│ ├── Write.java
│ ├── SimpleLibrary.java
│ ├── ProcessContext.java
│ ├── Load.java
│ ├── File.java
│ ├── Inexact.java
│ ├── r5rs.scm
│ ├── Char.java
│ ├── HashTable.java
│ └── NativeLibrary.java
│ ├── Token.java
│ ├── HELP
│ ├── Primitive.java
│ ├── DatumLabelSrc.java
│ ├── DatumLabelRef.java
│ ├── type
│ ├── ScmPairOrNil.java
│ ├── ScmNumber.java
│ ├── ScmNil.java
│ ├── ScmEndOfFileObject.java
│ ├── ScmObject.java
│ ├── ScmUniqueSymbol.java
│ ├── ScmBoolean.java
│ ├── ScmSymbol.java
│ ├── ScmPort.java
│ ├── ScmListBuilder.java
│ ├── ScmComplexPolar.java
│ ├── ScmComplexRectangular.java
│ ├── ScmRecord.java
│ ├── ObjectPair.java
│ ├── ScmNormalReal.java
│ ├── ScmProcedure.java
│ ├── ScmBinaryOutputPort.java
│ ├── DatumRecord.java
│ ├── ScmError.java
│ ├── ScmPair.java
│ └── ScmBinaryInputPort.java
│ ├── LibraryLoader.java
│ ├── LexicalException.java
│ ├── primitive
│ ├── UncaughtExceptionError.java
│ ├── Quote.java
│ ├── Eval.java
│ ├── SyntaxRule.java
│ ├── Lambda.java
│ ├── CallWithValues.java
│ ├── WithExceptionHandler.java
│ ├── Assignment.java
│ ├── RaiseContinuable.java
│ ├── Apply.java
│ ├── Raise.java
│ ├── If.java
│ ├── DefineValues.java
│ ├── CallWithCurrentContinuation.java
│ ├── Include.java
│ ├── Define.java
│ ├── DefineRecordType.java
│ ├── DynamicWind.java
│ └── Import.java
│ ├── SyntaxException.java
│ ├── SimpleToken.java
│ ├── BasicConstruct.java
│ ├── DatumLabel.java
│ ├── Feature.java
│ ├── Evaluable.java
│ ├── Main.java
│ ├── JavaEnvironment.java
│ ├── Evaluator.java
│ ├── Library.java
│ ├── SchemeEnvironment.java
│ ├── EvaluatorFactory.java
│ ├── Environment.java
│ └── LibraryManager.java
├── nbproject
├── genfiles.properties
├── project.xml
└── project.properties
└── pom.xml
/test/com/github/chungkwong/jschememin/to_include.scm:
--------------------------------------------------------------------------------
1 | 12
--------------------------------------------------------------------------------
/doc/.gitignore:
--------------------------------------------------------------------------------
1 | *.pdf
2 | *.aux
3 | *.idx
4 | *.toc
5 | *.log
6 | *.out
7 |
--------------------------------------------------------------------------------
/test/com/github/chungkwong/jschememin/lib-dec.scm:
--------------------------------------------------------------------------------
1 | (export x)
2 | (export y)
--------------------------------------------------------------------------------
/test/com/github/chungkwong/jschememin/lib-content.scm:
--------------------------------------------------------------------------------
1 | (define y 3)
2 | (define x 4)
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /dist/
2 | /build/
3 | /manifest.mf
4 | /.jacocoverage
5 | jacoco*
6 | /nbproject/private/
--------------------------------------------------------------------------------
/manifest.mf:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | X-COMMENT: Main-Class will be added automatically by build
3 |
4 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/lib/null.scm:
--------------------------------------------------------------------------------
1 | (define-library (scheme null)
2 | (import (scheme base))
3 | (export and begin case cond define define-syntax delay do if lambda let let* let-syntax letrec letrec-syntax
4 | or quasiquote quote set!))
--------------------------------------------------------------------------------
/nbproject/genfiles.properties:
--------------------------------------------------------------------------------
1 | build.xml.data.CRC32=bfe0352b
2 | build.xml.script.CRC32=622d1762
3 | build.xml.stylesheet.CRC32=8064a381@1.75.2.48
4 | # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
5 | # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
6 | nbproject/build-impl.xml.data.CRC32=bfe0352b
7 | nbproject/build-impl.xml.script.CRC32=ff24281b
8 | nbproject/build-impl.xml.stylesheet.CRC32=830a3534@1.80.1.48
9 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/lib/hashtables_derive.scm:
--------------------------------------------------------------------------------
1 | (import (scheme base))
2 | (import (scheme case-lambda))
3 | (define make-eq-hashtable
4 | (case-lambda
5 | (() (make-hashtable equal-hash eq?))
6 | ((k) (make-hashtable equal-hash eq? k))))
7 | (define make-eqv-hashtable
8 | (case-lambda
9 | (() (make-hashtable equal-hash eqv?))
10 | ((k) (make-hashtable equal-hash eq? k))))
11 | (define (hashtable-update! hashtable key proc default)
12 | (hashtable-set! hashtable key (proc (hashtable-ref hashtable key default))))
--------------------------------------------------------------------------------
/nbproject/project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | org.netbeans.modules.java.j2seproject
4 |
5 |
6 | JSchemeMin
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/doc/checkindex.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Diff the `tt' entries (identifiers) in the generated index.tex
4 | # (excepting certain special cases like library declarations) with the
5 | # identifiers in the library index, to verify they agree.
6 |
7 | diff <(perl -ne 'print if s/^\\item{\\tt{\\?([^{} ]*)}.*$/\1/' index.tex \
8 | | grep -E -v "^([!',.;?\`]|->|,@|body|catch|except|define-library|export|include-library-declarations|nil|only|prefix|rename|setcar|car-internal)\$" | sort -u) \
9 | <(./genstdmod.pl --list < stdmod-raw.tex | sort -u | egrep -v 'exact->inexact|inexact->exact') \
10 | && echo "Library and identifier indexes are consistent."
11 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/Token.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong
3 | *
4 | * This program is free software; you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation; either version 3 of the License, or (at
7 | * your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | */
15 | package com.github.chungkwong.jschememin;
16 |
17 | /**
18 | * The interface for lexer token
19 | * @author Chan Chung Kwong <1m02math@126.com>
20 | */
21 | public interface Token{
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/HELP:
--------------------------------------------------------------------------------
1 | Available commands:
2 | step
3 | Move to the next execution state
4 | step in
5 | If a expression is going to be executed, move to the execution state just before a subexpression is evaluated
6 | step over
7 | If a expression is going to be executed, move to the execution state just after the expression is evaluated
8 | run
9 | Move to the first execution state that a breakpoint expression is going to be evaluated
10 | eval EXPR
11 | Evaluate a Scheme expression EXPR in the current environment
12 | stack
13 | Show the execution stack of the current state
14 | list
15 | Show the indices corresponding to each expression as well as the expression is evaluated or not
16 | break add INDEX
17 | Set the expression with index INDEX as a breakpoint
18 | break remove INDEX
19 | Unset the expression with index INDEX as a breakpoint
20 | help
21 | Show this help
22 | quit
23 | Exit this debugger
--------------------------------------------------------------------------------
/doc/repository.tex:
--------------------------------------------------------------------------------
1 | \extrapart{Additional material}
2 |
3 | %%The Internet Scheme Repository at
4 | %%\begin{center}
5 | %%{\cf http://www.cs.indiana.edu/scheme-repository/}
6 | %%\end{center}
7 | %%contains an extensive Scheme bibliography, as well as papers,
8 | %%programs, implementations, and other material related to Scheme.
9 | %% Removed as only of historical interest; schemers.org links to it.
10 |
11 | The Scheme community website at
12 | {\cf http://schemers.org}
13 | contains additional resources for learning and programming, job and
14 | event postings, and Scheme user group information.
15 |
16 | A bibliography of Scheme-related research at
17 | {\cf http://library.readscheme.org}
18 | links to technical papers and theses related to the Scheme language,
19 | including both classic papers and recent research.
20 |
21 | On-line Scheme discussions are held using IRC
22 | on the {\cf \#scheme} channel at {\cf irc.freenode.net}
23 | and on the Usenet discussion group {\cf comp.lang.scheme}.
24 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/Primitive.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin;
18 |
19 | /**
20 | * Interface for primitive
21 | * @author Chan Chung Kwong <1m02math@126.com>
22 | */
23 | public interface Primitive{
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/lib/file_derive.scm:
--------------------------------------------------------------------------------
1 | (import (scheme base))
2 |
3 | (define (call-with-input-file file proc)
4 | (call-with-port (open-input-file file) proc))
5 | (define (call-with-output-file file proc)
6 | (call-with-port (open-output-file file) proc))
7 |
8 | (define (with-input-from-file file thunk)
9 | (let ((port (open-input-file file))
10 | (old (current-input-port)))
11 | (dynamic-wind (lambda () (set! old (current-input-port)) (set-current-input-port! port))
12 | (lambda () (let ((ret (thunk))) (close-port port) ret))
13 | (lambda () (set-current-input-port! old)))))
14 | (define (with-output-to-file file thunk)
15 | (let ((port (open-output-file file))
16 | (old (current-output-port)))
17 | (dynamic-wind (lambda () (set! old (current-output-port)) (set-current-output-port! port))
18 | (lambda () (let ((ret (thunk))) (close-port port) ret))
19 | (lambda () (set-current-output-port! old)))))
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/DatumLabelSrc.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015,2016 Chan Chung Kwong
3 | *
4 | * This program is free software; you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation; either version 3 of the License, or (at
7 | * your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | */
15 | package com.github.chungkwong.jschememin;
16 | /**
17 | * Represents labels to be referenced
18 | * @author kwong
19 | */
20 | public final class DatumLabelSrc extends DatumLabel{
21 | /**
22 | * Create a label
23 | * @param label ID
24 | */
25 | public DatumLabelSrc(String label){
26 | super(label);
27 | }
28 | @Override
29 | public String toString(){
30 | return "#"+getLabel()+"=";
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/DatumLabelRef.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015,2016 Chan Chung Kwong
3 | *
4 | * This program is free software; you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation; either version 3 of the License, or (at
7 | * your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | */
15 | package com.github.chungkwong.jschememin;
16 | /**
17 | * Represents labels that reference other label
18 | * @author kwong
19 | */
20 | public final class DatumLabelRef extends DatumLabel{
21 | /**
22 | * Create a label
23 | * @param label ID
24 | */
25 | public DatumLabelRef(String label){
26 | super(label);
27 | }
28 | @Override
29 | public String toString(){
30 | return "#"+getLabel()+"#";
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/type/ScmPairOrNil.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.type;
18 | /**
19 | * Represents the type list in Scheme
20 | * @author kwong
21 | */
22 | public abstract class ScmPairOrNil extends ScmObject{
23 | @Override
24 | public boolean isSelfevaluating(){
25 | return false;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/type/ScmNumber.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong
3 | *
4 | * This program is free software; you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation; either version 3 of the License, or (at
7 | * your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | */
15 | package com.github.chungkwong.jschememin.type;
16 | import com.github.chungkwong.jschememin.*;
17 | /**
18 | * Represents the type number in Scheme
19 | * @author kwong
20 | */
21 | public abstract class ScmNumber extends ScmObject implements Token{
22 | /**
23 | * Check if the number is a exact number
24 | * @return the result
25 | */
26 | public abstract boolean isExact();
27 | @Override
28 | public boolean isSelfevaluating(){
29 | return true;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/type/ScmNil.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.type;
18 | /**
19 | * Represents the type null in Scheme
20 | * @author kwong
21 | */
22 | public final class ScmNil extends ScmPairOrNil{
23 | /**
24 | * The null value
25 | */
26 | public static final ScmNil NIL=new ScmNil();
27 | private ScmNil(){
28 | }
29 | @Override
30 | public String toExternalRepresentation(){
31 | return "()";
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/LibraryLoader.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin;
18 | import com.github.chungkwong.jschememin.type.*;
19 | /**
20 | * Loader for library
21 | * @author Chan Chung Kwong <1m02math@126.com>
22 | */
23 | public interface LibraryLoader{
24 | /**
25 | * Get the library
26 | * @return
27 | */
28 | Library getLibrary();
29 | /**
30 | * The name of the library that this loader load
31 | * @return
32 | */
33 | ScmPair getName();
34 | }
35 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/lib/case-lambda.scm:
--------------------------------------------------------------------------------
1 | (define-library (scheme case-lambda)
2 | (import (scheme base))
3 | (export case-lambda)
4 | (begin
5 | (define-syntax case-lambda
6 | (syntax-rules ()
7 | ((case-lambda (params body0 ...) ...)
8 | (lambda args
9 | (let ((len (length args)))
10 | (letrec-syntax
11 | ((cl (syntax-rules ::: ()
12 | ((cl)
13 | (error "no matching clause"))
14 | ((cl ((p :::) . body) . rest)
15 | (if (= len (length '(p :::)))
16 | (apply (lambda (p :::)
17 | . body)
18 | args)
19 | (cl . rest)))
20 | ((cl ((p ::: . tail) . body)
21 | . rest)
22 | (if (>= len (length '(p :::)))
23 | (apply
24 | (lambda (p ::: . tail)
25 | . body)
26 | args)
27 | (cl . rest))))))
28 | (cl (params body0 ...) ...)))))))))
29 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/LexicalException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong
3 | *
4 | * This program is free software; you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation; either version 3 of the License, or (at
7 | * your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | */
15 | package com.github.chungkwong.jschememin;
16 |
17 | /**
18 | * Lexical exception when reading script source code
19 | * @author Chan Chung Kwong <1m02math@126.com>
20 | */
21 | public class LexicalException extends RuntimeException {
22 | /**
23 | * Creates a new instance of LexicalException without detail message.
24 | */
25 | public LexicalException() {
26 | }
27 | /**
28 | * Constructs an instance of LexicalException with the specified detail message.
29 | * @param msg the detail message.
30 | */
31 | public LexicalException(String msg) {
32 | super(msg);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/lib/NativeProcedure.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.lib;
18 | import com.github.chungkwong.jschememin.type.*;
19 | /**
20 | * Represents the dynamic part of a native procedure
21 | * @author Chan Chung Kwong <1m02math@126.com>
22 | */
23 | public interface NativeProcedure{
24 | /**
25 | * To be called when the procedure is called
26 | * @param param
27 | * @return
28 | * @throws Exception
29 | */
30 | ScmObject call(ScmObject param) throws Exception;
31 | }
32 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/lib/Lazy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.lib;
18 | import com.github.chungkwong.jschememin.*;
19 | /**
20 | * Correspoding to the library (scheme lazy) in Scheme
21 | * @author Chan Chung Kwong <1m02math@126.com>
22 | */
23 | public class Lazy extends NativeLibrary{
24 | public static final Lazy INSTANCE=new Lazy();
25 | private Lazy(){
26 | super("scheme","lazy");
27 | }
28 | @Override
29 | protected void init(Library lib){
30 | addDeriveFile("/com/github/chungkwong/jschememin/lib/lazy.scm");
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/lib/jschememin_derive.scm:
--------------------------------------------------------------------------------
1 | (import (scheme base))
2 | (import (scheme hashtables))
3 | (define duration (syntax-rules () ((_ x) (let ((t (thread-clock))) x (- (thread-clock) t)))))
4 | (define-record-type (make-call-record count total-time) call-record?
5 | (count count set-count!) (total-time total-time set-total-time!))
6 | (define statistics (make-eq-hashtable))
7 | (define profile-lambda
8 | (syntax-rules ()
9 | ((_ args body ...)
10 | (letrec ((proc (lambda args
11 | (let* ((t (thread-clock)) (ret (begin body ... )))
12 | (hashtable-update! statistics
13 | proc
14 | (lambda (e) (set-total-time! e (+ (total-time e) (- (thread-clock) t)))
15 | (set-count! e (+ (count e) 1))
16 | e)
17 | (make-call-record 0 0))
18 | ret))))
19 | proc))))
20 | (define (profile-record proc) (hashtable-ref statistics proc (make-call-record 0 0)))
21 | (define (profile-records) (hashtable-copy statistics #f))
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/lib/REPL.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.lib;
18 | import com.github.chungkwong.jschememin.*;
19 | /**
20 | * Correspoding to the library (scheme repl) in Scheme
21 | * @author Chan Chung Kwong <1m02math@126.com>
22 | */
23 | public class REPL extends NativeLibrary{
24 | public static final REPL INSTANCE=new REPL();
25 | private REPL(){
26 | super("scheme","repl");
27 | }
28 | @Override
29 | protected void init(Library lib){
30 | addNativeProcedure("interaction-environment",(o)->Utility.getInteractiveEnvironment());
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/primitive/UncaughtExceptionError.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.primitive;
18 |
19 | /**
20 | * Being thrown when a exception is no caught
21 | * @author Chan Chung Kwong <1m02math@126.com>
22 | */
23 | public class UncaughtExceptionError extends Error{
24 | /**
25 | * Wrap a Exception
26 | * @param cause
27 | */
28 | public UncaughtExceptionError(RuntimeException cause){
29 | super(cause);
30 | }
31 | @Override
32 | public synchronized RuntimeException getCause(){
33 | return (RuntimeException)super.getCause();
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | com.github.chungkwong
8 | jschememin
9 | 1.0-SNAPSHOT
10 | jar
11 |
12 | jschememin
13 | A implementation of the Scheme language R7RS
14 | http://github.com/chungkwong/jschememin
15 |
16 |
17 |
18 | GNU GENERAL PUBLIC LICENSE, Version 3
19 | https://www.gnu.org/licenses/gpl.txt
20 |
21 |
22 |
23 |
24 |
25 | Chan Chung Kwong
26 | 1m02math@126.com
27 | SYSU
28 | http://www.sysu.edu.cn
29 |
30 |
31 |
32 |
33 | scm:git:https://github.com/chungkwong/JSchemeMin.git
34 | scm:git:ssh://github.com:chungkwong/JSchemeMin.git
35 | http://github.com/chungkwong/jschememin/tree/master
36 |
37 |
38 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/type/ScmEndOfFileObject.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.type;
18 |
19 | /**
20 | * Represents the end-of-file object in Scheme
21 | * @author Chan Chung Kwong <1m02math@126.com>
22 | */
23 | public class ScmEndOfFileObject extends ScmObject{
24 | /**
25 | * The object
26 | */
27 | public static final ScmEndOfFileObject INSTANCE=new ScmEndOfFileObject();
28 | private ScmEndOfFileObject(){
29 | }
30 | @Override
31 | public String toExternalRepresentation(){
32 | return "eof-object";
33 | }
34 | @Override
35 | public boolean isSelfevaluating(){
36 | return false;
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/SyntaxException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | package com.github.chungkwong.jschememin;
19 | /**
20 | * Syntax exception when parsing script
21 | * @author Chan Chung Kwong <1m02math@126.com>
22 | */
23 | public class SyntaxException extends RuntimeException{
24 | /**
25 | * Creates a new instance of SyntaxException without detail message.
26 | */
27 | public SyntaxException() {
28 | }
29 | /**
30 | * Constructs an instance of SyntaxException with the specified detail message.
31 | * @param msg the detail message.
32 | */
33 | public SyntaxException(String msg) {
34 | super(msg);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/SimpleToken.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong
3 | *
4 | * This program is free software; you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation; either version 3 of the License, or (at
7 | * your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | */
15 | package com.github.chungkwong.jschememin;
16 | import java.util.*;
17 | /**
18 | * Standard tokens
19 | * @author kwong
20 | */
21 | public final class SimpleToken implements Token{
22 | private final String id;
23 | private SimpleToken(String id){
24 | this.id=id;
25 | }
26 | /**
27 | * build a token
28 | * @param id the text
29 | * @return the token
30 | */
31 | public static SimpleToken getToken(String id){
32 | return new SimpleToken(id);
33 | }
34 | @Override
35 | public String toString(){
36 | return id;
37 | }
38 | @Override
39 | public boolean equals(Object obj){
40 | return obj instanceof SimpleToken&&((SimpleToken)obj).id.equals(id);
41 | }
42 | @Override
43 | public int hashCode(){
44 | return Objects.hashCode(this.id);
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/lib/lazy.scm:
--------------------------------------------------------------------------------
1 | (define-library (scheme lazy)
2 | (import (scheme base))
3 | (export delay-force delay make-promise force promise?)
4 | (begin
5 | (define make-promise-aux
6 | (lambda (done? proc)
7 | (list (cons done? proc))))
8 |
9 | (define-syntax delay-force
10 | (syntax-rules ()
11 | ((delay-force expression)
12 | (make-promise-aux #f (lambda () expression)))))
13 |
14 | (define-syntax delay
15 | (syntax-rules ()
16 | ((delay expression)
17 | (delay-force (make-promise-aux #t expression)))))
18 |
19 | (define make-promise
20 | (lambda (obj)
21 | (list (cons #t obj) obj)))
22 |
23 | (define (force promise)
24 | (if (promise-done? promise)
25 | (promise-value promise)
26 | (let ((promise* ((promise-value promise))))
27 | (unless (promise-done? promise)
28 | (promise-update! promise* promise))
29 | (force promise))))
30 |
31 | (define promise?
32 | (lambda (x) (and (pair? x) (pair? (car x)))))
33 |
34 | (define promise-done?
35 | (lambda (x) (car (car x))))
36 | (define promise-value
37 | (lambda (x) (cdr (car x))))
38 | (define promise-update!
39 | (lambda (new old)
40 | (set-car! (car old) (promise-done? new))
41 | (set-cdr! (car old) (promise-value new))
42 | (set-car! new (car old))))))
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/primitive/Quote.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.primitive;
18 | import com.github.chungkwong.jschememin.*;
19 | import com.github.chungkwong.jschememin.type.*;
20 | /**
21 | * Correspoding to the primitive quote in Scheme
22 | * @author Chan Chung Kwong <1m02math@126.com>
23 | */
24 | public class Quote extends BasicConstruct implements Primitive{
25 | public static final Quote INSTANCE=new Quote();
26 | private Quote(){
27 | super(new ScmSymbol("quote"));
28 | }
29 | @Override
30 | public void call(SchemeEnvironment env,Continuation cont,Object pointer,ScmPairOrNil expr){
31 | cont.ret(ScmList.first(expr));
32 | }
33 |
34 | }
--------------------------------------------------------------------------------
/doc/Makefile:
--------------------------------------------------------------------------------
1 |
2 | .PHONY: all clean cleaner checkindex
3 |
4 | all: r7rs.pdf overview.pdf
5 |
6 | clean:
7 | rm -f *~
8 |
9 | cleaner: clean
10 | rm -f *.pdf *.aux *.log *.idx *.toc *.out
11 |
12 | DIFF_SOURCES=basic.tex derive.tex example.tex expr.tex \
13 | lex.tex procs.tex prog.tex struct.tex
14 |
15 | SOURCES=r7rs.tex $(DIFF_SOURCES) intro.tex \
16 | bib.tex syn.tex commands.tex first.tex notes.tex \
17 | repository.tex index.tex sem.tex stdmod-raw.tex \
18 | features.tex
19 |
20 | # index.tex: r7rs.idx
21 | # csi index.sch -e '(run)'
22 |
23 | stdmod.tex: stdmod-raw.tex
24 | ./genstdmod.pl < $< > $@
25 |
26 | checkindex: stdmod-raw.tex index.tex
27 | ./checkindex.sh
28 |
29 | intro-ebook.tex: intro.tex
30 | sed 's/\\clearextrapart{\(.*\)}/\1/g' $< > $@
31 |
32 | r7rs.pdf: $(SOURCES) stdmod.tex
33 | xelatex $<
34 | xelatex $<
35 |
36 | overview.pdf: overview.tex overview-body.tex
37 | xelatex $<
38 | xelatex $<
39 |
40 | r7rs-ebook.pdf: r7rs-ebook.tex intro-ebook.tex $(SOURCES) stdmod.tex
41 | xelatex $<
42 | xelatex $<
43 |
44 | r5diff/%.tex: %.tex
45 | hg cat -r 1 $< > r5diff/old-$<
46 | latexdiff --type=UNDERLINE --subtype=SAFE r5diff/old-$< $< | \
47 | perl -pe 's/\\section{\\DIF(add|del){([^{}]*)}}/\\section{\2}/; s/}\\ev \\DIFadd{/\\ev/' | \
48 | perl -pe 'BEGIN{undef $$/} s/\\ev([^%{]*)(%.*)?\n}/} \\ev \1\n/g' > $@
49 | rm -f r5diff/old-$<
50 |
51 | r5diff/r7rs.pdf: $(DIFF_SOURCES:%=r5diff/%)
52 | cd r5diff && $(MAKE) r7rs.pdf
53 |
--------------------------------------------------------------------------------
/doc/genstdmod.pl:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env perl
2 |
3 | use warnings;
4 | use strict;
5 |
6 | use constant COLUMNS => 2;
7 | use constant COLUMN_WIDTH => 24;
8 |
9 | my $list;
10 |
11 | my $list_only;
12 | if ($#ARGV >= 0 and $ARGV[0] =~ /^--?l(ist([-_]?only)?)?$/i) {
13 | shift;
14 | $list_only = 1;
15 | }
16 |
17 | while (<>) {
18 | if (/^\.(.*)/) {
19 | $list .= "$1\n";
20 | } else {
21 | if (length($list)) {
22 | $list = "" unless defined($list);
23 | if ($list_only) {
24 | print "$_\n" for sort split(/\s+/, $list);
25 | } else {
26 | my $columnated;
27 | my $column = 0;
28 | my $space = "";
29 | for my $id (sort split(/\s+/, $list)) {
30 | my $new_column = $column + 1 + int(length($id) / COLUMN_WIDTH);
31 | if ($new_column > COLUMNS) {
32 | $columnated .= "\n";
33 | $new_column -= $column;
34 | $column = 0;
35 | $space = "";
36 | }
37 | $columnated .= $space . $id;
38 | $space = " " x (($new_column-$column)*COLUMN_WIDTH - length($id));
39 | $space .= " " x ($new_column-$column-1);
40 | $column = $new_column;
41 | }
42 | $columnated =~ s/_/\\_/g;
43 | $columnated =~ s/\? /\?\\ /g;
44 | $columnated =~ s/((?:\\.|\S)+)/{\\cf $1}/g;
45 | print "$columnated\n";
46 | undef $list;
47 | }
48 | }
49 | print unless $list_only;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/primitive/Eval.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.primitive;
18 | import com.github.chungkwong.jschememin.*;
19 | import com.github.chungkwong.jschememin.type.*;
20 | /**
21 | * Correspoding to the primitive eval in Scheme
22 | * @author Chan Chung Kwong <1m02math@126.com>
23 | */
24 | public class Eval extends BasicConstruct{
25 | public static final Eval INSTANCE=new Eval();
26 | private Eval(){
27 | super(new ScmSymbol("eval"));
28 | }
29 | @Override
30 | public void call(SchemeEnvironment env,Continuation cont,Object pointer,ScmPairOrNil param){
31 | cont.callTail(ExpressionEvaluator.INSTANCE,ScmList.toList(ScmList.first(param)),(SchemeEnvironment)ScmList.second(param));
32 | }
33 | }
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/primitive/SyntaxRule.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.primitive;
18 | import com.github.chungkwong.jschememin.*;
19 | import com.github.chungkwong.jschememin.type.*;
20 | /**
21 | * Correspoding to the primitive syntax-rules in Scheme
22 | * @author Chan Chung Kwong <1m02math@126.com>
23 | */
24 | public class SyntaxRule extends BasicConstruct implements Primitive{
25 | public static final SyntaxRule INSTANCE=new SyntaxRule();
26 | private SyntaxRule(){
27 | super(new ScmSymbol("syntax-rules"));
28 | }
29 | @Override
30 | public void call(SchemeEnvironment env,Continuation cont,Object pointer,ScmPairOrNil param){
31 | cont.ret(new ScmSyntaxRules((ScmPair)param,env));
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/primitive/Lambda.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.primitive;
18 | import com.github.chungkwong.jschememin.*;
19 | import com.github.chungkwong.jschememin.type.*;
20 | /**
21 | * Correspoding to the primitive lambda in Scheme
22 | * @author Chan Chung Kwong <1m02math@126.com>
23 | */
24 | public class Lambda extends BasicConstruct implements Primitive{
25 | public static final Lambda INSTANCE=new Lambda();
26 | private Lambda(){
27 | super(new ScmSymbol("lambda"));
28 | }
29 | @Override
30 | public void call(SchemeEnvironment env,Continuation cont,Object pointer,ScmPairOrNil expr){
31 | ScmPair list=(ScmPair)expr;
32 | cont.ret(new ScmProcedure(list.getCar(),(ScmPair)list.getCdr(),env));
33 | }
34 | }
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/BasicConstruct.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin;
18 | import com.github.chungkwong.jschememin.type.*;
19 | /**
20 | * The base class for primitives
21 | * @author Chan Chung Kwong <1m02math@126.com>
22 | */
23 | public abstract class BasicConstruct extends Evaluable{
24 | private final ScmSymbol keyword;
25 | /**
26 | * Construct a BasicConstruct
27 | * @param keyword
28 | */
29 | protected BasicConstruct(ScmSymbol keyword){
30 | this.keyword=keyword;
31 | }
32 | /**
33 | * Get the keyword
34 | * @return
35 | */
36 | public ScmSymbol getKeyword(){
37 | return keyword;
38 | }
39 | @Override
40 | public String toExternalRepresentation(){
41 | return keyword.getValue();
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/doc/features.tex:
--------------------------------------------------------------------------------
1 | \chapter{Standard Feature Identifiers}
2 | \label{stdfeatures}
3 |
4 | An implementation may provide any or all of the feature identifiers
5 | listed below for use by {\cf cond-expand} and {\cf features},
6 | but must not provide a feature identifier if it does not
7 | provide the corresponding feature.
8 |
9 | \label{standard_features}
10 |
11 | \feature{r7rs}{All \rsevenrs\ Scheme implementations have this feature.}
12 | \feature{exact-closed}{All algebraic operations except {\cf /} produce
13 | exact values given exact inputs.}
14 | \feature{exact-complex}{Exact complex numbers are provided.}
15 | \feature{ieee-float}{Inexact numbers are IEEE 754 binary floating point
16 | values.}
17 | \feature{full-unicode}{All Unicode characters present in Unicode version 6.0 are supported as Scheme characters.}
18 | \feature{ratios}{{\cf /} with exact arguments produces an exact result
19 | when the divisor is nonzero.}
20 | \feature{posix}{This implementation is running on a POSIX
21 | system.}
22 | \feature{windows}{This implementation is running on Windows.}
23 | \feature{unix, darwin, gnu-linux, bsd, freebsd, solaris, ...}{Operating
24 | system flags (perhaps more than one).}
25 | \feature{i386, x86-64, ppc, sparc, jvm, clr, llvm, ...}{CPU architecture flags.}
26 | \feature{ilp32, lp64, ilp64, ...}{C memory model flags.}
27 | \feature{big-endian, little-endian}{Byte order flags.}
28 | \feature{\hyper{name}}{The name of this implementation.}
29 | \feature{\hyper{name-version}}{The name and version of this
30 | implementation.}
31 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/lib/Read.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.lib;
18 | import com.github.chungkwong.jschememin.*;
19 | import static com.github.chungkwong.jschememin.lib.Utility.car;
20 | import com.github.chungkwong.jschememin.type.*;
21 | /**
22 | * Correspoding to the library (scheme read) in Scheme
23 | * @author Chan Chung Kwong <1m02math@126.com>
24 | */
25 | public class Read extends NativeLibrary{
26 | public static final Read INSTANCE=new Read();
27 | private Read(){
28 | super("scheme","read");
29 | }
30 | @Override
31 | protected void init(Library lib){
32 | addNativeProcedure("read",new NativeProcedureDefault((o)->new Parser(new Lex(((ScmTextualInputPort)car(o)).getReader())).nextDatum(),
33 | (o)->ScmPort.CURRENT_INPUT));
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/lib/Time.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.lib;
18 | import com.github.chungkwong.jschememin.*;
19 | import com.github.chungkwong.jschememin.type.*;
20 | /**
21 | * Correspoding to the library (scheme time) in Scheme
22 | * @author Chan Chung Kwong <1m02math@126.com>
23 | */
24 | public class Time extends NativeLibrary{
25 | public static final Time INSTANCE=new Time();
26 | private Time(){
27 | super("scheme","time");
28 | }
29 | @Override
30 | protected void init(Library lib){
31 | addNativeProcedure("current-second",(o)->new ScmInteger(System.currentTimeMillis()/1000));
32 | addNativeProcedure("current-jiffy",(o)->new ScmInteger(System.nanoTime()));
33 | addNativeProcedure("jiffies-per-second",(o)->new ScmInteger(1000000000));
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/primitive/CallWithValues.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.primitive;
18 | import com.github.chungkwong.jschememin.*;
19 | import com.github.chungkwong.jschememin.type.*;
20 | /**
21 | * Correspoding to the primitive call-with-values in Scheme
22 | * @author Chan Chung Kwong <1m02math@126.com>
23 | */
24 | public class CallWithValues extends BasicConstruct{
25 | public static final CallWithValues INSTANCE=new CallWithValues();
26 | private CallWithValues(){
27 | super(new ScmSymbol("call-with-values"));
28 | }
29 | @Override
30 | public void call(SchemeEnvironment env,Continuation cont,Object pointer,ScmPairOrNil param){
31 | cont.callTail((Evaluable)ScmList.second(param),ScmNil.NIL,env);
32 | cont.call((Evaluable)ScmList.first(param),null,ScmNil.NIL,env);
33 | }
34 | }
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/lib/Eval.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.lib;
18 | import com.github.chungkwong.jschememin.*;
19 | import com.github.chungkwong.jschememin.primitive.*;
20 | /**
21 | * Correspoding to the library (scheme eval) in Scheme
22 | * @author Chan Chung Kwong <1m02math@126.com>
23 | */
24 | public class Eval extends NativeLibrary{
25 | public static final Eval INSTANCE=new Eval();
26 | private Eval(){
27 | super("scheme","eval");
28 | }
29 | @Override
30 | protected void init(Library lib){
31 | addNativeProcedure("environment",(o)->Import.INSTANCE.importLibraries(new SchemeEnvironment(false),o));
32 | addPrimitiveType(com.github.chungkwong.jschememin.primitive.Eval.INSTANCE);
33 | //addNativeProcedure("eval",(o)->new Evaluator((Environment)cadr(o)).eval(car(o)));
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/type/ScmObject.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong
3 | *
4 | * This program is free software; you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation; either version 3 of the License, or (at
7 | * your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | */
15 | package com.github.chungkwong.jschememin.type;
16 | /**
17 | * Represents objects in scheme
18 | * @author kwong
19 | */
20 | public abstract class ScmObject{
21 | /**
22 | * Get the external representation of the object
23 | * @return the String
24 | */
25 | public abstract String toExternalRepresentation();
26 | /**
27 | * Check if the object is self-evaluating
28 | * @return
29 | */
30 | public abstract boolean isSelfevaluating();
31 | @Override
32 | public String toString(){
33 | return toExternalRepresentation();
34 | }
35 | /**
36 | * Corresponding to the procedure eqv? in Scheme
37 | * @param obj
38 | * @return
39 | */
40 | public boolean equalsValue(ScmObject obj){
41 | return equals(obj);
42 | }
43 | /**
44 | * Corresponding to the procedure eq? in Scheme
45 | * @param obj
46 | * @return
47 | */
48 | public boolean equalsStrict(ScmObject obj){
49 | return equalsValue(obj);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/primitive/WithExceptionHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.primitive;
18 | import com.github.chungkwong.jschememin.*;
19 | import com.github.chungkwong.jschememin.type.*;
20 | /**
21 | * Correspoding to the primitive with-exception-handler in Scheme
22 | * @author Chan Chung Kwong <1m02math@126.com>
23 | */
24 | public class WithExceptionHandler extends BasicConstruct{
25 | public static final WithExceptionHandler INSTANCE=new WithExceptionHandler();
26 | private WithExceptionHandler(){
27 | super(new ScmSymbol("with-exception-handler"));
28 | }
29 | @Override
30 | public void call(SchemeEnvironment env,Continuation cont,Object pointer,ScmPairOrNil param){
31 | if(pointer==null){
32 | cont.replaceCurrent(this);
33 | cont.call((Evaluable)ScmList.second(param),ScmList.first(param),ScmNil.NIL,env);
34 | }else
35 | cont.ret(param);
36 | }
37 | }
--------------------------------------------------------------------------------
/test/com/github/chungkwong/jschememin/EmbedTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 Chan Chung Kwong
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin;
18 | import com.github.chungkwong.jschememin.type.*;
19 | import java.util.function.*;
20 | import javax.script.*;
21 | import org.junit.*;
22 | /**
23 | *
24 | * @author Chan Chung Kwong
25 | */
26 | public class EmbedTest{
27 | public EmbedTest(){
28 | }
29 | @Test
30 | public void testJavaFunction() throws ScriptException{
31 | ScriptEngine engine=EvaluatorFactory.INSTANCE.getScriptEngine();
32 | SimpleBindings bindings=new SimpleBindings();
33 | Function f=new Function(){
34 | @Override
35 | public String apply(String t){
36 | return t.toUpperCase();
37 | }
38 | };
39 | bindings.put("up",f);
40 | bindings.put("str","hello");
41 | engine.setBindings(bindings,ScriptContext.GLOBAL_SCOPE);
42 | Assert.assertEquals(engine.eval("(up \"heLlo\")"),new ScmString("HELLO"));
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/primitive/Assignment.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.primitive;
18 | import com.github.chungkwong.jschememin.*;
19 | import com.github.chungkwong.jschememin.type.*;
20 | /**
21 | * Correspoding to the primitive set! in Scheme
22 | * @author Chan Chung Kwong <1m02math@126.com>
23 | */
24 | public class Assignment extends BasicConstruct implements Primitive{
25 | public static final Assignment INSTANCE=new Assignment();
26 | private Assignment(){
27 | super(new ScmSymbol("set!"));
28 | }
29 | @Override
30 | public void call(SchemeEnvironment env,Continuation cont,Object pointer,ScmPairOrNil expr){
31 | if(pointer==null){
32 | cont.replaceCurrent(this);
33 | cont.call(ExpressionEvaluator.INSTANCE,(ScmSymbol)ScmList.first(expr),ScmList.second(expr),env);
34 | }else{
35 | env.set((ScmSymbol)pointer,ScmList.first(expr));
36 | cont.ret(expr);
37 | }
38 | }
39 |
40 | }
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/primitive/RaiseContinuable.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.primitive;
18 | import com.github.chungkwong.jschememin.*;
19 | import com.github.chungkwong.jschememin.type.*;
20 | /**
21 | * Correspoding to the primitive raise-continuable in Scheme
22 | * @author Chan Chung Kwong <1m02math@126.com>
23 | */
24 | public class RaiseContinuable extends BasicConstruct{
25 | public static final RaiseContinuable INSTANCE=new RaiseContinuable();
26 | private RaiseContinuable(){
27 | super(new ScmSymbol("raise-continuable"));
28 | }
29 | @Override
30 | public void call(SchemeEnvironment env,Continuation cont,Object pointer,ScmPairOrNil param){
31 | ScmPair handler=cont.getErrorHandler();
32 | if(handler==null)
33 | throw new UncaughtExceptionError(ScmError.toException(ScmList.first(param)));
34 | cont.callTail((Evaluable)handler.getCar(),param,(SchemeEnvironment)handler.getCdr());
35 | }
36 | }
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/lib/cxr.scm:
--------------------------------------------------------------------------------
1 | (define-library (scheme cxr)
2 | (import (scheme base))
3 | (export caaaar caaadr caaar caadar caaddr caadr cadaar cadadr cadar caddar cadddr caddr cdaaar
4 | cdaadr cdaar cdadar cdaddr cdadr cddaar cddadr cddar cdddar cddddr cdddr)
5 | (begin
6 | (define caaaar (lambda (x) (car (car (car (car x))))))
7 | (define caaar (lambda (x) (car (car (car x)))))
8 | (define caaddr (lambda (x) (car (car (cdr (cdr x))))))
9 | (define cadaar (lambda (x) (car (cdr (car (car x))))))
10 | (define cadar (lambda (x) (car (cdr (car x)))))
11 | (define cadddr (lambda (x) (car (cdr (cdr (cdr x))))))
12 | (define cdaaar (lambda (x) (cdr (car (car (car x))))))
13 | (define cdaar (lambda (x) (cdr (car (car x)))))
14 | (define cdaddr (lambda (x) (cdr (car (cdr (cdr x))))))
15 | (define cddaar (lambda (x) (cdr (cdr (car (car x))))))
16 | (define cddar (lambda (x) (cdr (cdr (car x)))))
17 | (define cddddr (lambda (x) (cdr (cdr (cdr (cdr x))))))
18 | (define caaadr (lambda (x) (car (car (car (cdr x))))))
19 | (define caadar (lambda (x) (car (car (cdr (car x))))))
20 | (define caadr (lambda (x) (car (car (cdr x)))))
21 | (define cadadr (lambda (x) (car (cdr (car (cdr x))))))
22 | (define caddar (lambda (x) (car (cdr (cdr (car x))))))
23 | (define caddr (lambda (x) (car (cdr (cdr x)))))
24 | (define cdaadr (lambda (x) (cdr (car (car (cdr x))))))
25 | (define cdadar (lambda (x) (cdr (car (cdr (car x))))))
26 | (define cdadr (lambda (x) (cdr (car (cdr x)))))
27 | (define cddadr (lambda (x) (cdr (cdr (car (cdr x))))))
28 | (define cdddar (lambda (x) (cdr (cdr (cdr (car x))))))
29 | (define cdddr (lambda (x) (cdr (cdr (cdr x)))))))
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/primitive/Apply.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.primitive;
18 | import com.github.chungkwong.jschememin.*;
19 | import com.github.chungkwong.jschememin.type.*;
20 | /**
21 | * Correspoding to the primitive apply in Scheme
22 | * @author Chan Chung Kwong <1m02math@126.com>
23 | */
24 | public class Apply extends BasicConstruct{
25 | public static final Apply INSTANCE=new Apply();
26 | private Apply(){
27 | super(new ScmSymbol("apply"));
28 | }
29 | @Override
30 | public void call(SchemeEnvironment env,Continuation cont,Object pointer,ScmPairOrNil param){
31 | ScmListBuilder buf=new ScmListBuilder();
32 | Evaluable proc=(Evaluable)ScmList.first(param);
33 | ScmPair curr=(ScmPair)((ScmPair)param).getCdr();
34 | for(;curr.getCdr() instanceof ScmPair;curr=(ScmPair)curr.getCdr()){
35 | buf.add(curr.getCar());
36 | }
37 | ScmList.forEach(curr.getCar(),(o)->buf.add(o));
38 | cont.callTail(proc,(ScmPairOrNil)buf.toList(),env);
39 | }
40 | }
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/lib/NativeEvaluable.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.lib;
18 | import com.github.chungkwong.jschememin.*;
19 | import com.github.chungkwong.jschememin.type.*;
20 | /**
21 | * Represents native procedures
22 | * @author Chan Chung Kwong <1m02math@126.com>
23 | */
24 | public class NativeEvaluable extends Evaluable{
25 | private final NativeProcedure proc;
26 | /**
27 | * Wrap a NativeProcedure
28 | * @param proc
29 | */
30 | public NativeEvaluable(NativeProcedure proc){
31 | this.proc=proc;
32 | }
33 | @Override
34 | public String toExternalRepresentation(){
35 | return this.getClass().getCanonicalName();
36 | }
37 | @Override
38 | public boolean isSelfevaluating(){
39 | return false;
40 | }
41 | @Override
42 | public void call(SchemeEnvironment env,Continuation cont,Object pointer,ScmPairOrNil param){
43 | try{
44 | cont.ret(proc.call(param));
45 | }catch(Exception ex){
46 | throw ScmError.toRuntimeException(ex);
47 | }
48 | }
49 | }
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/DatumLabel.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015,2016 Chan Chung Kwong
3 | *
4 | * This program is free software; you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation; either version 3 of the License, or (at
7 | * your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | */
15 | package com.github.chungkwong.jschememin;
16 | import com.github.chungkwong.jschememin.type.*;
17 | import java.util.*;
18 | /**
19 | * Represents labels for datum
20 | * @author kwong
21 | */
22 | public abstract class DatumLabel extends ScmObject implements Token{
23 | private final String label;
24 | /**
25 | * Create a label
26 | * @param label the label name
27 | */
28 | protected DatumLabel(String label){
29 | this.label=label;
30 | }
31 | /**
32 | * Get label name
33 | * @return
34 | */
35 | public String getLabel(){
36 | return label;
37 | }
38 | @Override
39 | public boolean equals(Object obj){
40 | return obj instanceof DatumLabel&&((DatumLabel)obj).label.equals(label);
41 | }
42 | @Override
43 | public int hashCode(){
44 | int hash=7;
45 | hash=97*hash+Objects.hashCode(getLabel());
46 | return hash;
47 | }
48 | @Override
49 | public String toExternalRepresentation(){
50 | throw new UnsupportedOperationException("Not supported yet.");
51 | }
52 | @Override
53 | public boolean isSelfevaluating(){
54 | throw new UnsupportedOperationException("Not supported yet.");
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/Feature.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong
3 | *
4 | * This program is free software; you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation; either version 3 of the License, or (at
7 | * your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | */
15 | package com.github.chungkwong.jschememin;
16 | import com.github.chungkwong.jschememin.type.*;
17 | import java.util.*;
18 | /**
19 | *
20 | * @author Chan Chung Kwong <1m02math@126.com>
21 | */
22 | public class Feature{
23 | private static final HashSet FEATURES=new HashSet<>();
24 | static{
25 | FEATURES.add("r7rs");
26 | FEATURES.add("exact-closed");
27 | FEATURES.add("exact-complex");
28 | //FEATURES.add("ieee-float");
29 | FEATURES.add("full-unicode");
30 | FEATURES.add("ratios");
31 | FEATURES.add("jvm");
32 | FEATURES.add("jschememin");
33 | FEATURES.add("jschememin-0.0.1");
34 | FEATURES.add(System.getProperty("os.arch"));
35 | FEATURES.add(System.getProperty("os.name"));
36 | }
37 | /**
38 | * Check if a feature is presented
39 | * @param feature
40 | * @return
41 | */
42 | public static boolean contains(String feature){
43 | return FEATURES.contains(feature);
44 | }
45 | /**
46 | * Get all features presented
47 | * @return
48 | */
49 | public static ScmPairOrNil getAll(){
50 | return ScmList.toList(FEATURES.stream().map((feature)->new ScmSymbol(feature)).toArray(ScmObject[]::new));
51 | }
52 | }
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/lib/NativeEvaluableMulti.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.lib;
18 | import com.github.chungkwong.jschememin.*;
19 | import com.github.chungkwong.jschememin.type.*;
20 | /**
21 | * Represents native procedures that may return many values
22 | * @author Chan Chung Kwong <1m02math@126.com>
23 | */
24 | public class NativeEvaluableMulti extends Evaluable{
25 | private final NativeProcedure proc;
26 | /**
27 | * Wrap a NativeProcedure
28 | * @param proc
29 | */
30 | public NativeEvaluableMulti(NativeProcedure proc){
31 | this.proc=proc;
32 | }
33 | @Override
34 | public String toExternalRepresentation(){
35 | return this.getClass().getCanonicalName();
36 | }
37 | @Override
38 | public boolean isSelfevaluating(){
39 | return false;
40 | }
41 | @Override
42 | public void call(SchemeEnvironment env,Continuation cont,Object pointer,ScmPairOrNil param){
43 | try{
44 | cont.ret((ScmPairOrNil)proc.call(param));
45 | }catch(Exception ex){
46 | throw ScmError.toRuntimeException(ex);
47 | }
48 | }
49 | }
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/primitive/Raise.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.primitive;
18 | import com.github.chungkwong.jschememin.*;
19 | import com.github.chungkwong.jschememin.type.*;
20 | /**
21 | * Correspoding to the primitive raise in Scheme
22 | * @author Chan Chung Kwong <1m02math@126.com>
23 | */
24 | public class Raise extends BasicConstruct{
25 | public static final Raise INSTANCE=new Raise();
26 | private Raise(){
27 | super(new ScmSymbol("raise"));
28 | }
29 | @Override
30 | public void call(SchemeEnvironment env,Continuation cont,Object pointer,ScmPairOrNil param){
31 | cont.removeUntilErrorHandler();
32 | if(cont.hasNext()){
33 | if(pointer!=null){
34 | param=(ScmPairOrNil)pointer;
35 | }
36 | ScmObject handler=(ScmObject)cont.getCurrentPointer();
37 | SchemeEnvironment e=cont.getCurrentEnvironment();
38 | cont.callTail(this,param,env);
39 | cont.call((Evaluable)handler,param,param,e);
40 | }else{
41 | throw new UncaughtExceptionError(ScmError.toException(ScmList.first(param)));
42 | }
43 | }
44 | }
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/type/ScmUniqueSymbol.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.type;
18 |
19 | /**
20 | * Represents symbols that is difference to all existing ones
21 | * @author Chan Chung Kwong <1m02math@126.com>
22 | */
23 | public class ScmUniqueSymbol extends ScmSymbol{
24 | private static int seq=0;
25 | private final ScmSymbol org;
26 | /**
27 | * Construcr a unique symbol
28 | * @param org the prefered name
29 | */
30 | public ScmUniqueSymbol(ScmSymbol org){
31 | super(Integer.toString(seq++));
32 | this.org=toLiteral(org);
33 | }
34 | /**
35 | * Get the prefered name
36 | * @return
37 | */
38 | public ScmSymbol getOrigin(){
39 | return org;
40 | }
41 | /**
42 | * Get prefered name or itself
43 | * @param id
44 | * @return
45 | */
46 | public static ScmSymbol toLiteral(ScmSymbol id){
47 | return id instanceof ScmUniqueSymbol?((ScmUniqueSymbol)id).getOrigin():id;
48 | }
49 | @Override
50 | public String toString(){
51 | return org.toString(); //To change body of generated methods, choose Tools | Templates.
52 | }
53 | }
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/Evaluable.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin;
18 | import com.github.chungkwong.jschememin.type.*;
19 | /**
20 | * Represents expression types
21 | * @author Chan Chung Kwong <1m02math@126.com>
22 | */
23 | public abstract class Evaluable extends ScmObject{
24 | @Override
25 | public boolean isSelfevaluating(){
26 | return false;
27 | }
28 | /**
29 | * To be called when such exprssion is evaluated
30 | * @param env the environment where the exprssion is evaluated
31 | * @param cont the execution stack
32 | * @param pointer saved at last call
33 | * @param param parameters given to the type
34 | */
35 | public abstract void call(SchemeEnvironment env,Continuation cont,Object pointer,ScmPairOrNil param);
36 | /**
37 | * Call and get the result in a new stack
38 | * @param param
39 | * @return
40 | */
41 | public ScmObject call(ScmPairOrNil param){
42 | Continuation cont=new Continuation();
43 | cont.callInit(this,param,null);
44 | while(cont.hasNext())
45 | cont.evalNext();
46 | return cont.getCurrentValue();
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/type/ScmBoolean.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong
3 | *
4 | * This program is free software; you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation; either version 3 of the License, or (at
7 | * your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | */
15 | package com.github.chungkwong.jschememin.type;
16 | import com.github.chungkwong.jschememin.*;
17 | public final class ScmBoolean extends ScmObject implements Token{
18 | /**
19 | * True
20 | */
21 | public static final ScmBoolean TRUE=new ScmBoolean(true);
22 | /**
23 | * False
24 | */
25 | public static final ScmBoolean FALSE=new ScmBoolean(false);
26 | private final boolean val;
27 | /**
28 | * Wrap a boolean
29 | * @param val the value
30 | */
31 | private ScmBoolean(boolean val){
32 | this.val=val;
33 | }
34 | /**
35 | * Convert to boolean
36 | * @return the boolean
37 | */
38 | public boolean isTrue(){
39 | return val;
40 | }
41 | @Override
42 | public boolean equals(Object obj){
43 | return this==obj;
44 | }
45 | @Override
46 | public int hashCode(){
47 | return this.val?1:0;
48 | }
49 | @Override
50 | public String toExternalRepresentation(){
51 | return val?"#t":"#f";
52 | }
53 | @Override
54 | public boolean isSelfevaluating(){
55 | return true;
56 | }
57 | /**
58 | * Convert from a boolean
59 | * @param b the boolean
60 | * @return the Scheme boolean
61 | */
62 | public static ScmBoolean valueOf(boolean b){
63 | return b?ScmBoolean.TRUE:ScmBoolean.FALSE;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/type/ScmSymbol.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong
3 | *
4 | * This program is free software; you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation; either version 3 of the License, or (at
7 | * your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | */
15 | package com.github.chungkwong.jschememin.type;
16 | import com.github.chungkwong.jschememin.*;
17 | import java.util.*;
18 | /**
19 | * Represents the type symbol in Scheme
20 | * @author kwong
21 | */
22 | public class ScmSymbol extends ScmObject implements Token{
23 | private final String id;
24 | /**
25 | * Make a symbol
26 | * @param id the name of the symbol
27 | */
28 | public ScmSymbol(String id){
29 | this.id=id;
30 | }
31 | /**
32 | * Get the name of the symbol
33 | * @return
34 | */
35 | public String getValue(){
36 | return id;
37 | }
38 | @Override
39 | public boolean equals(Object obj){
40 | return obj!=null&&getClass().equals(obj.getClass())&&((ScmSymbol)obj).id.equals(id);
41 | }
42 | @Override
43 | public int hashCode(){
44 | int hash=7;
45 | hash=97*hash+Objects.hashCode(this.id);
46 | return hash;
47 | }
48 | @Override
49 | public String toExternalRepresentation(){
50 | StringBuilder buf=new StringBuilder();
51 | buf.append('|');
52 | id.codePoints().forEach((c)->{
53 | if(c=='|'||c=='\\')
54 | buf.append('\\');
55 | buf.appendCodePoint(c);
56 | });
57 | buf.append('|');
58 | return buf.toString();
59 | }
60 | @Override
61 | public boolean isSelfevaluating(){
62 | return false;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/test/com/github/chungkwong/jschememin/SchemeAssert.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin;
18 | import com.github.chungkwong.jschememin.type.*;
19 | import java.io.*;
20 | import org.junit.*;
21 | /**
22 | *
23 | * @author Chan Chung Kwong <1m02math@126.com>
24 | */
25 | public class SchemeAssert{
26 | public static void assertExpressionValue(String expr,String result){
27 | ScmObject gotval=new Evaluator(true).eval(new Parser(expr).nextDatum());
28 | ScmObject expectval=new Evaluator(true).eval(new Parser(result).nextDatum());
29 | Assert.assertEquals(gotval,expectval);
30 | }
31 | public static void assertStandardOutput(String expr,String result){
32 | StringWriter out=new StringWriter();
33 | ScmPort.CURRENT_OUTPUT=new ScmTextualOutputPort(out);
34 | try{
35 | new Evaluator(true).eval(new Parser(expr).nextDatum());
36 | }catch(RuntimeException ex){
37 |
38 | }
39 | Assert.assertEquals(out.toString(),result);
40 | }
41 | public static void expectException(String expr){
42 | try{
43 | new Evaluator(true).eval(new Parser(expr).nextDatum());
44 | Assert.assertTrue(false);
45 | }catch(Throwable ex){
46 |
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/primitive/If.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.primitive;
18 | import com.github.chungkwong.jschememin.*;
19 | import com.github.chungkwong.jschememin.type.*;
20 | /**
21 | * Correspoding to the primitive if in Scheme
22 | * @author Chan Chung Kwong <1m02math@126.com>
23 | */
24 | public class If extends BasicConstruct implements Primitive{
25 | public static final If INSTANCE=new If();
26 | private If(){
27 | super(new ScmSymbol("if"));
28 | }
29 | @Override
30 | public void call(SchemeEnvironment env,Continuation cont,Object pointer,ScmPairOrNil expr){
31 | if(pointer==null){
32 | ScmPair list=(ScmPair)expr;
33 | cont.replaceCurrent(this);
34 | cont.call(ExpressionEvaluator.INSTANCE,(ScmPair)list.getCdr(),list.getCar(),env);
35 | }else{
36 | ScmPair list=(ScmPair)pointer;
37 | if(ScmList.first(expr)==ScmBoolean.FALSE){
38 | if(list.getCdr() instanceof ScmPair)
39 | cont.callTail(ExpressionEvaluator.INSTANCE,list.getCadr(),env);
40 | else
41 | cont.ret(new ScmSymbol("unspecified"));
42 | }else{
43 | cont.callTail(ExpressionEvaluator.INSTANCE,list.getCar(),env);
44 | }
45 | }
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/type/ScmPort.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.type;
18 | import java.io.*;
19 | /**
20 | *
21 | * @author Chan Chung Kwong <1m02math@126.com>
22 | */
23 | public abstract class ScmPort extends ScmObject{
24 | /**
25 | * current-input-port in Scheme
26 | */
27 | public static ScmPort CURRENT_INPUT=new ScmTextualInputPort(new InputStreamReader(System.in));
28 | /**
29 | * current-output-port in Scheme
30 | */
31 | public static ScmPort CURRENT_OUTPUT=new ScmTextualOutputPort(new OutputStreamWriter(System.out));
32 | /**
33 | * The current error port
34 | */
35 | public static ScmPort CURRENT_ERROR=new ScmTextualOutputPort(new OutputStreamWriter(System.err));
36 | private boolean closed=false;
37 | @Override
38 | public boolean isSelfevaluating(){
39 | return false;
40 | }
41 | /**
42 | * Corresponding to the procedure close-port in Scheme
43 | * @return
44 | * @throws IOException
45 | */
46 | public ScmPort close()throws IOException{
47 | closed=true;
48 | return this;
49 | }
50 | /**
51 | * Check if the port is closed
52 | * @return
53 | */
54 | public boolean isClosed(){
55 | return closed;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/primitive/DefineValues.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.primitive;
18 | import com.github.chungkwong.jschememin.*;
19 | import com.github.chungkwong.jschememin.type.*;
20 | /**
21 | * Correspoding to the primitive define-values in Scheme
22 | * @author Chan Chung Kwong <1m02math@126.com>
23 | */
24 | public class DefineValues extends BasicConstruct implements Primitive{
25 | public static final DefineValues INSTANCE=new DefineValues();
26 | private DefineValues(){
27 | super(new ScmSymbol("define-values"));
28 | }
29 | @Override
30 | public void call(SchemeEnvironment env,Continuation cont,Object pointer,ScmPairOrNil expr){
31 | if(pointer==null){
32 | cont.replaceCurrent(this);
33 | cont.call(ExpressionEvaluator.INSTANCE,ScmList.first(expr),(ScmPairOrNil)((ScmPair)expr).getCdr(),env);
34 | }else{
35 | ScmObject expr2=expr;
36 | while(pointer instanceof ScmPair){
37 | env.add((ScmSymbol)((ScmPair)pointer).getCar(),((ScmPair)expr2).getCar());
38 | pointer=((ScmPair)pointer).getCdr();
39 | expr2=(ScmPairOrNil)((ScmPair)expr2).getCdr();
40 | }
41 | if(pointer instanceof ScmSymbol)
42 | env.add((ScmSymbol)pointer,expr2);
43 | cont.ret((ScmObject)expr);
44 | }
45 | }
46 | }
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/lib/Complex.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.lib;
18 | import com.github.chungkwong.jschememin.*;
19 | import static com.github.chungkwong.jschememin.lib.Utility.cadr;
20 | import static com.github.chungkwong.jschememin.lib.Utility.car;
21 | import com.github.chungkwong.jschememin.type.*;
22 | /**
23 | * Correspoding to the library (scheme complex) in Scheme
24 | * @author Chan Chung Kwong <1m02math@126.com>
25 | */
26 | public class Complex extends NativeLibrary{
27 | public static final Complex INSTANCE=new Complex();
28 | private Complex(){
29 | super("scheme","complex");
30 | }
31 | @Override
32 | protected void init(Library lib){
33 | addNativeProcedure("imag-part",(o)->((ScmComplex)car(o)).getImag());
34 | addNativeProcedure("real-part",(o)->((ScmComplex)car(o)).getReal());
35 | addNativeProcedure("angle",(o)->((ScmComplex)car(o)).getAngle());
36 | addNativeProcedure("magnitude",(o)->((ScmComplex)car(o)).getMagnitude());
37 | addNativeProcedure("make-rectangular",(o)->new ScmComplexRectangular(
38 | ((ScmComplex)car(o)).toScmReal(),((ScmComplex)cadr(o)).toScmReal()));
39 | addNativeProcedure("make-polar",(o)->new ScmComplexPolar(
40 | ((ScmComplex)car(o)).toScmReal(),((ScmComplex)cadr(o)).toScmReal()));
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/lib/NativeProcedureDefault.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.lib;
18 | import com.github.chungkwong.jschememin.type.*;
19 | import java.util.function.*;
20 | /**
21 | * NativeProcedure with default arguments
22 | * @author Chan Chung Kwong <1m02math@126.com>
23 | */
24 | public class NativeProcedureDefault implements NativeProcedure{
25 | private final NativeProcedure proc;
26 | private final Function[] def;
27 | /**
28 | *
29 | * @param proc the NativeProcedure
30 | * @param def the functions being used to generate default argument
31 | */
32 | public NativeProcedureDefault(NativeProcedure proc,Function... def){
33 | this.proc=proc;
34 | this.def=def;
35 | }
36 | @Override
37 | public ScmObject call(ScmObject param) throws Exception{
38 | if(ScmList.getLength(param)
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.primitive;
18 | import com.github.chungkwong.jschememin.*;
19 | import com.github.chungkwong.jschememin.type.*;
20 | /**
21 | * Correspoding to the primitive call/cc in Scheme
22 | * @author Chan Chung Kwong <1m02math@126.com>
23 | */
24 | public class CallWithCurrentContinuation extends BasicConstruct{
25 | public static final CallWithCurrentContinuation INSTANCE=new CallWithCurrentContinuation();
26 | private CallWithCurrentContinuation(){
27 | super(new ScmSymbol("call-with-current-continuation"));
28 | }
29 | @Override
30 | public void call(SchemeEnvironment env,Continuation cont,Object pointer,ScmPairOrNil param){
31 | cont.callTail((Evaluable)ScmList.first(param),ScmList.toList(getRollbackProcedure(cont.getCopy())),env);
32 | }
33 | static final ScmObject getRollbackProcedure(Continuation checkpoint){
34 | return new Evaluable(){
35 | @Override
36 | public void call(SchemeEnvironment env,Continuation cont,Object pointer,ScmPairOrNil param){
37 | cont.reset(checkpoint);
38 | cont.ret((ScmPairOrNil)param);
39 | }
40 | @Override
41 | public String toExternalRepresentation(){
42 | return "roll-back-procedure";
43 | }
44 | };
45 | }
46 | }
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/Main.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong
3 | *
4 | * This program is free software; you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation; either version 3 of the License, or (at
7 | * your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | */
15 | package com.github.chungkwong.jschememin;
16 | import com.github.chungkwong.jschememin.type.*;
17 | import java.io.*;
18 | import java.util.*;
19 | /**
20 | *
21 | * @author Chan Chung Kwong <1m02math@126.com>
22 | */
23 | public class Main {
24 | /**
25 | * Command line arguments given to JSchemeMin
26 | */
27 | public static ScmPairOrNil COMMAND_LINE;
28 | /**
29 | * Entrance to the interpreter
30 | * @param args the command line arguments
31 | */
32 | public static void main(String[] args) {
33 | COMMAND_LINE=(ScmPairOrNil)Arrays.stream(args).map((arg)->new ScmString(arg)).collect(ScmList.COLLECTOR);
34 | if(args.length>=1&&args[0].equals("-d")){
35 | Debugger.main(args);
36 | return;
37 | }
38 | System.out.println("JSchemeMin REPL");
39 | Evaluator eval=new Evaluator(true);
40 | System.out.print("> ");
41 | System.out.flush();
42 | Parser parser=new Parser(new Lex(new InputStreamReader(System.in)));
43 | while(true){
44 | try{
45 | ScmObject d=parser.nextDatum();
46 | if(d==null)
47 | return;
48 | System.out.println("=> "+eval.eval(d));
49 | }catch(RuntimeException ex){
50 | ex.printStackTrace();
51 | }
52 | System.out.print("> ");
53 | System.out.flush();
54 | }
55 | }
56 | /**
57 | * Find a find
58 | * @param path the path to the file
59 | * @return
60 | */
61 | public static File resolveFile(String path){
62 | return new File(path).getAbsoluteFile();
63 | }
64 | }
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/lib/JSchemeMin.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.lib;
18 | import com.github.chungkwong.jschememin.*;
19 | import static com.github.chungkwong.jschememin.lib.Utility.car;
20 | import com.github.chungkwong.jschememin.type.*;
21 | import java.lang.management.*;
22 | /**
23 | * Correspoding to the library (jschememin) in Scheme
24 | * @author Chan Chung Kwong <1m02math@126.com>
25 | */
26 | public class JSchemeMin extends NativeLibrary{
27 | public static final JSchemeMin INSTANCE=new JSchemeMin();
28 | static final NativeProcedure LIBRARY_EXISTS=(o)->ScmBoolean.valueOf(LibraryManager.hasLibrary((ScmPair)car(o)));
29 | private JSchemeMin(){
30 | super("jschememin");
31 | }
32 | @Override
33 | protected void init(Library lib){
34 | addNativeProcedure("library-exists?",LIBRARY_EXISTS);
35 | addNativeProcedure("thread-clock",(o)->ScmInteger.valueOf(ManagementFactory.getThreadMXBean().getCurrentThreadCpuTime()));
36 | addNativeProcedure("memory-total",(o)->ScmInteger.valueOf(Runtime.getRuntime().totalMemory()));
37 | addNativeProcedure("memory-free",(o)->ScmInteger.valueOf(Runtime.getRuntime().freeMemory()));
38 | addDeriveFile("/com/github/chungkwong/jschememin/lib/jschememin_derive.scm",
39 | "duration","count","total-time","profile-lambda","profile-record","profile-records");
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/lib/Write.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.lib;
18 | import com.github.chungkwong.jschememin.*;
19 | import static com.github.chungkwong.jschememin.lib.Utility.cadr;
20 | import static com.github.chungkwong.jschememin.lib.Utility.car;
21 | import com.github.chungkwong.jschememin.type.*;
22 | /**
23 | * Correspoding to the library (scheme write) in Scheme
24 | * @author Chan Chung Kwong <1m02math@126.com>
25 | */
26 | public class Write extends NativeLibrary{
27 | public static final Write INSTANCE=new Write();
28 | private Write(){
29 | super("scheme","write");
30 | }
31 | @Override
32 | protected void init(Library lib){
33 | addNativeProcedure("write",new NativeProcedureDefault((o)->((ScmTextualOutputPort)cadr(o)).write(car(o)),
34 | (o)->car(o),(o)->ScmPort.CURRENT_OUTPUT));
35 | addNativeProcedure("write-shared",new NativeProcedureDefault((o)->((ScmTextualOutputPort)cadr(o)).writeShared(car(o)),
36 | (o)->car(o),(o)->ScmPort.CURRENT_OUTPUT));
37 | addNativeProcedure("write-simple",new NativeProcedureDefault((o)->((ScmTextualOutputPort)cadr(o)).writeSimple(car(o)),
38 | (o)->car(o),(o)->ScmPort.CURRENT_OUTPUT));
39 | addNativeProcedure("display",new NativeProcedureDefault((o)->((ScmTextualOutputPort)cadr(o)).display(car(o)),
40 | (o)->car(o),(o)->ScmPort.CURRENT_OUTPUT));
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/lib/SimpleLibrary.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.lib;
18 | import com.github.chungkwong.jschememin.*;
19 | import com.github.chungkwong.jschememin.type.*;
20 | import java.io.*;
21 | import java.util.*;
22 | import java.util.logging.*;
23 | /**
24 | * Loder for Scheme library mainly written in Scheme
25 | * @author Chan Chung Kwong <1m02math@126.com>
26 | */
27 | public class SimpleLibrary implements LibraryLoader{
28 | private final ScmPair name;
29 | private final String path;
30 | private Library lib=null;
31 | /**
32 | * Construct a SimpleLibrary
33 | * @param path location of the script file
34 | * @param part the name of the library
35 | */
36 | public SimpleLibrary(String path,String... part){
37 | this.name=(ScmPair)Arrays.stream(part).map((n)->new ScmSymbol(n)).collect(ScmList.COLLECTOR);
38 | this.path=path;
39 | }
40 | @Override
41 | public Library getLibrary(){
42 | if(lib==null){
43 | try{
44 | new Evaluator(false).eval(new Parser(new Lex(new InputStreamReader(SimpleLibrary.class.getResourceAsStream(path),"UTF-8"))).nextDatum());
45 | }catch(UnsupportedEncodingException ex){
46 | Logger.getGlobal().log(Level.SEVERE,null,ex);
47 | }
48 | lib=LibraryManager.getLibrary(name);
49 | }
50 | return lib;
51 | }
52 | @Override
53 | public ScmPair getName(){
54 | return name;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/nbproject/project.properties:
--------------------------------------------------------------------------------
1 | #Sun Nov 05 13:13:57 CST 2017
2 | excludes=
3 | javac.deprecation=false
4 | build.test.results.dir=${build.dir}/test/results
5 | javac.external.vm=false
6 | run.classpath=\
7 | ${javac.classpath}:\
8 | ${build.classes.dir}
9 | javadoc.nonavbar=false
10 | run.test.classpath=\
11 | ${javac.test.classpath}:\
12 | ${build.test.classes.dir}
13 | annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
14 | javac.processorpath=\
15 | ${javac.classpath}
16 | javac.target=1.8
17 | annotation.processing.processors.list=
18 | javadoc.noindex=false
19 | javadoc.additionalparam=
20 | includes=**
21 | build.classes.dir=${build.dir}/classes
22 | source.encoding=UTF-8
23 | javadoc.author=false
24 | test.src.dir=test
25 | build.dir=build
26 | build.test.classes.dir=${build.dir}/test/classes
27 | platform.active=default_platform
28 | javac.compilerargs=
29 | main.class=com.github.chungkwong.jschememin.Main
30 | dist.jar=${dist.dir}/JSchemeMin.jar
31 | javac.test.processorpath=${javac.test.classpath}
32 | javadoc.use=true
33 | dist.archive.excludes=
34 | build.sysclasspath=ignore
35 | debug.test.classpath=${run.test.classpath}
36 | dist.dir=dist
37 | build.classes.excludes=**/*.java,**/*.form
38 | javadoc.splitindex=true
39 | javadoc.encoding=${source.encoding}
40 | javac.source=1.8
41 | application.vendor=kwong
42 | junit.selected.version=4
43 | debug.classpath=${run.classpath}
44 | run.jvmargs=
45 | build.generated.dir=${build.dir}/generated
46 | jar.compress=false
47 | javac.test.classpath=\
48 | ${javac.classpath}:\
49 | ${build.classes.dir}:\
50 | ${libs.junit_4.classpath}:\
51 | ${libs.hamcrest.classpath}
52 | javadoc.private=false
53 | project.license=gpl30
54 | annotation.processing.run.all.processors=true
55 | application.title=JSchemeMin
56 | meta.inf.dir=${src.dir}/META-INF
57 | manifest.file=manifest.mf
58 | annotation.processing.enabled=true
59 | dist.javadoc.dir=${dist.dir}/javadoc
60 | src.dir=src
61 | mkdist.disabled=false
62 | endorsed.classpath=
63 | javac.classpath=
64 | annotation.processing.enabled.in.editor=false
65 | build.generated.sources.dir=${build.dir}/generated-sources
66 | javadoc.version=false
67 | javadoc.windowtitle=
68 | javadoc.notree=false
69 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/lib/ProcessContext.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.lib;
18 | import com.github.chungkwong.jschememin.*;
19 | import static com.github.chungkwong.jschememin.lib.Utility.car;
20 | import static com.github.chungkwong.jschememin.lib.Utility.emergencyExit;
21 | import static com.github.chungkwong.jschememin.lib.Utility.exit;
22 | import static com.github.chungkwong.jschememin.lib.Utility.getEnvironmentVariable;
23 | import static com.github.chungkwong.jschememin.lib.Utility.getEnvironmentVariables;
24 | import com.github.chungkwong.jschememin.type.*;
25 | /**
26 | * Correspoding to the library (scheme process-context) in Scheme
27 | * @author Chan Chung Kwong <1m02math@126.com>
28 | */
29 | public class ProcessContext extends NativeLibrary{
30 | public static final ProcessContext INSTANCE=new ProcessContext();
31 | private ProcessContext(){
32 | super("scheme","process-context");
33 | }
34 | @Override
35 | protected void init(Library lib){
36 | addNativeProcedure("command-line",(o)->Main.COMMAND_LINE);
37 | addNativeProcedure("exit",new NativeProcedureDefault((o)->{exit(o);return null;},(o)->ScmBoolean.TRUE));
38 | addNativeProcedure("emergency-exit",new NativeProcedureDefault((o)->{emergencyExit(o);return null;},(o)->ScmBoolean.TRUE));
39 | addNativeProcedure("get-environment-variable",(o)->getEnvironmentVariable((ScmString)car(o)));
40 | addNativeProcedure("get-environment-variables",(o)->getEnvironmentVariables());
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/lib/Load.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.lib;
18 | import com.github.chungkwong.jschememin.*;
19 | import static com.github.chungkwong.jschememin.lib.Utility.cadr;
20 | import static com.github.chungkwong.jschememin.lib.Utility.car;
21 | import static com.github.chungkwong.jschememin.lib.Utility.getInteractiveEnvironment;
22 | import com.github.chungkwong.jschememin.type.*;
23 | import java.io.*;
24 | /**
25 | * Correspoding to the library (scheme load) in Scheme
26 | * @author Chan Chung Kwong <1m02math@126.com>
27 | */
28 | public class Load extends NativeLibrary{
29 | public static final Load INSTANCE=new Load();
30 | private static final ScmSymbol BEGIN=new ScmSymbol("begin");
31 | private Load(){
32 | super("scheme","load");
33 | }
34 | @Override
35 | protected void init(Library lib){
36 | addNativeProcedure("load",new NativeProcedureDefault((o)->load(((ScmString)car(o)).getValue(),(SchemeEnvironment)cadr(o)),
37 | (o)->car(o),(o)->getInteractiveEnvironment()));
38 | }
39 | private static ScmObject load(String filename,SchemeEnvironment env){
40 | ScmPair content;
41 | try{
42 | Parser parser=new Parser(new Lex(new InputStreamReader(new FileInputStream(Main.resolveFile(filename)),"UTF-8"),false));
43 | content=new ScmPair(BEGIN,ScmList.toList(parser.getRemainingDatums()));
44 | }catch(FileNotFoundException|UnsupportedEncodingException ex){
45 | throw new RuntimeException();
46 | }
47 | return new Evaluator(env).eval(content);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/type/ScmListBuilder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.type;
18 |
19 | /**
20 | * A helper that may construct list by reverse order in the structure
21 | * @author Chan Chung Kwong <1m02math@126.com>
22 | */
23 | public class ScmListBuilder{
24 | private ScmObject start=ScmNil.NIL;
25 | private ScmPair end=null;
26 | /**
27 | * Prepare for a list
28 | */
29 | public ScmListBuilder(){
30 |
31 | }
32 | /**
33 | * Provides a item to be added
34 | * @param item
35 | */
36 | public void add(ScmObject item){
37 | ScmPair fresh=new ScmPair(item,ScmNil.NIL);
38 | if(end==null){
39 | start=end=fresh;
40 | }else{
41 | end.setCdr(fresh);
42 | end=fresh;
43 | }
44 | }
45 | /**
46 | * Provides some items to be added
47 | * @param list
48 | */
49 | public void addAll(ScmPairOrNil list){
50 | ScmList.forEach(list,(item)->add(item));
51 | }
52 | /**
53 | * Provides some items to be added
54 | * @param buf
55 | */
56 | public void addAll(ScmListBuilder buf){
57 | if(end==null){
58 | start=buf.start;
59 | end=buf.end;
60 | }else if(buf.end!=null){
61 | end.setCdr(buf.start);
62 | end=buf.end;
63 | }
64 | }
65 | /**
66 | * Set the last item in a partial list
67 | * @param obj
68 | */
69 | public void setLast(ScmObject obj){
70 | if(end==null)
71 | start=obj;
72 | else
73 | end.setCdr(obj);
74 | }
75 | /**
76 | * Build the list
77 | * @return the list
78 | */
79 | public ScmObject toList(){
80 | return start;
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/primitive/Include.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.primitive;
18 | import com.github.chungkwong.jschememin.*;
19 | import com.github.chungkwong.jschememin.type.*;
20 | import java.io.*;
21 | /**
22 | * Correspoding to the primitive include in Scheme
23 | * @author Chan Chung Kwong <1m02math@126.com>
24 | */
25 | public class Include extends BasicConstruct implements Primitive{
26 | public static final Include INSTANCE=new Include("include",false);
27 | public static final Include INSTANCE_CI=new Include("include-ci",true);
28 | private final boolean foldingCase;
29 | private Include(String name,boolean foldingCase){
30 | super(new ScmSymbol(name));
31 | this.foldingCase=foldingCase;
32 | }
33 | @Override
34 | public void call(SchemeEnvironment env,Continuation cont,Object pointer,ScmPairOrNil expr){
35 | cont.callTail(ExpressionEvaluator.INSTANCE,getFileContent((ScmPair)expr),env);
36 | }
37 | ScmObject getFileContent(ScmPair files){
38 | ScmListBuilder buf=new ScmListBuilder();
39 | buf.add(new ScmSymbol("begin"));
40 | ScmList.forEach(files,(file)->appendContent(((ScmString)file).getValue(),buf));
41 | return buf.toList();
42 | }
43 | private void appendContent(String file,ScmListBuilder buf){
44 | try{
45 | Parser parser=new Parser(new Lex(new InputStreamReader(new FileInputStream(Main.resolveFile(file)),"UTF-8"),foldingCase));
46 | ScmObject datum;
47 | while((datum=parser.nextDatum())!=null)
48 | buf.add(datum);
49 | }catch(FileNotFoundException|UnsupportedEncodingException ex){
50 | throw new RuntimeException();
51 | }
52 | }
53 |
54 | }
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/JavaEnvironment.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2017 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin;
18 | import com.github.chungkwong.jschememin.type.*;
19 | import java.util.*;
20 | import javax.script.*;
21 | /**
22 | * Environment backed by ScriptContext
23 | *
24 | * @author Chan Chung Kwong <1m02math@126.com>
25 | */
26 | public class JavaEnvironment extends Environment{
27 | private final ScriptContext parent;
28 | /**
29 | * Create a new environment
30 | *
31 | * @param parent the backed ScriptContext
32 | * @param repl REPL mode or not
33 | */
34 | public JavaEnvironment(ScriptContext parent,boolean repl){
35 | super(repl);
36 | this.parent=parent;
37 | }
38 | @Override
39 | public Optional getOptional(ScmSymbol id){
40 | return Optional.ofNullable(getSelfOptional(id));
41 | }
42 | @Override
43 | public ScmObject getSelfOptional(ScmSymbol id){
44 | return ScmJavaObject.toScmObject(parent.getAttribute(id.getValue()));
45 | }
46 | @Override
47 | public void set(ScmSymbol id,ScmObject obj){
48 | int scope=parent.getAttributesScope(id.getValue());
49 | if(scope!=-1){
50 | parent.setAttribute(id.getValue(),ScmJavaObject.toJavaObject(obj),scope);
51 | }
52 | if(isREPL()){
53 | add(id,obj);
54 | }
55 | }
56 | @Override
57 | public void add(ScmSymbol id,ScmObject obj){
58 | parent.setAttribute(id.getValue(),ScmJavaObject.toJavaObject(obj),parent.getScopes().get(0));
59 | }
60 | @Override
61 | public void remove(ScmSymbol id){
62 | int scope=parent.getAttributesScope(id.getValue());
63 | if(scope!=-1){
64 | parent.removeAttribute(id.getValue(),scope);
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/primitive/Define.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.primitive;
18 | import com.github.chungkwong.jschememin.*;
19 | import com.github.chungkwong.jschememin.type.*;
20 | import java.util.*;
21 | /**
22 | * Correspoding to the primitive define in Scheme
23 | * @author Chan Chung Kwong <1m02math@126.com>
24 | */
25 | public class Define extends BasicConstruct implements Primitive{
26 | public static final Define INSTANCE=new Define();
27 | private Define(){
28 | super(new ScmSymbol("define"));
29 | }
30 | @Override
31 | public void call(SchemeEnvironment env,Continuation cont,Object pointer,ScmPairOrNil expr){
32 | if(pointer==null){
33 | ScmPair remain=(ScmPair)expr;
34 | if(remain.getCar() instanceof ScmSymbol){
35 | Optional old=env.getOptional((ScmSymbol)remain.getCar());
36 | if(!old.isPresent()||isSyntax(old.get()))
37 | env.add((ScmSymbol)remain.getCar(),ScmNil.NIL);
38 | cont.replaceCurrent(this);
39 | cont.call(ExpressionEvaluator.INSTANCE,(ScmSymbol)remain.getCar(),((ScmPair)remain.getCdr()).getCar(),env);
40 | }else if(remain.getCar() instanceof ScmPair){
41 | ScmSymbol name=(ScmSymbol)((ScmPair)remain.getCar()).getCar();
42 | ScmProcedure proc=new ScmProcedure(((ScmPair)remain.getCar()).getCdr(),(ScmPair)remain.getCdr(),env);
43 | env.add(name,proc);
44 | cont.ret(proc);
45 | }else
46 | throw new SyntaxException();
47 | }else{
48 | env.add((ScmSymbol)pointer,ScmList.first(expr));
49 | cont.ret(expr);
50 | }
51 | }
52 | private static boolean isSyntax(ScmObject obj){
53 | return obj instanceof ScmSyntaxRules||obj instanceof Primitive;
54 | }
55 | }
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/primitive/DefineRecordType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.primitive;
18 | import com.github.chungkwong.jschememin.*;
19 | import com.github.chungkwong.jschememin.type.*;
20 | /**
21 | * Correspoding to the primitive define-record-type in Scheme
22 | * @author Chan Chung Kwong <1m02math@126.com>
23 | */
24 | public class DefineRecordType extends BasicConstruct implements Primitive{
25 | public static final DefineRecordType INSTANCE=new DefineRecordType();
26 | private DefineRecordType(){
27 | super(new ScmSymbol("define-record-type"));
28 | }
29 | @Override
30 | public void call(SchemeEnvironment env,Continuation cont,Object pointer,ScmPairOrNil param){
31 | ScmSymbol name=(ScmSymbol)ScmList.first(param);
32 | param=(ScmPairOrNil)((ScmPair)param).getCdr();
33 | ScmPair constructor=(ScmPair)ScmList.first(param);
34 | ScmRecordType type=new ScmRecordType(name,constructor.getCdr());
35 | env.add((ScmSymbol)constructor.getCar(),type.getConstractor());
36 | param=(ScmPairOrNil)((ScmPair)param).getCdr();
37 | env.add((ScmSymbol)ScmList.first(param),type.getPredicate());
38 | param=(ScmPairOrNil)((ScmPair)param).getCdr();
39 | while(param instanceof ScmPair){
40 | ScmPair field=(ScmPair)ScmList.first(param);
41 | ScmSymbol fieldname=(ScmSymbol)field.getCar();
42 | field=(ScmPair)field.getCdr();
43 | env.add((ScmSymbol)field.getCar(),type.getAccessor(fieldname));
44 | if(field.getCdr() instanceof ScmPair){
45 | env.add((ScmSymbol)((ScmPair)field.getCdr()).getCar(),type.getModifier(fieldname));
46 | }
47 | param=(ScmPairOrNil)((ScmPair)param).getCdr();
48 | }
49 | cont.ret(type);
50 | }
51 | }
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/type/ScmComplexPolar.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong
3 | *
4 | * This program is free software; you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation; either version 3 of the License, or (at
7 | * your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | */
15 | package com.github.chungkwong.jschememin.type;
16 | /**
17 | * Represents some complex number in Scheme
18 | * @author Chan Chung Kwong <1m02math@126.com>
19 | */
20 | public class ScmComplexPolar extends ScmComplex{
21 | private static final ScmFloatingPointNumber TWOPI=ScmFloatingPointNumber.PI.multiply(ScmInteger.TWO.toInExact());
22 | private static final ScmInteger THREE=new ScmInteger(3);
23 | private final ScmReal abs,radius;
24 | /**
25 | * Construct a complex number
26 | * @param abs
27 | * @param radius
28 | */
29 | public ScmComplexPolar(ScmReal abs,ScmReal radius){
30 | this.abs=abs;
31 | if(abs.isZero()){
32 | this.radius=ScmInteger.ZERO;
33 | }else if(radius instanceof ScmSpecialReal||ScmReal.lessEquals(radius.getMagnitude(),THREE)){
34 | this.radius=radius;
35 | }else{
36 | this.radius=radius.subtract(((ScmFloatingPointNumber)radius.divide(TWOPI)).round().multiply(TWOPI));
37 | }
38 | }
39 | @Override
40 | public ScmReal getAngle(){
41 | return radius;
42 | }
43 | @Override
44 | public ScmReal getMagnitude(){
45 | return abs;
46 | }
47 | @Override
48 | public ScmReal getImag(){
49 | return radius.equals(ScmInteger.ZERO)?ScmInteger.ZERO:abs.multiply(radius.sin());
50 | }
51 | @Override
52 | public ScmReal getReal(){
53 | return radius.equals(ScmInteger.ZERO)?abs:abs.multiply(radius.cos());
54 | }
55 | @Override
56 | public String toExternalRepresentation(int radix){
57 | return abs.toExternalRepresentation(radix)+"@"+radius.toExternalRepresentation(radix);
58 | }
59 | @Override
60 | public boolean isZero(){
61 | return abs.isZero();
62 | }
63 | @Override
64 | public boolean isFinite(){
65 | return abs.isFinite();
66 | }
67 | @Override
68 | public boolean isInfinite(){
69 | return abs.isInfinite();
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/lib/File.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.lib;
18 | import com.github.chungkwong.jschememin.*;
19 | import static com.github.chungkwong.jschememin.lib.Utility.car;
20 | import com.github.chungkwong.jschememin.type.*;
21 | /**
22 | * Correspoding to the library (scheme file) in Scheme
23 | * @author Chan Chung Kwong <1m02math@126.com>
24 | */
25 | public class File extends NativeLibrary{
26 | public static final File INSTANCE=new File();
27 | private File(){
28 | super("scheme","file");
29 | }
30 | @Override
31 | protected void init(Library lib){
32 | addNativeProcedure("file-exists?",(o)->ScmBoolean.valueOf(Main.resolveFile(((ScmString)car(o)).getValue()).exists()));
33 | addNativeProcedure("file-delete",(o)->{
34 | java.io.File file=Main.resolveFile(((ScmString)car(o)).getValue());
35 | if(file.exists()&&file.delete())
36 | return ScmBoolean.TRUE;
37 | else
38 | throw ScmError.toException(new ScmError(new ScmString("Failed to delete file"),ScmList.toList(car(o)),ScmError.ErrorType.FILE));
39 | });
40 | addNativeProcedure("open-input-file",(o)->new ScmTextualInputPort(((ScmString)car(o)).getValue()));
41 | addNativeProcedure("open-binary-input-file",(o)->new ScmBinaryInputPort(((ScmString)car(o)).getValue()));
42 | addNativeProcedure("open-output-file",(o)->new ScmTextualOutputPort(((ScmString)car(o)).getValue()));
43 | addNativeProcedure("open-binary-output-file",(o)->new ScmBinaryOutputPort(((ScmString)car(o)).getValue()));
44 | addDeriveFile("/com/github/chungkwong/jschememin/lib/file_derive.scm","call-with-input-file",
45 | "call-with-output-file","with-input-from-file","with-output-to-file");
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/type/ScmComplexRectangular.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong
3 | *
4 | * This program is free software; you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation; either version 3 of the License, or (at
7 | * your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | */
15 | package com.github.chungkwong.jschememin.type;
16 | /**
17 | * Represents some complex number in Scheme
18 | * @author Chan Chung Kwong <1m02math@126.com>
19 | */
20 | public class ScmComplexRectangular extends ScmComplex{
21 | public static final ScmComplexRectangular I=new ScmComplexRectangular(ScmInteger.ZERO,ScmInteger.ONE);
22 | private final ScmReal real,imag;
23 | /**
24 | * Construct a complex number
25 | * @param real
26 | * @param imag
27 | */
28 | public ScmComplexRectangular(ScmReal real,ScmReal imag){
29 | this.real=real;
30 | this.imag=imag;
31 | }
32 | @Override
33 | public ScmReal getReal(){
34 | return real;
35 | }
36 | @Override
37 | public ScmReal getImag(){
38 | return imag;
39 | }
40 | @Override
41 | public ScmReal getMagnitude(){
42 | return real.multiply(real).add(imag.multiply(imag)).sqrt().toScmReal();
43 | }
44 | @Override
45 | public ScmReal getAngle(){
46 | if(real.isPositive()&&imag.isZero())
47 | return ScmInteger.ZERO;
48 | else
49 | return ScmFloatingPointNumber.valueOf(Math.atan2(ScmFloatingPointNumber.toDouble(imag)
50 | ,ScmFloatingPointNumber.toDouble(real)));
51 | }
52 | @Override
53 | public boolean isZero(){
54 | return real.isZero()&&imag.isZero();
55 | }
56 | @Override
57 | public boolean isFinite(){
58 | return real.isFinite()&&imag.isFinite();
59 | }
60 | @Override
61 | public boolean isInfinite(){
62 | return real.isInfinite()||imag.isInfinite();
63 | }
64 | @Override
65 | public String toExternalRepresentation(int radix){
66 | StringBuilder buf=new StringBuilder();
67 | buf.append(real.toExternalRepresentation(radix));
68 | if(imag.needPlusSign())
69 | buf.append('+');
70 | buf.append(imag.toExternalRepresentation(radix));
71 | buf.append("i");
72 | return buf.toString();
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/type/ScmRecord.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.type;
18 | import java.util.*;
19 | /**
20 | * Represents records in Scheme
21 | * @author Chan Chung Kwong <1m02math@126.com>
22 | */
23 | public class ScmRecord extends ScmObject{
24 | private final ScmRecordType type;
25 | private final ScmObject[] fields;
26 | /**
27 | * Create a record
28 | * @param type the type of the record
29 | * @param fields the fields that the record have
30 | */
31 | public ScmRecord(ScmRecordType type,ScmObject[] fields){
32 | this.type=type;
33 | this.fields=fields;
34 | }
35 | ScmObject get(int i){
36 | return fields[i];
37 | }
38 | void set(int i,ScmObject obj){
39 | fields[i]=obj;
40 | }
41 | /**
42 | * Get the type of the record
43 | * @return the type
44 | */
45 | public ScmRecordType getType(){
46 | return type;
47 | }
48 | @Override
49 | public String toExternalRepresentation(){
50 | ScmListBuilder buf=new ScmListBuilder();
51 | buf.add(type.getName());
52 | type.indices.forEach((key,value)->buf.add(new ScmPair(key,fields[value])));
53 | return buf.toList().toString();
54 | }
55 | @Override
56 | public boolean isSelfevaluating(){
57 | return false;
58 | }
59 | @Override
60 | public boolean equals(Object obj){
61 | return obj instanceof ScmRecord&&((ScmRecord)obj).type.equals(type)
62 | &&Arrays.equals(((ScmRecord)obj).fields,fields);
63 | }
64 | @Override
65 | public boolean equalsValue(ScmObject obj){
66 | return this==obj;
67 | }
68 | @Override
69 | public int hashCode(){
70 | int hash=5;
71 | hash=83*hash+Objects.hashCode(this.type);
72 | hash=83*hash+Arrays.deepHashCode(this.fields);
73 | return hash;
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/type/ObjectPair.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.type;
18 | import java.util.*;
19 | /**
20 | *
21 | * @author Chan Chung Kwong <1m02math@126.com>
22 | */
23 | class ObjectPair{
24 | private final Object car,cdr;
25 | private ObjectPair(Object car,Object cdr){
26 | this.car=car;
27 | this.cdr=cdr;
28 | }
29 | @Override
30 | public boolean equals(Object obj){
31 | return obj instanceof ObjectPair&&((ObjectPair)obj).car==car&&((ObjectPair)obj).cdr==cdr;
32 | }
33 | @Override
34 | public int hashCode(){
35 | int hash=7;
36 | hash=23*hash+System.identityHashCode(car);
37 | hash=23*hash+System.identityHashCode(cdr);
38 | return hash;
39 | }
40 | static boolean equals(Object a,Object b,HashSet found){
41 | if(a instanceof ScmPair&&b instanceof ScmPair){
42 | ScmPair c=(ScmPair)a,d=(ScmPair)b;
43 | ObjectPair pair=new ObjectPair(a,b);
44 | if(found.contains(pair))
45 | return true;
46 | else{
47 | found.add(pair);
48 | return equals(c.getCar(),d.getCar(),found)&&equals(c.getCdr(),d.getCdr(),found);
49 | }
50 | }else if(a instanceof ScmVector&& b instanceof ScmVector){
51 | ScmVector c=(ScmVector)a,d=(ScmVector)b;
52 | ObjectPair pair=new ObjectPair(a,b);
53 | if(found.contains(pair))
54 | return true;
55 | else{
56 | found.add(pair);
57 | if(c.getLength()==d.getLength())
58 | for(int i=0;i
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.lib;
18 | import com.github.chungkwong.jschememin.*;
19 | import static com.github.chungkwong.jschememin.lib.Utility.cadr;
20 | import static com.github.chungkwong.jschememin.lib.Utility.car;
21 | import static com.github.chungkwong.jschememin.lib.Utility.cdr;
22 | import com.github.chungkwong.jschememin.type.*;
23 | /**
24 | * Correspoding to the library (scheme inexact) in Scheme
25 | * @author Chan Chung Kwong <1m02math@126.com>
26 | */
27 | public class Inexact extends NativeLibrary{
28 | public static final Inexact INSTANCE=new Inexact();
29 | private Inexact(){
30 | super("scheme","inexact");
31 | }
32 | @Override
33 | protected void init(Library lib){
34 | addNativeProcedure("finite?",(o)->ScmBoolean.valueOf(((ScmComplex)car(o)).isFinite()));
35 | addNativeProcedure("infinite?",(o)->ScmBoolean.valueOf(((ScmComplex)car(o)).isInfinite()));
36 | addNativeProcedure("nan?",(o)->ScmBoolean.valueOf(((ScmComplex)car(o)).isNaN()));
37 | addNativeProcedure("log",(o)->cdr(o)instanceof ScmNil?((ScmComplex)car(o)).log():((ScmComplex)car(o)).log((ScmComplex)cadr(o)));
38 | addNativeProcedure("exp",(o)->((ScmComplex)car(o)).exp());
39 | addNativeProcedure("sin",(o)->((ScmComplex)car(o)).sin());
40 | addNativeProcedure("cos",(o)->((ScmComplex)car(o)).cos());
41 | addNativeProcedure("tan",(o)->((ScmComplex)car(o)).tan());
42 | addNativeProcedure("asin",(o)->((ScmComplex)car(o)).arcsin());
43 | addNativeProcedure("acos",(o)->((ScmComplex)car(o)).arccos());
44 | addNativeProcedure("atan",new NativeProcedureDefault(
45 | (o)->new ScmComplexRectangular(((ScmComplex)cadr(o)).toScmReal(),((ScmComplex)car(o)).toScmReal()).getAngle(),
46 | (o)->car(o),(o)->ScmInteger.ONE));
47 | addNativeProcedure("sqrt",(o)->((ScmComplex)car(o)).sqrt());
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/primitive/DynamicWind.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.primitive;
18 | import com.github.chungkwong.jschememin.*;
19 | import com.github.chungkwong.jschememin.type.*;
20 | /**
21 | * Correspoding to the primitive dynamic-wind in Scheme
22 | * @author Chan Chung Kwong <1m02math@126.com>
23 | */
24 | public class DynamicWind extends BasicConstruct{
25 | public static final DynamicWind INSTANCE=new DynamicWind();
26 | private DynamicWind(){
27 | super(new ScmSymbol("dynamic-wind"));
28 | }
29 | @Override
30 | public void call(SchemeEnvironment env,Continuation cont,Object pointer,ScmPairOrNil param){
31 | if(pointer==null){
32 | Backtrack track=new Backtrack((Evaluable)ScmList.first(param),
33 | (Evaluable)ScmList.second(param),(Evaluable)ScmList.third(param),false);
34 | cont.call(track.getBefore(),track,ScmNil.NIL,env);
35 | }else if(pointer instanceof Backtrack){
36 | Backtrack old=(Backtrack)pointer;
37 | if(old.isStarted())
38 | cont.call(((Backtrack)pointer).getAfter(),param,ScmNil.NIL,env);
39 | else
40 | cont.call(((Backtrack)pointer).getThunk(),new Backtrack(old.getBefore(),old.getThunk(),old.getAfter(),true),ScmNil.NIL,env);
41 | }else{
42 | cont.ret((ScmPairOrNil)pointer);
43 | }
44 | }
45 | public static class Backtrack{
46 | private final Evaluable before;
47 | private final Evaluable thunk;
48 | private final Evaluable after;
49 | private final boolean started;
50 | public Backtrack(Evaluable before,Evaluable thunk,Evaluable after,boolean started){
51 | this.before=before;
52 | this.thunk=thunk;
53 | this.after=after;
54 | this.started=started;
55 | }
56 | public Evaluable getBefore(){
57 | return before;
58 | }
59 | public Evaluable getThunk(){
60 | return thunk;
61 | }
62 | public Evaluable getAfter(){
63 | return after;
64 | }
65 | public boolean isStarted(){
66 | return started;
67 | }
68 | }
69 | }
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/Evaluator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin;
18 | import com.github.chungkwong.jschememin.type.*;
19 | import java.io.*;
20 | import javax.script.*;
21 | /**
22 | * Evaluator for Scheme
23 | * @author Chan Chung Kwong <1m02math@126.com>
24 | */
25 | public class Evaluator extends AbstractScriptEngine{
26 | private final SchemeEnvironment env;
27 | /**
28 | * Create a evaluator
29 | * @param repl REPL mode or not
30 | */
31 | public Evaluator(boolean repl){
32 | this(new SchemeEnvironment(repl));
33 | }
34 | /**
35 | * Create a evaluator
36 | * @param env top-level environemnt
37 | */
38 | public Evaluator(SchemeEnvironment env){
39 | this.env=env;
40 | }
41 | /**
42 | * Evaluate a expression
43 | * @param expr the expression
44 | * @return the value
45 | */
46 | public ScmObject eval(ScmObject expr){
47 | Continuation cont=new Continuation();
48 | cont.callInit(ExpressionEvaluator.INSTANCE,expr,env);
49 | while(cont.hasNext())
50 | cont.evalNext();
51 | return cont.getCurrentValue();
52 | }
53 | /**
54 | * Get the top level environment
55 | * @return
56 | */
57 | public SchemeEnvironment getEnvironment(){
58 | return env;
59 | }
60 | @Override
61 | public Object eval(String script,ScriptContext context) throws ScriptException{
62 | return eval(new StringReader(script),context);
63 | }
64 | @Override
65 | public Object eval(Reader reader,ScriptContext context) throws ScriptException{
66 | Parser parser=new Parser(new Lex(reader));
67 | env.setParent(new JavaEnvironment(context,env.isREPL()));
68 | ScmObject datum,ret=null;
69 | while((datum=parser.nextDatum())!=null){
70 | ret=eval(datum);
71 | }
72 | return ret;
73 | }
74 | @Override
75 | public Bindings createBindings(){
76 | Bindings bindings=new SimpleBindings();
77 | return bindings;
78 | }
79 | @Override
80 | public ScriptEngineFactory getFactory(){
81 | return EvaluatorFactory.INSTANCE;
82 | }
83 | }
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/lib/r5rs.scm:
--------------------------------------------------------------------------------
1 | (define-library (scheme r5rs)
2 | (import (scheme base) (scheme char) (scheme complex) (scheme cxr) (scheme eval) (scheme file) (scheme inexact) (scheme load))
3 | (export * + - / < <= = > >= abs acos and angle append apply asin assoc assq assv atan
4 | begin boolean? caaaar caaadr caaar caadar caaddr caadr caar cadaar cadadr cadar caddar cadddr caddr cadr
5 | call-with-current-continuation call-with-input-file call-with-output-file call-with-values
6 | car case cdaaar cdaadr cdaar cdadar cdaddr cdadr cdar cddaar cddadr cddar cdddar cddddr cdddr cddr cdr
7 | ceiling char->integer char-alphabetic? char-ci<=? char-ci char-ci=? char-ci>=? char-ci>?
8 | char-downcase char-lower-case? char-numeric? char-ready? char-upcase char-upper-case? char-whitespace?
9 | char<=? char char=? char>=? char>? char? close-input-port close-output-port complex? cond cons cos
10 | current-input-port current-output-port define define-syntax delay denominator display do dynamic-wind
11 | eof-object? eq? equal? eqv? eval even? (rename inexact exact->inexact) exact? exp expt floor for-each force
12 | gcd if imag-part (rename exact inexact->exact) inexact? input-port? integer->char integer?
13 | interaction-environment lambda lcm length let let* let-syntax letrec letrec-syntax list list->string
14 | list->vector list-ref list-tail list? load log magnitude make-polar make-rectangular make-string make-vector
15 | map max member memq memv min modulo negative? newline not null? number->string number? numerator
16 | odd? open-input-file open-output-file or output-port? pair? peek-char positive? procedure?
17 | quasiquote quote quotient rational? rationalize read read-char real-part real? remainder reverse round
18 | set! set-car! set-cdr! sin sqrt string string->list string->number string->symbol string-append
19 | string-ci<=? string-ci string-ci=? string-ci>=? string-ci>? string-copy string-fill! string-length
20 | string-ref string-set! string<=? string string=? string>=? string>? string? substring
21 | symbol->string symbol? tan truncate values vector vector->list vector-fill! vector-length vector-ref
22 | vector-set! vector? with-input-from-file with-output-to-file write write-char zero?
23 | null-environment scheme-report-environment)
24 | (begin
25 | (define (null-environment version) (case version
26 | ((5) (environment '(scheme null)))
27 | (else (raise 'not5))))
28 | (define (scheme-report-environment version) (case version ((5) (environment '(scheme r5rs))) (else (raise 'not5))))))
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/Library.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin;
18 | import com.github.chungkwong.jschememin.type.*;
19 | import java.util.*;
20 | /**
21 | * Library in scheme
22 | * @author Chan Chung Kwong <1m02math@126.com>
23 | */
24 | public class Library extends ScmObject{
25 | private final ScmPair name;
26 | private final HashMap export;
27 | private final SchemeEnvironment internal;
28 | /**
29 | * Create a library
30 | * @param name the name
31 | * @param export the export name mapping
32 | * @param internal internal environment
33 | */
34 | public Library(ScmPair name,HashMap export,SchemeEnvironment internal){
35 | this.name=name;
36 | this.export=export;
37 | this.internal=internal;
38 | LibraryManager.addLibrary(this);
39 | }
40 | /**
41 | * Get the name
42 | * @return
43 | */
44 | public ScmPair getName(){
45 | return name;
46 | }
47 | /**
48 | * Get the exported names
49 | * @return
50 | */
51 | public Set getExportSet(){
52 | return export.keySet();
53 | }
54 | /**
55 | * Get the export name mapping
56 | * @return
57 | */
58 | public HashMap getExportMap(){
59 | return export;
60 | }
61 | /**
62 | * Export the library to a environment
63 | * @param env
64 | */
65 | public void exportTo(Environment env){
66 | export.forEach((ex,im)->env.add(ex,internal.get(im)));
67 | }
68 | /**
69 | * Export some names in the library to a environment
70 | * @param env
71 | * @param importset
72 | */
73 | public void exportTo(Environment env,HashMap importset){
74 | importset.forEach((ex,im)->env.add(im,internal.get(export.get(ex))));
75 | }
76 | /**
77 | * Get the internal environment
78 | * @return
79 | */
80 | public SchemeEnvironment getInternalEnvironment(){
81 | return internal;
82 | }
83 | @Override
84 | public String toExternalRepresentation(){
85 | return name.toString();
86 | }
87 | @Override
88 | public boolean isSelfevaluating(){
89 | return false;
90 | }
91 | }
--------------------------------------------------------------------------------
/test/com/github/chungkwong/jschememin/lib-example.scm:
--------------------------------------------------------------------------------
1 | (define-library (example grid)
2 | (export make rows cols ref each
3 | (rename put! set!))
4 | (import (scheme base))
5 | (begin
6 | ;; Create an NxM grid.
7 | (define (make n m)
8 | (let ((grid (make-vector n)))
9 | (do ((i 0 (+ i 1)))
10 | ((= i n) grid)
11 | (let ((v (make-vector m #f)))
12 | (vector-set! grid i v)))))
13 | (define (rows grid)
14 | (vector-length grid))
15 | (define (cols grid)
16 | (vector-length (vector-ref grid 0)))
17 | ;; Return #f if out of range.
18 | (define (ref grid n m)
19 | (and (< -1 n (rows grid))
20 | (< -1 m (cols grid))
21 | (vector-ref (vector-ref grid n) m)))
22 | (define (put! grid n m v)
23 | (vector-set! (vector-ref grid n) m v))
24 | (define (each grid proc)
25 | (do ((j 0 (+ j 1)))
26 | ((= j (rows grid)))
27 | (do ((k 0 (+ k 1)))
28 | ((= k (cols grid)))
29 | (proc j k (ref grid j k)))))))
30 |
31 | (define-library (example life)
32 | (export life)
33 | (import (except (scheme base) set!)
34 | (scheme write)
35 | (example grid))
36 | (begin
37 | (define (life-count grid i j)
38 | (define (count i j)
39 | (if (ref grid i j) 1 0))
40 | (+ (count (- i 1) (- j 1))
41 | (count (- i 1) j)
42 | (count (- i 1) (+ j 1))
43 | (count i (- j 1))
44 | (count i (+ j 1))
45 | (count (+ i 1) (- j 1))
46 | (count (+ i 1) j)
47 | (count (+ i 1) (+ j 1))))
48 | (define (life-alive? grid i j)
49 | (case (life-count grid i j)
50 | ((3) #t)
51 | ((2) (ref grid i j))
52 | (else #f)))
53 | (define (life-print grid)
54 | (each grid
55 | (lambda (i j v)
56 | (display (if v "*" " "))
57 | (when (= j (- (cols grid) 1))
58 | (newline)))))
59 | (define (life grid iterations)
60 | (do ((i 0 (+ i 1))
61 | (grid0 grid grid1)
62 | (grid1 (make (rows grid) (cols grid))
63 | grid0))
64 | ((= i iterations))
65 | (each grid0
66 | (lambda (j k v)
67 | (let ((a (life-alive? grid0 j k)))
68 | (set! grid1 j k a))))
69 | (life-print grid1)))))
70 |
71 | ;; Main program.
72 | (import (scheme base)
73 | (only (example life) life)
74 | (rename (prefix (example grid) grid-)
75 | (grid-make make-grid)))
76 |
77 | ;; Initialize a grid with a glider.
78 | (define grid (make-grid 5 6))
79 | (grid-set! grid 1 1 #t)
80 | (grid-set! grid 2 2 #t)
81 | (grid-set! grid 3 0 #t)
82 | (grid-set! grid 3 1 #t)
83 | (grid-set! grid 3 2 #t)
84 |
85 | ;; Run for 80 iterations.
86 | (life grid 3)
87 | (flush-output-port)
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/type/ScmNormalReal.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.type;
18 |
19 | /**
20 | * Represents most reals in Scheme
21 | * @author Chan Chung Kwong <1m02math@126.com>
22 | */
23 | public abstract class ScmNormalReal extends ScmReal implements Comparable{
24 | @Override
25 | public abstract ScmNormalReal negate();
26 | @Override
27 | public abstract ScmNormalReal floor();
28 | @Override
29 | public abstract ScmNormalReal ceiling();
30 | @Override
31 | public abstract ScmNormalReal truncate();
32 | @Override
33 | public abstract ScmNormalReal round();
34 | public abstract int signum();
35 | @Override
36 | public abstract ScmFloatingPointNumber toInExact();
37 | @Override
38 | public boolean isZero(){
39 | return signum()==0;
40 | }
41 | @Override
42 | public boolean isPositive(){
43 | return signum()>0;
44 | }
45 | @Override
46 | public boolean isNegative(){
47 | return signum()<0;
48 | }
49 | @Override
50 | public ScmComplex log(){
51 | return toInExact().log();
52 | }
53 | @Override
54 | public ScmComplex sqrt(){
55 | return toInExact().sqrt();
56 | }
57 | @Override
58 | public ScmReal exp(){
59 | return toInExact().exp();
60 | }
61 | @Override
62 | public ScmReal sin(){
63 | return toInExact().sin();
64 | }
65 | @Override
66 | public ScmReal cos(){
67 | return toInExact().cos();
68 | }
69 | @Override
70 | public ScmReal getAngle(){
71 | int sign=signum();
72 | if(sign>0)
73 | return ScmInteger.ZERO;
74 | else if(sign<0)
75 | return ScmFloatingPointNumber.PI;
76 | else
77 | return ScmSpecialReal.POSITIVE_NAN;
78 | }
79 | @Override
80 | public boolean isFinite(){
81 | return true;
82 | }
83 | @Override
84 | public boolean isInfinite(){
85 | return false;
86 | }
87 | @Override
88 | public boolean isRational(){
89 | return true;
90 | }
91 | @Override
92 | public boolean isInteger(){
93 | return equals(truncate());
94 | }
95 | @Override
96 | public double toDouble(){
97 | return toInExact().getValue().doubleValue();
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/SchemeEnvironment.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin;
18 | import com.github.chungkwong.jschememin.lib.*;
19 | import com.github.chungkwong.jschememin.primitive.*;
20 | import com.github.chungkwong.jschememin.type.*;
21 | import java.util.*;
22 | /**
23 | * Standard environment
24 | * @author Chan Chung Kwong <1m02math@126.com>
25 | */
26 | public class SchemeEnvironment extends Environment{
27 | private Environment parent;
28 | private final HashMap bindings=new HashMap<>();
29 | /**
30 | * Create a top-level environment
31 | * @param repl REPL mode or not
32 | */
33 | public SchemeEnvironment(boolean repl){
34 | super(repl);
35 | this.parent=null;
36 | bindings.put(DefineLibrary.INSTANCE.getKeyword(),DefineLibrary.INSTANCE);
37 | bindings.put(Import.INSTANCE.getKeyword(),Import.INSTANCE);
38 | if(repl)
39 | Base.INSTANCE.getLibrary().exportTo(this);
40 | }
41 | void setParent(Environment parent){
42 | this.parent=parent;
43 | }
44 | /**
45 | * Create a envionment
46 | * @param parent parent environment
47 | */
48 | public SchemeEnvironment(Environment parent){
49 | super(parent.isREPL());
50 | this.parent=parent;
51 | }
52 | @Override
53 | public Optional getOptional(ScmSymbol id){
54 | Environment env=getFirstEnvironmentContains(this,id);
55 | return env!=null?Optional.ofNullable(env.getSelfOptional(id)):Optional.empty();
56 | }
57 | @Override
58 | public ScmObject getSelfOptional(ScmSymbol id){
59 | return bindings.get(id);
60 | }
61 | @Override
62 | public void set(ScmSymbol id,ScmObject obj){
63 | Environment env=getFirstEnvironmentContains(this,id);
64 | if(env!=null){
65 | env.add(id,obj);
66 | }else if(isREPL())
67 | add(id,obj);
68 | }
69 | private static Environment getFirstEnvironmentContains(Environment env,ScmSymbol id){
70 | while(env instanceof SchemeEnvironment){
71 | if(((SchemeEnvironment)env).bindings.containsKey(id))
72 | break;
73 | env=((SchemeEnvironment)env).parent;
74 | }
75 | return env;
76 | }
77 | @Override
78 | public void add(ScmSymbol id,ScmObject obj){
79 | bindings.put(id,obj);
80 | }
81 | @Override
82 | public void remove(ScmSymbol id){
83 | bindings.remove(id);
84 | }
85 | }
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/EvaluatorFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin;
18 | import com.github.chungkwong.jschememin.type.*;
19 | import java.util.*;
20 | import java.util.stream.*;
21 | import javax.script.*;
22 | /**
23 | * An implementation of ScriptEngineFactory
24 | * @author Chan Chung Kwong <1m02math@126.com>
25 | */
26 | public class EvaluatorFactory implements ScriptEngineFactory{
27 | /**
28 | * The factory for jSchemeMin
29 | */
30 | public static final EvaluatorFactory INSTANCE=new EvaluatorFactory();
31 | private static final HashMap PARAMETERS=new HashMap<>();
32 | static{
33 | PARAMETERS.put("ScriptEngine.ENGINE","JSchemeMin");
34 | PARAMETERS.put("ScriptEngine.ENGINE_VERSION","0.0.1");
35 | PARAMETERS.put("ScriptEngine.NAME","JSchemeMin");
36 | PARAMETERS.put("ScriptEngine.LANGUAGE","scheme");
37 | PARAMETERS.put("ScriptEngine.LANGUAGE_VERSION","7");
38 | }
39 | private EvaluatorFactory(){
40 |
41 | }
42 | @Override
43 | public String getEngineName(){
44 | return PARAMETERS.get("ScriptEngine.ENGINE");
45 | }
46 | @Override
47 | public String getEngineVersion(){
48 | return PARAMETERS.get("ScriptEngine.ENGINE_VERSION");
49 | }
50 | @Override
51 | public List getExtensions(){
52 | return Arrays.asList("scm");
53 | }
54 | @Override
55 | public List getMimeTypes(){
56 | return Arrays.asList("text/x-scheme");
57 | }
58 | @Override
59 | public List getNames(){
60 | return Arrays.asList(PARAMETERS.get("ScriptEngine.NAME"));
61 | }
62 | @Override
63 | public String getLanguageName(){
64 | return PARAMETERS.get("ScriptEngine.LANGUAGE_NAME");
65 | }
66 | @Override
67 | public String getLanguageVersion(){
68 | return PARAMETERS.get("ScriptEngine.LANGUAGE_VERSION");
69 | }
70 | @Override
71 | public Object getParameter(String key){
72 | return PARAMETERS.get(key);
73 | }
74 | @Override
75 | public String getMethodCallSyntax(String obj,String m,String... args){
76 | return Arrays.stream(args).collect(Collectors.joining(" ","("+m,")"));
77 | }
78 | @Override
79 | public String getOutputStatement(String toDisplay){
80 | return "(write-string "+new ScmString(toDisplay).toExternalRepresentation()+")";
81 | }
82 | @Override
83 | public String getProgram(String... statements){
84 | return Arrays.stream(statements).collect(Collectors.joining(" ","(begin ",")"));
85 | }
86 | @Override
87 | public Evaluator getScriptEngine(){
88 | return new Evaluator(true);
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/Environment.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2017 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin;
18 | import com.github.chungkwong.jschememin.type.*;
19 | import java.util.*;
20 | /**
21 | * Environment where variable is stored
22 | * @author Chan Chung Kwong <1m02math@126.com>
23 | */
24 | public abstract class Environment extends ScmObject{
25 | /**
26 | * The value of unbound variable if in REPL mode
27 | */
28 | public static final ScmSymbol UNBOUNDED=new ScmSymbol("unbound");
29 | private final boolean repl;
30 | /**
31 | * Create a environment
32 | * @param repl REPL mode or not
33 | */
34 | public Environment(boolean repl){
35 | this.repl=repl;
36 | }
37 | /**
38 | * Get the value of a variable
39 | * @param id name
40 | * @return value in Optional
41 | */
42 | public abstract Optional getOptional(ScmSymbol id);
43 | /**
44 | * Set a variable
45 | * @param id name
46 | * @param obj value
47 | */
48 | public abstract void set(ScmSymbol id,ScmObject obj);
49 | /**
50 | * Add a variable
51 | * @param id name
52 | * @param obj value
53 | */
54 | public abstract void add(ScmSymbol id,ScmObject obj);
55 | /**
56 | * Get the value of a variable in this environment, not its parent
57 | * @param id
58 | * @return value in Optional
59 | */
60 | public abstract ScmObject getSelfOptional(ScmSymbol id);
61 | /**
62 | * Delete a variable
63 | * @param id name
64 | */
65 | public abstract void remove(ScmSymbol id);
66 | /**
67 | * Get the value of a variable
68 | * @param id the name of the variable
69 | * @return
70 | */
71 | public ScmObject get(ScmSymbol id){
72 | Optional obj=getOptional(id);
73 | if(obj.isPresent())
74 | return obj.get();
75 | else
76 | return repl?UNBOUNDED:null;
77 | }
78 | /**
79 | * Check if a variable exists
80 | * @param id the name of the variable
81 | * @return
82 | */
83 | public boolean containsKey(ScmSymbol id){
84 | return getOptional(id).isPresent();
85 | }
86 | /**
87 | * Add a keyword
88 | * @param keyword
89 | */
90 | public void addPrimitiveType(BasicConstruct keyword){
91 | add(keyword.getKeyword(),keyword);
92 | }
93 | /**
94 | * Check if in REPL mode
95 | * @return
96 | */
97 | public boolean isREPL(){
98 | return repl;
99 | }
100 | @Override
101 | public String toExternalRepresentation(){
102 | return "'environment";
103 | //return '\"'+bindings.toString()+'\"';
104 | }
105 | @Override
106 | public boolean isSelfevaluating(){
107 | return false;
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/LibraryManager.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin;
18 | import com.github.chungkwong.jschememin.lib.*;
19 | import com.github.chungkwong.jschememin.type.*;
20 | import java.util.*;
21 | /**
22 | *
23 | * @author Chan Chung Kwong <1m02math@126.com>
24 | */
25 | public class LibraryManager{
26 | private static final HashMap LIBRARIES=new HashMap<>();
27 | private static final HashMap NATIVE_LIBRARIES=new HashMap<>();
28 | static{
29 | addNativeLibrary(Base.INSTANCE);
30 | addNativeLibrary(Char.INSTANCE);
31 | addNativeLibrary(Complex.INSTANCE);
32 | addNativeLibrary(Eval.INSTANCE);
33 | addNativeLibrary(File.INSTANCE);
34 | addNativeLibrary(HashTable.INSTANCE);
35 | addNativeLibrary(Inexact.INSTANCE);
36 | addNativeLibrary(Java.INSTANCE);
37 | addNativeLibrary(JSchemeMin.INSTANCE);
38 | addNativeLibrary(Lazy.INSTANCE);
39 | addNativeLibrary(Load.INSTANCE);
40 | addNativeLibrary(ProcessContext.INSTANCE);
41 | addNativeLibrary(REPL.INSTANCE);
42 | addNativeLibrary(Read.INSTANCE);
43 | addNativeLibrary(Time.INSTANCE);
44 | addNativeLibrary(Write.INSTANCE);
45 | addNativeLibrary(new SimpleLibrary("/com/github/chungkwong/jschememin/lib/case-lambda.scm","scheme","case-lambda"));
46 | addNativeLibrary(new SimpleLibrary("/com/github/chungkwong/jschememin/lib/cxr.scm","scheme","cxr"));
47 | addNativeLibrary(new SimpleLibrary("/com/github/chungkwong/jschememin/lib/lazy.scm","scheme","lazy"));
48 | addNativeLibrary(new SimpleLibrary("/com/github/chungkwong/jschememin/lib/null.scm","scheme","null"));
49 | addNativeLibrary(new SimpleLibrary("/com/github/chungkwong/jschememin/lib/r5rs.scm","scheme","r5rs"));
50 | }
51 | private static void addNativeLibrary(LibraryLoader lib){
52 | NATIVE_LIBRARIES.put(lib.getName(),lib);
53 | }
54 | /**
55 | * Registry a library
56 | * @param lib
57 | */
58 | public static void addLibrary(Library lib){
59 | LIBRARIES.put(lib.getName(),lib);
60 | }
61 | /**
62 | * Check if a library is available
63 | * @param name the name of the library
64 | * @return
65 | */
66 | public static boolean hasLibrary(ScmPair name){
67 | return LIBRARIES.containsKey(name)||NATIVE_LIBRARIES.containsKey(name);
68 | }
69 | /**
70 | * Get a library
71 | * @param name the name of the library
72 | * @return
73 | */
74 | public static Library getLibrary(ScmPair name){
75 | if(LIBRARIES.containsKey(name))
76 | return LIBRARIES.get(name);
77 | else if(NATIVE_LIBRARIES.containsKey(name))
78 | return NATIVE_LIBRARIES.get(name).getLibrary();
79 | else
80 | throw new RuntimeException("Library not found: "+name);
81 | }
82 | }
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/type/ScmProcedure.java:
--------------------------------------------------------------------------------
1 | package com.github.chungkwong.jschememin.type;
2 | import com.github.chungkwong.jschememin.*;
3 | /**
4 | * Represents the type procedure in Scheme
5 | * @author kwong
6 | */
7 | public final class ScmProcedure extends Evaluable{
8 | private final SchemeEnvironment parent;
9 | private final ScmObject formal;
10 | private final ScmPair body;
11 | /**
12 | * Construct a procedure
13 | * @param formal the formal parameters
14 | * @param body the body
15 | * @param parent the environment where the procedure is defined
16 | */
17 | public ScmProcedure(ScmObject formal,ScmPair body,SchemeEnvironment parent){
18 | this.formal=formal;
19 | this.body=body;
20 | this.parent=parent;
21 | }
22 | @Override
23 | public String toExternalRepresentation(){
24 | StringBuilder buf=new StringBuilder();
25 | buf.append("(lambda ").append(formal.toExternalRepresentation()).append(' ').append(body.getCar().toExternalRepresentation());
26 | ScmPair tmp=body;
27 | while(tmp.getCdr() instanceof ScmPair){
28 | tmp=(ScmPair)tmp.getCdr();
29 | buf.append(' ').append(tmp.getCar().toExternalRepresentation());
30 | }
31 | buf.append(')');
32 | return buf.toString();
33 | }
34 | @Override
35 | public boolean isSelfevaluating(){
36 | return false;
37 | }
38 | @Override
39 | public void call(SchemeEnvironment dynamicEnv,Continuation cont,Object pointer,ScmPairOrNil param){
40 | if(pointer==null){
41 | call(dynamicEnv,cont,new Backtrack(extendEnvironment((ScmPairOrNil)param),body),null);
42 | }else{
43 | assert pointer instanceof Backtrack;
44 | Backtrack b=(Backtrack)pointer;
45 | ScmObject next=b.getRemaining().getCdr();
46 | if(next==ScmNil.NIL){
47 | cont.callTail(ExpressionEvaluator.INSTANCE,b.getRemaining().getCar(),b.getEnvironment());
48 | }else if(next instanceof ScmPair){
49 | cont.call(ExpressionEvaluator.INSTANCE,new Backtrack(b.getEnvironment(),(ScmPair)next),b.getRemaining().getCar(),b.getEnvironment());
50 | }else
51 | throw new SyntaxException();
52 | }
53 | }
54 | @Override
55 | public boolean equalsValue(ScmObject obj){
56 | return this==obj;
57 | }
58 | private SchemeEnvironment extendEnvironment(ScmPairOrNil param){
59 | SchemeEnvironment env=new SchemeEnvironment(parent);
60 | if(formal instanceof ScmSymbol){
61 | env.add((ScmSymbol)formal,param);
62 | }else if(formal instanceof ScmPair){
63 | ScmPair remainingFormal=(ScmPair)formal;
64 | while(true){
65 | env.add((ScmSymbol)remainingFormal.getCar(),ScmList.first(param));
66 | param=(ScmPairOrNil)((ScmPair)param).getCdr();
67 | ScmObject next=remainingFormal.getCdr();
68 | if(next instanceof ScmPair){
69 | remainingFormal=(ScmPair)next;
70 | }else if(next instanceof ScmNil){
71 | break;
72 | }else if(next instanceof ScmSymbol){
73 | env.add((ScmSymbol)next,param);
74 | break;
75 | }else
76 | throw new SyntaxException();
77 | }
78 | }else if(formal instanceof ScmNil){
79 |
80 | }else
81 | throw new SyntaxException();
82 | return env;
83 | }
84 | static class Backtrack{
85 | private final SchemeEnvironment env;
86 | private final ScmPair remaining;
87 | public Backtrack(SchemeEnvironment env,ScmPair remaining){
88 | this.env=env;
89 | this.remaining=remaining;
90 | }
91 | public SchemeEnvironment getEnvironment(){
92 | return env;
93 | }
94 | public ScmPair getRemaining(){
95 | return remaining;
96 | }
97 | }
98 | }
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/type/ScmBinaryOutputPort.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.type;
18 | import com.github.chungkwong.jschememin.*;
19 | import java.io.*;
20 | /**
21 | * Represents the type binary output port in Scheme
22 | * @author Chan Chung Kwong <1m02math@126.com>
23 | */
24 | public class ScmBinaryOutputPort extends ScmPort{
25 | private final OutputStream out;
26 | /**
27 | * Wrap a OutputStream
28 | * @param out
29 | */
30 | public ScmBinaryOutputPort(OutputStream out){
31 | this.out=out;
32 | }
33 | /**
34 | * Construct a port to write to a file
35 | * @param file the file name
36 | */
37 | public ScmBinaryOutputPort(String file){
38 | try{
39 | this.out=new FileOutputStream(Main.resolveFile(file));
40 | }catch(FileNotFoundException ex){
41 | throw ScmError.toException(new ScmError(new ScmString(ex.getLocalizedMessage()),ScmNil.NIL,ScmError.ErrorType.FILE));
42 | }
43 | }
44 | /**
45 | * Corresponding to the procedure write-u8 in Scheme
46 | * @param obj
47 | * @return
48 | * @throws IOException
49 | */
50 | public ScmBinaryOutputPort writeByte(ScmInteger obj) throws IOException{
51 | int b=obj.getValue().intValueExact();
52 | if(b>=0&&b<256)
53 | out.write(b);
54 | else
55 | throw new RuntimeException("A byte is expected");
56 | return this;
57 | }
58 | /**
59 | * Corresponding to the procedure write-bytevector in Scheme
60 | * @param obj
61 | * @param start
62 | * @param end
63 | * @return
64 | * @throws IOException
65 | */
66 | public ScmBinaryOutputPort writeByteVector(ScmByteVector obj,int start,int end) throws IOException{
67 | out.write(obj.getByteArray(),start,end-start);
68 | return this;
69 | }
70 | /**
71 | * Corresponding to the procedure get-output-bytevector in Scheme
72 | * @return
73 | */
74 | public byte[] getByteArray(){
75 | if(out instanceof ByteArrayOutputStream)
76 | return ((ByteArrayOutputStream)out).toByteArray();
77 | else
78 | throw new RuntimeException();
79 | }
80 | /**
81 | * Corresponding to the procedure flush-output-port in Scheme
82 | * @return
83 | * @throws IOException
84 | */
85 | public ScmBinaryOutputPort flush()throws IOException{
86 | out.flush();
87 | return this;
88 | }
89 | /**
90 | * Corresponding to the procedure close-output-port in Scheme
91 | * @return
92 | * @throws IOException
93 | */
94 | @Override
95 | public ScmBinaryOutputPort close()throws IOException{
96 | super.close();
97 | out.close();
98 | return this;
99 | }
100 | @Override
101 | public String toExternalRepresentation(){
102 | return out.toString();
103 | }
104 | }
--------------------------------------------------------------------------------
/doc/overview.tex:
--------------------------------------------------------------------------------
1 | \documentclass[twoside,twocolumn]{algol60}
2 |
3 | \usepackage[slantfont,boldfont]{xeCJK}
4 | \usepackage{amsmath}
5 |
6 | \pagestyle{headings}
7 | \showboxdepth=0
8 | \makeindex
9 | \input{commands}
10 |
11 | \def\headertitle{Revised$^{7}$ Scheme}
12 | \def\integerversion{7}
13 |
14 | % Sizes and dimensions
15 |
16 | \topmargin -.375in % Nominal distance from top of page to top of
17 | % box containing running head.
18 | \headsep 15pt % Space between running head and text.
19 |
20 | \textheight 663pt % Height of text (including footnotes and figures,
21 | % excluding running head and foot).
22 |
23 | \textwidth 523pt % Width of text line.
24 | \columnsep 15pt % Space between columns
25 | \columnseprule 0pt % Width of rule between columns.
26 |
27 | \parskip 5pt plus 2pt minus 2pt % Extra vertical space between paragraphs.
28 | \parindent 0pt % Width of paragraph indentation.
29 | \topsep 0pt plus 2pt % Extra vertical space, in addition to
30 | % \parskip, added above and below list and
31 | % paragraphing environments.
32 |
33 | \oddsidemargin -.5in % Left margin on odd-numbered pages.
34 | \evensidemargin -.5in % Left margin on even-numbered pages.
35 |
36 | %% End of sizes and dimensions
37 |
38 | \usepackage{hyperref}
39 | %% \usepackage{supertabular}
40 |
41 | \begin{document}
42 |
43 | \parindent 0pt %!! 15pt % Width of paragraph indentation.
44 |
45 | % First page
46 |
47 | \thispagestyle{empty}
48 |
49 |
50 | \topnewpage[{
51 | \begin{center} {\huge\bf
52 | 修订{\Huge$^{\mathbf{7}}$} 算法语言概述 \\
53 | \vskip 3pt
54 | Scheme}
55 |
56 | \vskip 1ex
57 | $$
58 | \begin{tabular}{l@{\extracolsep{.5in}}l@{\extracolsep{.5in}}l}
59 | \multicolumn{3}{c}{A\authorsc{LEX} S\authorsc{HINN},
60 | J\authorsc{OHN} C\authorsc{OWAN}, \authorsc{AND}
61 | A\authorsc{RTHUR} A. G\authorsc{LECKLER} (\textit{Editors})} \\
62 | \\
63 | S\authorsc{TEVEN} G\authorsc{ANZ} &
64 | A\authorsc{LEXEY} R\authorsc{ADUL} &
65 | O\authorsc{LIN} S\authorsc{HIVERS} \\
66 |
67 | A\authorsc{ARON} W. H\authorsc{SU} &
68 | J\authorsc{EFFREY} T. R\authorsc{EAD} &
69 | A\authorsc{LARIC} S\authorsc{NELL}-P\authorsc{YM} \\
70 |
71 | B\authorsc{RADLEY} L\authorsc{UCIER} &
72 | D\authorsc{AVID} R\authorsc{USH} &
73 | G\authorsc{ERALD} J. S\authorsc{USSMAN} \\
74 |
75 | E\authorsc{MMANUEL} M\authorsc{EDERNACH} &
76 | B\authorsc{ENJAMIN} L. R\authorsc{USSEL} &
77 | \\
78 | \\
79 | \multicolumn{3}{c}{R\authorsc{ICHARD} K\authorsc{ELSEY},
80 | W\authorsc{ILLIAM} C\authorsc{LINGER},
81 | \authorsc{AND} J\authorsc{ONATHAN} R\authorsc{EES}} \\
82 | \multicolumn{3}{c}{\textit{(Editors, Revised$^{\mathit{5}}$ Report on the Algorithmic Language Scheme)}} \\
83 | \\
84 | \multicolumn{3}{c}{M\authorsc{ICHAEL} S\authorsc{PERBER},
85 | R. K\authorsc{ENT} D\authorsc{YBVIG}, M\authorsc{ATTHEW} F\authorsc{LATT},
86 | \authorsc{AND} A\authorsc{NTON} \authorsc{VAN} S\authorsc{TRAATEN}} \\
87 | \multicolumn{3}{c}{\textit{(Editors, Revised$^{\mathit{6}}$ Report on the Algorithmic Language Scheme)}} \\
88 | \end{tabular}
89 | $$
90 | \vskip 2ex
91 | {\it 献给对John McCarthy 和 Daniel Weinreb的记忆}
92 | \vskip 2.6ex
93 | \end{center}
94 | }]
95 |
96 | \clearpage
97 |
98 | \eject
99 | \input{overview-body} \par
100 |
101 | \vfill\eject
102 |
103 |
104 |
105 | \end{document}
106 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/type/DatumRecord.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.type;
18 | import java.util.*;
19 | /**
20 | * A data structure being used to trace cyclic reference. Mainly for internal use.
21 | * @author Chan Chung Kwong <1m02math@126.com>
22 | */
23 | public class DatumRecord{
24 | private static int idCounter=0;
25 | private final int id;
26 | private boolean reused,defined;
27 | /**
28 | * Construct a record
29 | */
30 | public DatumRecord(){
31 | this.id=++idCounter;
32 | this.reused=false;
33 | this.defined=false;
34 | }
35 | /**
36 | * Mark the record as reused
37 | */
38 | public void reuse(){
39 | reused=true;
40 | }
41 | /**
42 | * Check if the record is marked as reused
43 | * @return
44 | */
45 | public boolean isReused(){
46 | return reused;
47 | }
48 | /**
49 | * Mark the record as defined
50 | */
51 | public void define(){
52 | defined=true;
53 | }
54 | /**
55 | * Check if the record is marked as defined
56 | * @return
57 | */
58 | public boolean isDefined(){
59 | return defined;
60 | }
61 | /**
62 | * Get the ID of the record
63 | * @return
64 | */
65 | public int getId(){
66 | return id;
67 | }
68 | /**
69 | * Ensure that new records have a greater ID later on
70 | * @param counter
71 | */
72 | public static void updateId(int counter){
73 | if(counter>idCounter)
74 | idCounter=counter;
75 | }
76 | @Override
77 | public String toString(){
78 | return super.toString();
79 | }
80 | /**
81 | * Collect reference in a object to a map
82 | * @param object
83 | * @param map
84 | */
85 | public static void collectReference(ScmObject object,IdentityHashMap map){
86 | if(map.containsKey(object))
87 | map.get(object).reuse();
88 | else if(object instanceof ScmVector){
89 | map.put(object,new DatumRecord());
90 | for(int i=0;i<((ScmVector)object).getLength();i++)
91 | collectReference(((ScmVector)object).get(i),map);
92 | }else if(object instanceof ScmPair){
93 | map.put(object,new DatumRecord());
94 | collectReference(((ScmPair)object).getCar(),map);
95 | collectReference(((ScmPair)object).getCdr(),map);
96 | }
97 | }
98 | /**
99 | * Write external representation of a object
100 | * @param obj the object
101 | * @param buf output buffer
102 | * @param refs known references
103 | * @return
104 | */
105 | public static boolean toExternalRepresentation(ScmObject obj,StringBuilder buf,IdentityHashMap refs){
106 | if(obj instanceof ScmVector){
107 | return ((ScmVector)obj).toExternalRepresentation(buf,refs);
108 | }else if(obj instanceof ScmPair){
109 | return ((ScmPair)obj).toExternalRepresentation(buf,refs);
110 | }else{
111 | buf.append(obj.toExternalRepresentation());
112 | return true;
113 | }
114 | }
115 | }
--------------------------------------------------------------------------------
/doc/extract.scm:
--------------------------------------------------------------------------------
1 |
2 | ; Code to extract the examples from the report. Written for R5RS by
3 | ; Richard Kelsey.
4 |
5 | ; This prints everything in INPUT-FILE that is between a "\begin{scheme}"
6 | ; and an "\end{scheme}" to the current output port.
7 |
8 | (define (find-examples input-file)
9 | (call-with-input-file input-file
10 | (lambda (in)
11 | (extract-text "\\begin{scheme}"
12 | "\\end{scheme}"
13 | (input-port->source in)
14 | (output-port->sink (current-output-port))))))
15 |
16 | ; Turning ports into sources (thunks that generate characters) and
17 | ; sinks (procedures of one argument that consume characters).
18 |
19 | (define (input-port->source port)
20 | (lambda ()
21 | (read-char port)))
22 |
23 | (define (output-port->sink port)
24 | (lambda (char)
25 | (write-char char port)))
26 |
27 | ; Read characters from SOURCE, passing to SINK all characters found between
28 | ; the strings BEGIN and END.
29 |
30 | (define (extract-text begin end source sink)
31 | (let loop ()
32 | (if (find-string begin source (lambda (char) (values)))
33 | (if (find-string end source sink)
34 | (loop)))))
35 |
36 | ; Transfer characters from SOURCE to SINK until STRING is found.
37 | ;
38 | ; We first make a circular buffer containing the first (string-length STRING)
39 | ; characters from SOURCE. We then compare the buffer with STRING to see if
40 | ; a match is found. If not, we pass the first character from the buffer to
41 | ; SINK and get the next item from SOURCE. If it's a character we put it in
42 | ; the buffer, advance the buffer one character, and continue. When we reach
43 | ; the end of SOURCE, the remaining characters in the buffer are passed to SINK.
44 |
45 | (define (find-string string source sink)
46 | (let ((buffer (make-circular-buffer (string-length string) source)))
47 | (let loop ((buffer buffer))
48 | (if (buffer-match? string buffer)
49 | #t
50 | (begin
51 | (sink (car buffer))
52 | (let ((next (source)))
53 | (if (char? next)
54 | (begin
55 | (set-car! buffer next)
56 | (loop (cdr buffer)))
57 | (begin
58 | (set-car! buffer #f)
59 | (let flush-loop ((buffer (cdr buffer)))
60 | (if (car buffer)
61 | (begin
62 | (sink (car buffer))
63 | (flush-loop (cdr buffer)))
64 | #f))))))))))
65 |
66 | ; Returns a circular list of COUNT pairs containing the first COUNT
67 | ; items from SOURCE.
68 |
69 | (define (make-circular-buffer count source)
70 | (let ((start (list (source))))
71 | (let loop ((last start) (i 1))
72 | (if (= i count)
73 | (begin
74 | (set-cdr! last start)
75 | last)
76 | (let ((next (list (source))))
77 | (set-cdr! last next)
78 | (loop next (+ i 1)))))
79 | start))
80 |
81 | ; Returns #T if the contents of the BUFFER, a list of characters, matches
82 | ; STRING. This is the same as `(string=? string (list->string buffer))'
83 | ; except that it works for circular buffers.
84 |
85 | (define (buffer-match? string buffer)
86 | (let loop ((buffer buffer) (i 0))
87 | (cond ((= i (string-length string))
88 | #t)
89 | ((char=? (car buffer) (string-ref string i))
90 | (loop (cdr buffer) (+ i 1)))
91 | (else
92 | #f))))
93 |
94 | ; Return a source that generates the characters from STRING. This is only
95 | ; used for testing.
96 |
97 | (define (string-source string)
98 | (let ((i 0))
99 | (lambda ()
100 | (if (= i (string-length string))
101 | #f
102 | (begin
103 | (set! i (+ i 1))
104 | (string-ref string (- i 1)))))))
105 |
106 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/lib/Char.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.lib;
18 | import com.github.chungkwong.jschememin.*;
19 | import static com.github.chungkwong.jschememin.lib.Utility.car;
20 | import com.github.chungkwong.jschememin.type.*;
21 | /**
22 | * Correspoding to the library (scheme char) in Scheme
23 | * @author Chan Chung Kwong <1m02math@126.com>
24 | */
25 | public class Char extends NativeLibrary{
26 | public static final Char INSTANCE=new Char();
27 | private Char(){
28 | super("scheme","char");
29 | }
30 | @Override
31 | protected void init(Library lib){
32 | addNativeProcedure("char-alphabetic?",(o)->ScmBoolean.valueOf(((ScmCharacter)car(o)).isAlphabetic()));
33 | addNativeProcedure("char-numeric?",(o)->ScmBoolean.valueOf(((ScmCharacter)car(o)).isNumeric()));
34 | addNativeProcedure("char-whitespace?",(o)->ScmBoolean.valueOf(((ScmCharacter)car(o)).isWhiteSpace()));
35 | addNativeProcedure("char-upper-case?",(o)->ScmBoolean.valueOf(((ScmCharacter)car(o)).isUpperCase()));
36 | addNativeProcedure("char-lower-case?",(o)->ScmBoolean.valueOf(((ScmCharacter)car(o)).isLowerCase()));
37 | addNativeProcedure("digit-value",(o)->{int d=((ScmCharacter)car(o)).getDigitValue();return d>=0?new ScmInteger(d):ScmBoolean.FALSE;});
38 | addNativeProcedure("char-upcase",(o)->((ScmCharacter)car(o)).upCase());
39 | addNativeProcedure("char-downcase",(o)->((ScmCharacter)car(o)).downCase());
40 | addNativeProcedure("char-foldcase",(o)->((ScmCharacter)car(o)).foldCase());
41 | addNativeProcedure("string-upcase",(o)->((ScmString)car(o)).toUpperCase());
42 | addNativeProcedure("string-downcase",(o)->((ScmString)car(o)).toLowerCase());
43 | addNativeProcedure("string-foldcase",(o)->((ScmString)car(o)).toFoldingCase());
44 | addNativeProcedure("char-ci=?",Utility.chainComparator((a,b)->((ScmCharacter)a).compareToIgnoreCase((ScmCharacter)b)==0));
45 | addNativeProcedure("char-ci",Utility.chainComparator((a,b)->((ScmCharacter)a).compareToIgnoreCase((ScmCharacter)b)<0));
46 | addNativeProcedure("char-ci<=?",Utility.chainComparator((a,b)->((ScmCharacter)a).compareToIgnoreCase((ScmCharacter)b)<=0));
47 | addNativeProcedure("char-ci>?",Utility.chainComparator((a,b)->((ScmCharacter)a).compareToIgnoreCase((ScmCharacter)b)>0));
48 | addNativeProcedure("char-ci>=?",Utility.chainComparator((a,b)->((ScmCharacter)a).compareToIgnoreCase((ScmCharacter)b)>=0));
49 | addNativeProcedure("string-ci=?",Utility.chainComparator((a,b)->((ScmString)a).compareToIgnoreCase((ScmString)b)==0));
50 | addNativeProcedure("string-ci",Utility.chainComparator((a,b)->((ScmString)a).compareToIgnoreCase((ScmString)b)<0));
51 | addNativeProcedure("string-ci<=?",Utility.chainComparator((a,b)->((ScmString)a).compareToIgnoreCase((ScmString)b)<=0));
52 | addNativeProcedure("string-ci>?",Utility.chainComparator((a,b)->((ScmString)a).compareToIgnoreCase((ScmString)b)>0));
53 | addNativeProcedure("string-ci>=?",Utility.chainComparator((a,b)->((ScmString)a).compareToIgnoreCase((ScmString)b)>=0));
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/lib/HashTable.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.lib;
18 | import com.github.chungkwong.jschememin.*;
19 | import static com.github.chungkwong.jschememin.lib.Utility.caddr;
20 | import static com.github.chungkwong.jschememin.lib.Utility.cadr;
21 | import static com.github.chungkwong.jschememin.lib.Utility.car;
22 | import com.github.chungkwong.jschememin.type.*;
23 | /**
24 | * Correspoding to the library (scheme hashtables) in Scheme
25 | * @author Chan Chung Kwong <1m02math@126.com>
26 | */
27 | public class HashTable extends NativeLibrary{
28 | private static final ScmSymbol OK=new ScmSymbol("ok");
29 | public static final HashTable INSTANCE=new HashTable();
30 | private HashTable(){
31 | super("scheme","hashtables");
32 | }
33 | @Override
34 | protected void init(Library lib){
35 | addNativeProcedure("make-hashtable",new NativeProcedureDefault(
36 | (o)->new ScmHashTable((Evaluable)car(o),(Evaluable)cadr(o),((ScmComplex)caddr(o)).intValueExact()),
37 | (o)->car(o),(o)->cadr(o),(o)->new ScmInteger(16)));
38 | addNativeProcedure("hashtable-copy",new NativeProcedureDefault(
39 | (o)->((ScmHashTable)car(o)).copy(((ScmBoolean)cadr(o)).isTrue()),
40 | (o)->car(o),(o)->ScmBoolean.FALSE));
41 | addNativeProcedure("hashtable-mutable?",(o)->ScmBoolean.valueOf(((ScmHashTable)car(o)).isMutable()));
42 | addNativeProcedure("hashtable-equivalence-function",(o)->((ScmHashTable)car(o)).getEquivalenceFunction());
43 | addNativeProcedure("hashtable-hash-function",(o)->((ScmHashTable)car(o)).getHashFunction());
44 | addNativeProcedure("hashtable?",(o)->ScmBoolean.valueOf(car(o)instanceof ScmHashTable));
45 | addNativeProcedure("hashtable-contains?",(o)->ScmBoolean.valueOf(((ScmHashTable)car(o)).contains(cadr(o))));
46 | addNativeProcedure("hashtable-size",(o)->new ScmInteger(((ScmHashTable)car(o)).size()));
47 | addNativeProcedure("hashtable-ref",(o)->((ScmHashTable)car(o)).get(cadr(o),caddr(o)));
48 | addNativeProcedure("hashtable-set!",(o)->{((ScmHashTable)car(o)).put(cadr(o),caddr(o));return OK;});
49 | addNativeProcedure("hashtable-delete!",(o)->{((ScmHashTable)car(o)).remove(cadr(o));return OK;});
50 | addNativeProcedure("hashtable-clear!",(o)->{((ScmHashTable)car(o)).clear();return OK;});
51 | addNativeProcedure("hashtable-keys",(o)->((ScmHashTable)car(o)).keys());
52 | addNativeProcedureMulti("hashtable-entries",(o)->ScmList.toList(((ScmHashTable)car(o)).keys(),((ScmHashTable)car(o)).values()));
53 | addNativeProcedure("equal-hash",(o)->new ScmInteger(((ScmObject)car(o)).hashCode()));
54 | addNativeProcedure("string-hash",(o)->new ScmInteger(((ScmString)car(o)).hashCode()));
55 | addNativeProcedure("string-ci-hash",(o)->new ScmInteger(((ScmString)car(o)).toFoldingCase().hashCode()));
56 | addNativeProcedure("symbol-hash",(o)->new ScmInteger(((ScmSymbol)car(o)).hashCode()));
57 | addDeriveFile("/com/github/chungkwong/jschememin/lib/hashtables_derive.scm",
58 | "make-eq-hashtable","make-eqv-hashtable","hashtable-update!");
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/type/ScmError.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.type;
18 | /**
19 | * Represents errors in Scheme
20 | * @author Chan Chung Kwong <1m02math@126.com>
21 | */
22 | public class ScmError extends ScmObject{
23 | /**
24 | * The type of error in Scheme
25 | */
26 | public static enum ErrorType{
27 | READ,FILE,SYNTAX,JAVA,OTHER
28 | }
29 | private final ScmString message;
30 | private final ScmPairOrNil irritants;
31 | private final ErrorType type;
32 | /**
33 | * Construct a error
34 | * @param message the error message
35 | * @param irritants something related to the errir
36 | * @param type the type of the error
37 | */
38 | public ScmError(ScmString message,ScmPairOrNil irritants,ErrorType type){
39 | this.message=message;
40 | this.irritants=irritants;
41 | this.type=type;
42 | }
43 |
44 | /**
45 | * Get the error message
46 | * @return
47 | */
48 | public ScmString getErrorMessage(){
49 | return message;
50 | }
51 | /**
52 | * Get something related to the error
53 | * @return
54 | */
55 | public ScmPairOrNil getIrritants(){
56 | return irritants;
57 | }
58 | /**
59 | * Get the type of the error
60 | * @return
61 | */
62 | public ErrorType getType(){
63 | return type;
64 | }
65 | @Override
66 | public String toExternalRepresentation(){
67 | return new ScmPair(new ScmSymbol("error"),new ScmPair(message,irritants)).toExternalRepresentation();
68 | }
69 | @Override
70 | public boolean isSelfevaluating(){
71 | return true;
72 | }
73 | /**
74 | * Wrap a Throwable
75 | * @param t
76 | * @return
77 | */
78 | public static RuntimeException toRuntimeException(Throwable t){
79 | if(t instanceof ScmException)
80 | return (ScmException)t;
81 | return new ScmException(toScmObject(t));
82 | }
83 | /**
84 | * Wrap a error object
85 | * @param obj
86 | * @return
87 | */
88 | public static RuntimeException toException(ScmObject obj){
89 | if(obj instanceof ScmError&&((ScmError)obj).getType()==ErrorType.JAVA)
90 | return new ScmException(obj,(Throwable)((ScmJavaObject)ScmList.first(((ScmError)obj).getIrritants())).getJavaObject());
91 | else
92 | return new ScmException(obj);
93 | }
94 | /**
95 | * Convert to a Scheme object
96 | * @param obj
97 | * @return
98 | */
99 | public static ScmObject toScmObject(Throwable obj){
100 | //obj.printStackTrace();
101 | if(obj instanceof ScmException)
102 | return ((ScmException)obj).getObject();
103 | return new ScmError(new ScmString(obj.toString()),ScmList.toList(new ScmJavaObject(obj)),ErrorType.JAVA);
104 | }
105 | private static class ScmException extends RuntimeException{
106 | private final ScmObject obj;
107 | public ScmException(ScmObject obj){
108 | super();
109 | this.obj=obj;
110 | }
111 | public ScmException(ScmObject obj,Throwable cause){
112 | super(cause);
113 | this.obj=obj;
114 | }
115 | public ScmObject getObject(){
116 | return obj;
117 | }
118 | @Override
119 | public String getMessage(){
120 | return obj.toExternalRepresentation();
121 | }
122 | }
123 | }
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/primitive/Import.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.primitive;
18 | import com.github.chungkwong.jschememin.*;
19 | import com.github.chungkwong.jschememin.type.*;
20 | import java.util.*;
21 | /**
22 | * Correspoding to the primitive import in Scheme
23 | * @author Chan Chung Kwong <1m02math@126.com>
24 | */
25 | public class Import extends BasicConstruct implements Primitive{
26 | public static final Import INSTANCE=new Import();
27 | private static final ScmSymbol PREFIX=new ScmSymbol("prefix");
28 | private static final ScmSymbol RENAME=new ScmSymbol("rename");
29 | private static final ScmSymbol EXCEPT=new ScmSymbol("except");
30 | private static final ScmSymbol ONLY=new ScmSymbol("only");
31 | private Import(){
32 | super(new ScmSymbol("import"));
33 | }
34 | @Override
35 | public void call(SchemeEnvironment env,Continuation cont,Object pointer,ScmPairOrNil list){
36 | importLibraries(env,list);
37 | cont.ret(new ScmSymbol("ok"));
38 | }
39 | public SchemeEnvironment importLibraries(SchemeEnvironment env,ScmObject list){
40 | ScmList.forEach(list,(o)->importLibrary(env,(ScmPair)o));
41 | return env;
42 | }
43 | private void importLibrary(SchemeEnvironment env,ScmPair spec){
44 | ImportSet set=getImportSet(spec);
45 | set.lib.exportTo(env,set.ex2im);
46 | }
47 | private ImportSet getImportSet(ScmPair list){
48 | if(list.getCdr() instanceof ScmPair&&((ScmPair)list.getCdr()).getCar() instanceof ScmPair){
49 | ScmObject car=list.getCar();
50 | ImportSet set=getImportSet((ScmPair)list.getCadr());
51 | list=(ScmPair)list.getCddr();
52 | if(car.equals(PREFIX)){
53 | ScmSymbol prefix=(ScmSymbol)list.getCar();
54 | for(Map.Entry entry:set.ex2im.entrySet()){
55 | entry.setValue(new ScmSymbol(prefix.getValue()+entry.getValue().getValue()));
56 | }
57 | }else if(car.equals(RENAME)){
58 | HashMap rename=new HashMap<>();
59 | ScmList.forEach(list,(c)->rename.put((ScmSymbol)((ScmPair)c).getCar(),(ScmSymbol)((ScmPair)c).getCadr()));
60 | for(Map.Entry entry:set.ex2im.entrySet())
61 | if(rename.containsKey(entry.getValue()))
62 | entry.setValue(rename.get(entry.getValue()));
63 | }else if(car.equals(EXCEPT)){
64 | HashSet remain=new HashSet<>();
65 | ScmList.forEach(list,(c)->remain.add((ScmSymbol)c));
66 | Iterator> iter=set.ex2im.entrySet().iterator();
67 | while(iter.hasNext())
68 | if(remain.contains(iter.next().getValue()))
69 | iter.remove();
70 | }else if(car.equals(ONLY)){
71 | HashSet remain=new HashSet<>();
72 | ScmList.forEach(list,(c)->remain.add((ScmSymbol)c));
73 | Iterator> iter=set.ex2im.entrySet().iterator();
74 | while(iter.hasNext())
75 | if(!remain.contains(iter.next().getValue()))
76 | iter.remove();
77 | }
78 | return set;
79 | }else
80 | return new ImportSet(list);
81 | }
82 | static class ImportSet{
83 | final Library lib;
84 | final HashMap ex2im=new HashMap<>();
85 | public ImportSet(ScmPair libName){
86 | lib=LibraryManager.getLibrary(libName);
87 | lib.getExportSet().stream().forEach((exportName)->{
88 | ex2im.put(exportName,exportName);
89 | });
90 | }
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/lib/NativeLibrary.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.lib;
18 | import com.github.chungkwong.jschememin.*;
19 | import com.github.chungkwong.jschememin.type.*;
20 | import java.io.*;
21 | import java.util.*;
22 | import java.util.logging.*;
23 | /**
24 | * Loader for native library
25 | * @author Chan Chung Kwong <1m02math@126.com>
26 | */
27 | public abstract class NativeLibrary implements LibraryLoader{
28 | private Library lib=null;
29 | private final ScmPair name;
30 | /**
31 | *
32 | * @param part the name of the library
33 | */
34 | public NativeLibrary(String... part){
35 | this.name=(ScmPair)Arrays.stream(part).map((n)->new ScmSymbol(n)).collect(ScmList.COLLECTOR);
36 | }
37 | @Override
38 | public ScmPair getName(){
39 | return name;
40 | }
41 | @Override
42 | public Library getLibrary(){
43 | if(lib==null){
44 | lib=new Library(name,new HashMap<>(),new SchemeEnvironment(false));
45 | init(lib);
46 | }
47 | return lib;
48 | }
49 | /**
50 | * Add a object into the library
51 | * @param name the variable name
52 | * @param obj the object
53 | * @param export if the object prefered to be exposed to users
54 | */
55 | protected void addNative(ScmSymbol name,ScmObject obj,boolean export){
56 | lib.getInternalEnvironment().add(name,obj);
57 | if(export)
58 | lib.getExportMap().put(name,name);
59 | }
60 | /**
61 | * Add a object into the library
62 | * @param type
63 | */
64 | protected void addPrimitiveType(BasicConstruct type){
65 | lib.getInternalEnvironment().addPrimitiveType(type);
66 | lib.getExportMap().put(type.getKeyword(),type.getKeyword());
67 | }
68 | /**
69 | * Exexute a derive file and use add variables that it define to the library
70 | * @param file the file name
71 | * @param export the variable to be exposed to users
72 | */
73 | protected void addDeriveFile(String file,String... export){
74 | try{
75 | Parser parser=new Parser(new Lex(new InputStreamReader(NativeLibrary.class.getResourceAsStream(file),"UTF-8")));
76 | SchemeEnvironment internal=lib.getInternalEnvironment();
77 | Evaluator evaluator=new Evaluator(internal);
78 | parser.getRemainingDatums().forEach((d)->evaluator.eval(d));
79 | for(String name:export){
80 | ScmSymbol id=new ScmSymbol(name);
81 | lib.getExportMap().put(id,id);
82 | }
83 | }catch(UnsupportedEncodingException ex){
84 | Logger.getGlobal().log(Level.SEVERE,null,ex);
85 | }
86 | }
87 | /**
88 | * Add a object into the library
89 | * @param name the variable name
90 | * @param proc the object
91 | */
92 | protected void addNativeProcedure(String name,NativeProcedure proc){
93 | ScmSymbol sym=new ScmSymbol(name);
94 | lib.getInternalEnvironment().add(sym,new NativeEvaluable(proc));
95 | lib.getExportMap().put(sym,sym);
96 | }
97 | /**
98 | * Add a object into the library
99 | * @param name the variable name
100 | * @param proc the object
101 | */
102 | protected void addNativeProcedureMulti(String name,NativeProcedure proc){
103 | ScmSymbol sym=new ScmSymbol(name);
104 | lib.getInternalEnvironment().add(sym,new NativeEvaluableMulti(proc));
105 | lib.getExportMap().put(sym,sym);
106 | }
107 | /**
108 | * To be executed when the library actual being loaded
109 | * @param lib the library
110 | */
111 | protected abstract void init(Library lib);
112 | }
113 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/type/ScmPair.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.type;
18 | import java.util.*;
19 | /**
20 | * Represents the type pair in Scheme
21 | * @author kwong
22 | */
23 | public final class ScmPair extends ScmPairOrNil{
24 | private ScmObject car;
25 | private ScmObject cdr;
26 | /**
27 | * Construct a pair
28 | * @param car the car field
29 | * @param cdr the cdr field
30 | */
31 | public ScmPair(ScmObject car,ScmObject cdr){
32 | this.car=car;
33 | this.cdr=cdr;
34 | }
35 | /**
36 | * Corresponding to the procedure car in Scheme
37 | * @return
38 | */
39 | public ScmObject getCar(){
40 | return car;
41 | }
42 | /**
43 | * Corresponding to the procedure cdr in Scheme
44 | * @return
45 | */
46 | public ScmObject getCdr(){
47 | return cdr;
48 | }
49 | public ScmObject getCaar(){
50 | return ((ScmPair)car).getCar();
51 | }
52 | public ScmObject getCadr(){
53 | return ((ScmPair)cdr).getCar();
54 | }
55 | public ScmObject getCdar(){
56 | return ((ScmPair)car).getCdr();
57 | }
58 | public ScmObject getCddr(){
59 | return ((ScmPair)cdr).getCdr();
60 | }
61 | public ScmObject getCaddr(){
62 | return ((ScmPair)((ScmPair)cdr).getCdr()).getCar();
63 | }
64 | /**
65 | * Corresponding to the procedure set-car! in Scheme
66 | * @param car
67 | */
68 | public void setCar(ScmObject car){
69 | this.car=car;
70 | }
71 | /**
72 | * Corresponding to the procedure set-cdr! in Scheme
73 | * @param cdr
74 | */
75 | public void setCdr(ScmObject cdr){
76 | this.cdr=cdr;
77 | }
78 | @Override
79 | public boolean equals(Object obj){
80 | return obj==this||ObjectPair.equals(this,obj,new HashSet<>());
81 | }
82 | @Override
83 | public boolean equalsValue(ScmObject obj){
84 | return this==obj;
85 | }
86 | @Override
87 | public int hashCode(){
88 | int hash=7;
89 | if(!(car instanceof ScmPair||car instanceof ScmVector))
90 | hash=13*hash+Objects.hashCode(this.car);
91 | if(!(cdr instanceof ScmPair||cdr instanceof ScmVector))
92 | hash=13*hash+Objects.hashCode(this.cdr);
93 | return hash;
94 | }
95 | @Override
96 | public String toExternalRepresentation(){
97 | StringBuilder buf=new StringBuilder();
98 | IdentityHashMap refs=new IdentityHashMap<>();
99 | DatumRecord.collectReference(this,refs);
100 | toExternalRepresentation(buf,refs);
101 | return buf.toString();
102 | }
103 | boolean toExternalRepresentation(StringBuilder buf,IdentityHashMap refs){
104 | DatumRecord record=refs.get(this);
105 | if(record!=null&&record.isReused()){
106 | if(record.isDefined()){
107 | buf.append('#').append(record.getId()).append('#');
108 | return false;
109 | }else{
110 | buf.append('#').append(record.getId()).append('=');
111 | record.define();
112 | }
113 | }
114 | buf.append("(");
115 | DatumRecord.toExternalRepresentation(car,buf,refs);
116 | ScmObject next=cdr;
117 | boolean noCycle=true;
118 | while(next instanceof ScmPair&&!refs.get(next).isReused()){
119 | buf.append(" ");
120 | DatumRecord.toExternalRepresentation(((ScmPair)next).getCar(),buf,refs);
121 | next=((ScmPair)next).getCdr();
122 | }
123 | if(!(next instanceof ScmNil)){
124 | buf.append(" . ");
125 | DatumRecord.toExternalRepresentation(next,buf,refs);
126 | }
127 | buf.append(")");
128 | return true;
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/doc/example.tex:
--------------------------------------------------------------------------------
1 |
2 | \extrapart{Example} % -*- Mode: Lisp; Package: SCHEME; Syntax: Common-lisp -*-
3 |
4 | \nobreak
5 | The procedure {\cf integrate-system} integrates the system
6 | $$y_k^\prime = f_k(y_1, y_2, \ldots, y_n), \; k = 1, \ldots, n$$
7 | of differential equations with the method of Runge-Kutta.
8 |
9 | The parameter {\tt system-derivative} is a function that takes a system
10 | state (a vector of values for the state variables $y_1, \ldots, y_n$)
11 | and produces a system derivative (the values $y_1^\prime, \ldots,
12 | y_n^\prime$). The parameter {\tt initial-state} provides an initial
13 | system state, and {\tt h} is an initial guess for the length of the
14 | integration step.
15 |
16 | The value returned by {\cf integrate-system} is an infinite stream of
17 | system states.
18 |
19 | \begin{schemenoindent}
20 | (define (integrate-system system-derivative
21 | initial-state
22 | h)
23 | (let ((next (runge-kutta-4 system-derivative h)))
24 | (letrec ((states
25 | (cons initial-state
26 | (delay (map-streams next
27 | states)))))
28 | states)))%
29 | \end{schemenoindent}
30 |
31 | The procedure {\cf runge-kutta-4} takes a function, {\tt f}, that produces a
32 | system derivative from a system state. It
33 | produces a function that takes a system state and
34 | produces a new system state.
35 |
36 | \begin{schemenoindent}
37 | (define (runge-kutta-4 f h)
38 | (let ((*h (scale-vector h))
39 | (*2 (scale-vector 2))
40 | (*1/2 (scale-vector (/ 1 2)))
41 | (*1/6 (scale-vector (/ 1 6))))
42 | (lambda (y)
43 | ;; y is a system state
44 | (let* ((k0 (*h (f y)))
45 | (k1 (*h (f (add-vectors y (*1/2 k0)))))
46 | (k2 (*h (f (add-vectors y (*1/2 k1)))))
47 | (k3 (*h (f (add-vectors y k2)))))
48 | (add-vectors y
49 | (*1/6 (add-vectors k0
50 | (*2 k1)
51 | (*2 k2)
52 | k3)))))))
53 |
54 | (define (elementwise f)
55 | (lambda vectors
56 | (generate-vector
57 | (vector-length (car vectors))
58 | (lambda (i)
59 | (apply f
60 | (map (lambda (v) (vector-ref v i))
61 | vectors))))))
62 |
63 | (define (generate-vector size proc)
64 | (let ((ans (make-vector size)))
65 | (letrec ((loop
66 | (lambda (i)
67 | (cond ((= i size) ans)
68 | (else
69 | (vector-set! ans i (proc i))
70 | (loop (+ i 1)))))))
71 | (loop 0))))
72 |
73 | (define add-vectors (elementwise +))
74 |
75 | (define (scale-vector s)
76 | (elementwise (lambda (x) (* x s))))%
77 | \end{schemenoindent}
78 |
79 | The {\cf map-streams} procedure is analogous to {\cf map}: it applies its first
80 | argument (a procedure) to all the elements of its second argument (a
81 | stream).
82 |
83 | \begin{schemenoindent}
84 | (define (map-streams f s)
85 | (cons (f (head s))
86 | (delay (map-streams f (tail s)))))%
87 | \end{schemenoindent}
88 |
89 | Infinite streams are implemented as pairs whose car holds the first
90 | element of the stream and whose cdr holds a promise to deliver the rest
91 | of the stream.
92 |
93 | \begin{schemenoindent}
94 | (define head car)
95 | (define (tail stream)
96 | (force (cdr stream)))%
97 | \end{schemenoindent}
98 |
99 | \bigskip
100 | The following illustrates the use of {\cf integrate-system} in
101 | integrating the system
102 | $$ C {dv_C \over dt} = -i_L - {v_C \over R}$$\nobreak
103 | $$ L {di_L \over dt} = v_C$$
104 | which models a damped oscillator.
105 |
106 | \begin{schemenoindent}
107 | (define (damped-oscillator R L C)
108 | (lambda (state)
109 | (let ((Vc (vector-ref state 0))
110 | (Il (vector-ref state 1)))
111 | (vector (- 0 (+ (/ Vc (* R C)) (/ Il C)))
112 | (/ Vc L)))))
113 |
114 | (define the-states
115 | (integrate-system
116 | (damped-oscillator 10000 1000 .001)
117 | '\#(1 0)
118 | .01))%
119 | \end{schemenoindent}
120 |
121 |
--------------------------------------------------------------------------------
/src/com/github/chungkwong/jschememin/type/ScmBinaryInputPort.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Chan Chung Kwong <1m02math@126.com>
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package com.github.chungkwong.jschememin.type;
18 | import com.github.chungkwong.jschememin.*;
19 | import java.io.*;
20 | import java.math.*;
21 | import java.util.*;
22 | /**
23 | * Represents the type binary input port in Scheme
24 | * @author Chan Chung Kwong <1m02math@126.com>
25 | */
26 | public class ScmBinaryInputPort extends ScmPort{
27 | private final PushbackInputStream in;
28 | /**
29 | * Wrap a InputStream
30 | * @param in
31 | */
32 | public ScmBinaryInputPort(PushbackInputStream in){
33 | this.in=in;
34 | }
35 | /**
36 | * Wrap a InputStream
37 | * @param in
38 | */
39 | public ScmBinaryInputPort(InputStream in){
40 | this(new PushbackInputStream(in));
41 | }
42 | /**
43 | * Construct a port to read from a file
44 | * @param file the file name
45 | */
46 | public ScmBinaryInputPort(String file){
47 | try{
48 | this.in=new PushbackInputStream(new FileInputStream(Main.resolveFile(file)));
49 | }catch(FileNotFoundException ex){
50 | throw ScmError.toException(new ScmError(new ScmString(ex.getLocalizedMessage()),ScmNil.NIL,ScmError.ErrorType.FILE));
51 | }
52 | }
53 | /**
54 | * Corresponding to the procedure read-u8 in Scheme
55 | * @return
56 | * @throws IOException
57 | */
58 | public ScmObject readByte() throws IOException{
59 | int b=in.read();
60 | return b==-1?ScmEndOfFileObject.INSTANCE:new ScmInteger(BigInteger.valueOf(b));
61 | }
62 | /**
63 | * Corresponding to the procedure peek-u8 in Scheme
64 | * @return
65 | * @throws IOException
66 | */
67 | public ScmObject peekByte() throws IOException{
68 | int b=in.read();
69 | if(b==-1)
70 | return ScmEndOfFileObject.INSTANCE;
71 | else{
72 | in.unread(b);
73 | return new ScmInteger(BigInteger.valueOf(b));
74 | }
75 | }
76 | /**
77 | * Corresponding to the procedure read-bytevector in Scheme
78 | * @param max
79 | * @return
80 | * @throws IOException
81 | */
82 | public ScmObject readBytevector(ScmInteger max) throws IOException{
83 | int len=max.getValue().intValueExact();
84 | byte[] buf=new byte[len];
85 | len=in.read(buf);
86 | return len==-1?ScmEndOfFileObject.INSTANCE:new ScmByteVector(Arrays.copyOf(buf,len));
87 | }
88 | /**
89 | * Corresponding to the procedure read-bytevector in Scheme
90 | * @param vector
91 | * @param start
92 | * @param end
93 | * @return
94 | * @throws IOException
95 | */
96 | public ScmObject readBytevector(ScmByteVector vector,ScmInteger start,ScmInteger end) throws IOException{
97 | int offset=start.getValue().intValueExact();
98 | int len=end.getValue().intValueExact()-offset;
99 | len=in.read(vector.getByteArray(),offset,len);
100 | return len==-1?ScmEndOfFileObject.INSTANCE:new ScmInteger(BigInteger.valueOf(len));
101 | }
102 | /**
103 | * Corresponding to the procedure u8-ready in Scheme
104 | * @return
105 | * @throws IOException
106 | */
107 | public ScmBoolean ready() throws IOException{
108 | return ScmBoolean.valueOf(in.available()>=1);
109 | }
110 | /**
111 | * Corresponding to the procedure close-input-port in Scheme
112 | * @return
113 | * @throws IOException
114 | */
115 | @Override
116 | public ScmBinaryInputPort close()throws IOException{
117 | super.close();
118 | in.close();
119 | return this;
120 | }
121 | @Override
122 | public String toExternalRepresentation(){
123 | return in.toString();
124 | }
125 | }
--------------------------------------------------------------------------------