Functions as first-class objects, lambdas implemented. Added several new SFs
This commit is contained in:
parent
14ac02ab12
commit
c63b92bf41
@ -1,12 +1,12 @@
|
|||||||
#Tue Nov 24 11:54:14 CST 2009
|
#Tue Nov 24 14:17:29 CST 2009
|
||||||
build.dir=build
|
build.dir=build
|
||||||
src.dir=src
|
src.dir=src
|
||||||
grammar.output.dir=${src.dir}/edu/utexas/cs345/jdblisp/parser
|
grammar.output.dir=${src.dir}/edu/utexas/cs345/jdblisp/parser
|
||||||
build.jar=${build.dir}/JCLisp-${application.version}.${build.number}.jar
|
build.jar=${build.dir}/JCLisp-${application.version}.${build.number}.jar
|
||||||
build.number=6
|
build.number=19
|
||||||
dist.dir=dist
|
dist.dir=dist
|
||||||
dist.jar=${dist.dir}/JCLisp-${application.version}.jar
|
dist.jar=${dist.dir}/JCLisp-${application.version}.jar
|
||||||
lib.dir=lib
|
lib.dir=lib
|
||||||
grammar.file=${src.dir}/edu/utexas/cs345/jdblisp/Parser.jj
|
|
||||||
build.classes.dir=${build.dir}/classes
|
build.classes.dir=${build.dir}/classes
|
||||||
|
grammar.file=${src.dir}/edu/utexas/cs345/jdblisp/Parser.jj
|
||||||
application.version=0.1.0
|
application.version=0.1.0
|
||||||
|
@ -4,7 +4,19 @@ package edu.utexas.cs345.jdblisp;
|
|||||||
* FormEntry
|
* FormEntry
|
||||||
* @author Jonathan Bernard(jdbernard@gmail.com)
|
* @author Jonathan Bernard(jdbernard@gmail.com)
|
||||||
*/
|
*/
|
||||||
public interface FormEntry {
|
public abstract class FormEntry implements SExp {
|
||||||
SExp call(SymbolTable table, Seq arguments) throws LispException;
|
|
||||||
HelpTopic helpinfo();
|
public final Symbol name;
|
||||||
|
public HelpTopic helpinfo;
|
||||||
|
|
||||||
|
public FormEntry(Symbol name, HelpTopic helpinfo) {
|
||||||
|
this.name = name;
|
||||||
|
this.helpinfo = helpinfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract SExp call(SymbolTable table, Seq arguments) throws LispException;
|
||||||
|
public abstract String display(String offset);
|
||||||
|
|
||||||
|
public SExp eval(SymbolTable symbolTable) { return this; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,8 @@ package edu.utexas.cs345.jdblisp;
|
|||||||
* FunctionEntry
|
* FunctionEntry
|
||||||
* @author Jonathan Bernard (jdbernard@gmail.com)
|
* @author Jonathan Bernard (jdbernard@gmail.com)
|
||||||
*/
|
*/
|
||||||
public class FunctionEntry implements FormEntry {
|
public class FunctionEntry extends FormEntry {
|
||||||
|
|
||||||
public final HelpTopic helpinfo;
|
|
||||||
public final Symbol name;
|
|
||||||
protected final Symbol[] parameters;
|
protected final Symbol[] parameters;
|
||||||
protected final SExp body;
|
protected final SExp body;
|
||||||
|
|
||||||
@ -16,6 +14,7 @@ public class FunctionEntry implements FormEntry {
|
|||||||
//private Logger traceLog = Logger.getLogger(getClass());
|
//private Logger traceLog = Logger.getLogger(getClass());
|
||||||
|
|
||||||
public FunctionEntry(Symbol name, Symbol[] parameters, SExp body) {
|
public FunctionEntry(Symbol name, Symbol[] parameters, SExp body) {
|
||||||
|
super(name, null);
|
||||||
|
|
||||||
// build invocation help string
|
// build invocation help string
|
||||||
String invokation = "(" + name.name;
|
String invokation = "(" + name.name;
|
||||||
@ -26,7 +25,6 @@ public class FunctionEntry implements FormEntry {
|
|||||||
// build help topic
|
// build help topic
|
||||||
FormHelpTopic helpinfo = new FormHelpTopic(name.name, null, invokation, bodyInfo);
|
FormHelpTopic helpinfo = new FormHelpTopic(name.name, null, invokation, bodyInfo);
|
||||||
|
|
||||||
this.name = name;
|
|
||||||
this.parameters = parameters;
|
this.parameters = parameters;
|
||||||
this.body = body;
|
this.body = body;
|
||||||
this.helpinfo = helpinfo;
|
this.helpinfo = helpinfo;
|
||||||
@ -34,16 +32,21 @@ public class FunctionEntry implements FormEntry {
|
|||||||
|
|
||||||
public FunctionEntry(Symbol name, Symbol[] parameters, SExp body,
|
public FunctionEntry(Symbol name, Symbol[] parameters, SExp body,
|
||||||
HelpTopic helpinfo) {
|
HelpTopic helpinfo) {
|
||||||
this.name = name;
|
super(name, helpinfo);
|
||||||
this.parameters = parameters;
|
this.parameters = parameters;
|
||||||
this.body = body;
|
this.body = body;
|
||||||
this.helpinfo = helpinfo;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isTraceEnabled() { return traceEnabled ;}
|
public boolean isTraceEnabled() { return traceEnabled ;}
|
||||||
|
|
||||||
public void enableTrace(boolean enable) { this.traceEnabled = enable; }
|
public void enableTrace(boolean enable) { this.traceEnabled = enable; }
|
||||||
|
|
||||||
|
public String display(String offset) {
|
||||||
|
return offset + "Function: " + name.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() { return "<FUNCTION " + name.toString() + ">"; }
|
||||||
|
|
||||||
public SExp call(SymbolTable symbolTable, Seq arguments) throws LispException {
|
public SExp call(SymbolTable symbolTable, Seq arguments) throws LispException {
|
||||||
|
|
||||||
String traceString = null;
|
String traceString = null;
|
||||||
|
49
src/edu/utexas/cs345/jdblisp/Lambda.java
Normal file
49
src/edu/utexas/cs345/jdblisp/Lambda.java
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
package edu.utexas.cs345.jdblisp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lambda
|
||||||
|
*/
|
||||||
|
public class Lambda extends FunctionEntry {
|
||||||
|
|
||||||
|
private SymbolTable closure;
|
||||||
|
|
||||||
|
public Lambda(Symbol[] parameters, SExp body, SymbolTable closure) {
|
||||||
|
super(new Symbol(""), parameters, body);
|
||||||
|
|
||||||
|
this.closure = closure;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Lambda(Symbol[] parameters, SExp body, SymbolTable closure,
|
||||||
|
HelpTopic helpinfo) {
|
||||||
|
super(new Symbol(""), parameters, body, helpinfo);
|
||||||
|
|
||||||
|
this.closure = closure;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String display(String offset) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append(offset).append("Lambda : \n");
|
||||||
|
|
||||||
|
for (Symbol param : parameters)
|
||||||
|
sb.append(" ").append(offset).append("Parameter: \n")
|
||||||
|
.append(param.display(offset + " "));
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("<LAMBDA (");
|
||||||
|
for (Symbol param : parameters)
|
||||||
|
sb.append(param.toString()).append(" ");
|
||||||
|
sb.append(") >");
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SExp call(SymbolTable symbolTable, Seq arguments)
|
||||||
|
throws LispException {
|
||||||
|
return super.call(closure, arguments);
|
||||||
|
}
|
||||||
|
}
|
@ -40,7 +40,15 @@ public class List implements SExp {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return SExp.NIL;
|
// if the car is not a symbol, it had better be a lambda
|
||||||
|
SExp evaluated = seq.car.eval(table);
|
||||||
|
if (evaluated instanceof Lambda) {
|
||||||
|
return ((Lambda) evaluated).call(table, seq.cdr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// not a function call and not a lambda, error
|
||||||
|
throw new TypeException(seq.car, Lambda.class);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String display(String offset) {
|
public String display(String offset) {
|
||||||
|
@ -12,6 +12,7 @@ import edu.utexas.cs345.jdblisp.*;
|
|||||||
public class Parser {
|
public class Parser {
|
||||||
|
|
||||||
private static Symbol QUOTE_SYMB = new Symbol("QUOTE");
|
private static Symbol QUOTE_SYMB = new Symbol("QUOTE");
|
||||||
|
private static Symbol FUNCTION_SYMB = new Symbol("FUNCTION");
|
||||||
}
|
}
|
||||||
|
|
||||||
PARSER_END(Parser)
|
PARSER_END(Parser)
|
||||||
@ -30,6 +31,7 @@ TOKEN : /* PUNCTUATION */
|
|||||||
| < RPAREN: ")" >
|
| < RPAREN: ")" >
|
||||||
| < NIL: (["N","n"]["I","i"]["L","l"])>
|
| < NIL: (["N","n"]["I","i"]["L","l"])>
|
||||||
| < QUOTE: "'" >
|
| < QUOTE: "'" >
|
||||||
|
| < FUNCTION: "#'" >
|
||||||
| < KEYWORD: ":" >
|
| < KEYWORD: ":" >
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -43,7 +45,7 @@ TOKEN : /* LITERALS & SYMBOLS */
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SExp -> Symbol | Str | Num | List | "'" SExp
|
* SExp -> Symbol | Str | Num | List
|
||||||
*/
|
*/
|
||||||
SExp sexp():
|
SExp sexp():
|
||||||
{ SExp s = null; Token t;
|
{ SExp s = null; Token t;
|
||||||
@ -52,6 +54,7 @@ SExp sexp():
|
|||||||
| t = <STRG> { return new Str(t.image); }
|
| t = <STRG> { return new Str(t.image); }
|
||||||
| t = <NUMB> { return new Num(t.image); }
|
| t = <NUMB> { return new Num(t.image); }
|
||||||
| t = <QUOTE> s = sexp() { return new List(new Seq(QUOTE_SYMB, s)); }
|
| t = <QUOTE> s = sexp() { return new List(new Seq(QUOTE_SYMB, s)); }
|
||||||
|
| t = <FUNCTION> s = sexp() { return new List(new Seq(FUNCTION_SYMB, s)); }
|
||||||
| s = list() { return s; }
|
| s = list() { return s; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,22 +7,27 @@ import java.util.ArrayList;
|
|||||||
* SpecialFormEntry
|
* SpecialFormEntry
|
||||||
* @author Jonathan Bernard (jdbernard@gmail.com)
|
* @author Jonathan Bernard (jdbernard@gmail.com)
|
||||||
*/
|
*/
|
||||||
public abstract class SpecialFormEntry implements FormEntry {
|
public abstract class SpecialFormEntry extends FormEntry {
|
||||||
|
|
||||||
public final HelpTopic helpinfo;
|
|
||||||
|
|
||||||
protected LISPRuntime environment;
|
protected LISPRuntime environment;
|
||||||
|
|
||||||
public SpecialFormEntry(LISPRuntime environment, HelpTopic helpinfo) {
|
public SpecialFormEntry(Symbol name, LISPRuntime environment, HelpTopic helpinfo) {
|
||||||
|
super(name, helpinfo);
|
||||||
this.environment = environment;
|
this.environment = environment;
|
||||||
this.helpinfo = helpinfo;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public HelpTopic helpinfo() { return helpinfo; }
|
|
||||||
|
|
||||||
public abstract SExp call(SymbolTable symbolTable, Seq arguments)
|
public abstract SExp call(SymbolTable symbolTable, Seq arguments)
|
||||||
throws LispException;
|
throws LispException;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String display(String offset) {
|
||||||
|
return offset + "Special Form Entry: " + name.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "<SPECIAL-FORM (" + name.toString() + ") >";
|
||||||
|
}
|
||||||
// ------------------------
|
// ------------------------
|
||||||
// SPECIAL FORMS DEFINITION
|
// SPECIAL FORMS DEFINITION
|
||||||
// ------------------------
|
// ------------------------
|
||||||
@ -40,6 +45,7 @@ public abstract class SpecialFormEntry implements FormEntry {
|
|||||||
// ---
|
// ---
|
||||||
|
|
||||||
final SpecialFormEntry DIV = new SpecialFormEntry(
|
final SpecialFormEntry DIV = new SpecialFormEntry(
|
||||||
|
new Symbol("/"),
|
||||||
environment,
|
environment,
|
||||||
new FormHelpTopic("/", "Divide several expressions.",
|
new FormHelpTopic("/", "Divide several expressions.",
|
||||||
"(- divisor) | (- dividend <divisor_1> [... <divisor_n>])",
|
"(- divisor) | (- dividend <divisor_1> [... <divisor_n>])",
|
||||||
@ -99,6 +105,7 @@ public abstract class SpecialFormEntry implements FormEntry {
|
|||||||
// ---
|
// ---
|
||||||
|
|
||||||
final SpecialFormEntry DIF = new SpecialFormEntry(
|
final SpecialFormEntry DIF = new SpecialFormEntry(
|
||||||
|
new Symbol("-"),
|
||||||
environment,
|
environment,
|
||||||
new FormHelpTopic("-", "Subtract several expressions.",
|
new FormHelpTopic("-", "Subtract several expressions.",
|
||||||
"(- subtrahend) | (- <minuend> <subtrahend_1> [... <subtrahend_n>])",
|
"(- subtrahend) | (- <minuend> <subtrahend_1> [... <subtrahend_n>])",
|
||||||
@ -158,6 +165,7 @@ public abstract class SpecialFormEntry implements FormEntry {
|
|||||||
// ---
|
// ---
|
||||||
|
|
||||||
final SpecialFormEntry MUL = new SpecialFormEntry(
|
final SpecialFormEntry MUL = new SpecialFormEntry(
|
||||||
|
new Symbol("*"),
|
||||||
environment,
|
environment,
|
||||||
new FormHelpTopic("*", "Multiply several expressions.",
|
new FormHelpTopic("*", "Multiply several expressions.",
|
||||||
"(+ [<multiplicand_1> ... <multiplicand_n>])",
|
"(+ [<multiplicand_1> ... <multiplicand_n>])",
|
||||||
@ -193,6 +201,7 @@ public abstract class SpecialFormEntry implements FormEntry {
|
|||||||
// ---
|
// ---
|
||||||
|
|
||||||
final SpecialFormEntry SUM = new SpecialFormEntry(
|
final SpecialFormEntry SUM = new SpecialFormEntry(
|
||||||
|
new Symbol("+"),
|
||||||
environment,
|
environment,
|
||||||
new FormHelpTopic("+", "Sum several expressions.",
|
new FormHelpTopic("+", "Sum several expressions.",
|
||||||
"(+ [<addend_1> ... <addend_n>])",
|
"(+ [<addend_1> ... <addend_n>])",
|
||||||
@ -222,11 +231,18 @@ public abstract class SpecialFormEntry implements FormEntry {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ---
|
||||||
|
// CAR
|
||||||
|
// ---
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
|
||||||
// ----
|
// ----
|
||||||
// CONS
|
// CONS
|
||||||
// ----
|
// ----
|
||||||
|
|
||||||
SpecialFormEntry CONS = new SpecialFormEntry(
|
final SpecialFormEntry CONS = new SpecialFormEntry(
|
||||||
|
new Symbol("CONS"),
|
||||||
environment,
|
environment,
|
||||||
new FormHelpTopic("CONS", "create a cons",
|
new FormHelpTopic("CONS", "create a cons",
|
||||||
"(cons <object-1> <object-2>) => <cons>",
|
"(cons <object-1> <object-2>) => <cons>",
|
||||||
@ -262,6 +278,7 @@ public abstract class SpecialFormEntry implements FormEntry {
|
|||||||
// -----
|
// -----
|
||||||
|
|
||||||
final SpecialFormEntry DEFUN = new SpecialFormEntry(
|
final SpecialFormEntry DEFUN = new SpecialFormEntry(
|
||||||
|
new Symbol("DEFUN"),
|
||||||
environment,
|
environment,
|
||||||
new FormHelpTopic("DEFUN", "Define a (global) function.",
|
new FormHelpTopic("DEFUN", "Define a (global) function.",
|
||||||
"(defun <name> (<param-list>) <func-body>)",
|
"(defun <name> (<param-list>) <func-body>)",
|
||||||
@ -330,6 +347,7 @@ public abstract class SpecialFormEntry implements FormEntry {
|
|||||||
// ------------
|
// ------------
|
||||||
|
|
||||||
final SpecialFormEntry DEFPARAMETER = new SpecialFormEntry(
|
final SpecialFormEntry DEFPARAMETER = new SpecialFormEntry(
|
||||||
|
new Symbol("DEFPARAMETER"),
|
||||||
environment,
|
environment,
|
||||||
new FormHelpTopic("DEFPARAMETER", "define a dynamic variable",
|
new FormHelpTopic("DEFPARAMETER", "define a dynamic variable",
|
||||||
"(defparameter <name> <initial-value> [<documentation>]) => <name>",
|
"(defparameter <name> <initial-value> [<documentation>]) => <name>",
|
||||||
@ -388,6 +406,7 @@ public abstract class SpecialFormEntry implements FormEntry {
|
|||||||
// ------
|
// ------
|
||||||
|
|
||||||
final SpecialFormEntry DEFVAR = new SpecialFormEntry(
|
final SpecialFormEntry DEFVAR = new SpecialFormEntry(
|
||||||
|
new Symbol("DEFVAR"),
|
||||||
environment,
|
environment,
|
||||||
new FormHelpTopic("DEFVAR", "define a variable",
|
new FormHelpTopic("DEFVAR", "define a variable",
|
||||||
"(defvar <name> [<initial-value> [<documentation>]]) => <name>",
|
"(defvar <name> [<initial-value> [<documentation>]]) => <name>",
|
||||||
@ -431,6 +450,7 @@ public abstract class SpecialFormEntry implements FormEntry {
|
|||||||
// ----------------
|
// ----------------
|
||||||
|
|
||||||
final SpecialFormEntry ENABLEDEBUGAST = new SpecialFormEntry(
|
final SpecialFormEntry ENABLEDEBUGAST = new SpecialFormEntry(
|
||||||
|
new Symbol("ENABLE-DEBUG-AST"),
|
||||||
environment,
|
environment,
|
||||||
new FormHelpTopic("ENABLE-DEBUG-AST",
|
new FormHelpTopic("ENABLE-DEBUG-AST",
|
||||||
"Enable debug information: abstract syntax tree.",
|
"Enable debug information: abstract syntax tree.",
|
||||||
@ -457,11 +477,93 @@ public abstract class SpecialFormEntry implements FormEntry {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// --------
|
||||||
|
// FUNCTION
|
||||||
|
// --------
|
||||||
|
|
||||||
|
final SpecialFormEntry FUNCTION = new SpecialFormEntry(
|
||||||
|
new Symbol("FUNCTION"),
|
||||||
|
environment,
|
||||||
|
new FormHelpTopic("FUNCTION", "retrieve a function",
|
||||||
|
"(function <func-name>) => <function>",
|
||||||
|
"function returns the function specified by the symbol passed "
|
||||||
|
+ " as an argument. #'funcname is equivalent to (function "
|
||||||
|
+ " funcname).",
|
||||||
|
"func-name", "a symbol naming a function",
|
||||||
|
"function", "a function"))
|
||||||
|
{
|
||||||
|
public SExp call(SymbolTable symbolTable, Seq arguments)
|
||||||
|
throws LispException {
|
||||||
|
FormEntry fe = null;
|
||||||
|
|
||||||
|
if (arguments == null || arguments.length() != 1)
|
||||||
|
throw new InvalidArgumentQuantityException(1);
|
||||||
|
|
||||||
|
if (!(arguments.car instanceof Symbol))
|
||||||
|
throw new TypeException(arguments.car, Symbol.class);
|
||||||
|
|
||||||
|
fe = symbolTable.lookupFunction((Symbol) arguments.car);
|
||||||
|
|
||||||
|
if (fe == null)
|
||||||
|
throw new UndefinedFunctionException((Symbol) arguments.car);
|
||||||
|
|
||||||
|
return fe;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// -------
|
||||||
|
// FUNCALL
|
||||||
|
// -------
|
||||||
|
|
||||||
|
final SpecialFormEntry FUNCALL = new SpecialFormEntry(
|
||||||
|
new Symbol("FUNCALL"),
|
||||||
|
environment,
|
||||||
|
new FormHelpTopic("FUNCALL", "make a function call",
|
||||||
|
"(funcall <function> <arg>*) => <result>",
|
||||||
|
"funcall applies function to args. If function is a symbol, "
|
||||||
|
+ "it is coerced to a function as if by finding its "
|
||||||
|
+ "functional value in the global environment.",
|
||||||
|
"function", "a function designator",
|
||||||
|
"arg", "an object",
|
||||||
|
"results", "the result of the function call"))
|
||||||
|
{
|
||||||
|
public SExp call(SymbolTable symbolTable, Seq arguments)
|
||||||
|
throws LispException {
|
||||||
|
|
||||||
|
if (arguments == null)
|
||||||
|
throw new InvalidArgumentQuantityException(
|
||||||
|
"form requires at least one argument.");
|
||||||
|
|
||||||
|
// first argument: function designator
|
||||||
|
SExp func = arguments.car.eval(symbolTable);
|
||||||
|
FormEntry fe = null;
|
||||||
|
arguments = arguments.cdr;
|
||||||
|
|
||||||
|
// cast if already a form entry
|
||||||
|
if (func instanceof FormEntry) fe = (FormEntry) func;
|
||||||
|
|
||||||
|
// lookup the function if it is a symbol
|
||||||
|
if (func instanceof Symbol) {
|
||||||
|
fe = environment.globalSymbolTable
|
||||||
|
.lookupFunction((Symbol) func);
|
||||||
|
if (fe == null)
|
||||||
|
throw new UndefinedFunctionException((Symbol) func);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fe == null)
|
||||||
|
throw new TypeException(func, FormEntry.class);
|
||||||
|
|
||||||
|
// make the function call
|
||||||
|
return fe.call(symbolTable, arguments);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// ----
|
// ----
|
||||||
// GETF
|
// GETF
|
||||||
// ----
|
// ----
|
||||||
|
|
||||||
SpecialFormEntry GETF = new SpecialFormEntry(
|
final SpecialFormEntry GETF = new SpecialFormEntry(
|
||||||
|
new Symbol("GETF"),
|
||||||
environment,
|
environment,
|
||||||
new FormHelpTopic("GETF", "",
|
new FormHelpTopic("GETF", "",
|
||||||
"(getf <plist> <indicator> [<default>]) => <value>",
|
"(getf <plist> <indicator> [<default>]) => <value>",
|
||||||
@ -525,6 +627,7 @@ public abstract class SpecialFormEntry implements FormEntry {
|
|||||||
// ----
|
// ----
|
||||||
|
|
||||||
final SpecialFormEntry HELP = new SpecialFormEntry(
|
final SpecialFormEntry HELP = new SpecialFormEntry(
|
||||||
|
new Symbol("HELP"),
|
||||||
environment,
|
environment,
|
||||||
new FormHelpTopic("HELP",
|
new FormHelpTopic("HELP",
|
||||||
"Display online help information for a topic.",
|
"Display online help information for a topic.",
|
||||||
@ -553,7 +656,7 @@ public abstract class SpecialFormEntry implements FormEntry {
|
|||||||
// lookup help for funtion
|
// lookup help for funtion
|
||||||
FormEntry fe = symbolTable.lookupFunction(
|
FormEntry fe = symbolTable.lookupFunction(
|
||||||
(Symbol) arguments.car);
|
(Symbol) arguments.car);
|
||||||
if (fe != null) topics.add(fe.helpinfo());
|
if (fe != null) topics.add(fe.helpinfo);
|
||||||
|
|
||||||
// lookup help for variable
|
// lookup help for variable
|
||||||
VariableEntry ve = symbolTable.lookupVariable(
|
VariableEntry ve = symbolTable.lookupVariable(
|
||||||
@ -576,6 +679,7 @@ public abstract class SpecialFormEntry implements FormEntry {
|
|||||||
// --
|
// --
|
||||||
|
|
||||||
final SpecialFormEntry IF = new SpecialFormEntry(
|
final SpecialFormEntry IF = new SpecialFormEntry(
|
||||||
|
new Symbol("IF"),
|
||||||
environment,
|
environment,
|
||||||
new FormHelpTopic("IF",
|
new FormHelpTopic("IF",
|
||||||
"conditional code execution",
|
"conditional code execution",
|
||||||
@ -612,11 +716,63 @@ public abstract class SpecialFormEntry implements FormEntry {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ------
|
||||||
|
// LAMBDA
|
||||||
|
// ------
|
||||||
|
|
||||||
|
final SpecialFormEntry LAMBDA = new SpecialFormEntry(
|
||||||
|
new Symbol("LAMBDA"),
|
||||||
|
environment,
|
||||||
|
new FormHelpTopic("LAMDA",
|
||||||
|
"create an anonymous function over the current lexical closure",
|
||||||
|
"(lambda <param-list> <form>) => <lambda>",
|
||||||
|
"",
|
||||||
|
"param-list", "a list of symbols",
|
||||||
|
"form", "a form",
|
||||||
|
"lambda", "a function"))
|
||||||
|
{
|
||||||
|
public SExp call(SymbolTable symbolTable, Seq arguments)
|
||||||
|
throws LispException {
|
||||||
|
|
||||||
|
ArrayList<Symbol> parameters = new ArrayList<Symbol>();
|
||||||
|
SExp body;
|
||||||
|
Seq paramSeq;
|
||||||
|
|
||||||
|
if (arguments.length() != 2)
|
||||||
|
throw new InvalidArgumentQuantityException(
|
||||||
|
2, arguments.length());
|
||||||
|
|
||||||
|
// first parameter: parameters to the lambda
|
||||||
|
if (!(arguments.car instanceof List))
|
||||||
|
throw new TypeException(arguments.car, List.class);
|
||||||
|
|
||||||
|
paramSeq = ((List) arguments.car).seq;
|
||||||
|
while (paramSeq != null) {
|
||||||
|
if (!(paramSeq.car instanceof Symbol))
|
||||||
|
throw new TypeException(paramSeq.car, Symbol.class);
|
||||||
|
|
||||||
|
parameters.add((Symbol) paramSeq.car);
|
||||||
|
paramSeq = paramSeq.cdr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// second argument: function body
|
||||||
|
arguments = arguments.cdr;
|
||||||
|
assert (arguments != null);
|
||||||
|
|
||||||
|
body = arguments.car;
|
||||||
|
|
||||||
|
return new Lambda(parameters.toArray(new Symbol[]{}),
|
||||||
|
body, symbolTable);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// ---
|
// ---
|
||||||
// LET
|
// LET
|
||||||
// ---
|
// ---
|
||||||
|
|
||||||
final SpecialFormEntry LET = new SpecialFormEntry(
|
final SpecialFormEntry LET = new SpecialFormEntry(
|
||||||
|
new Symbol("LET"),
|
||||||
environment,
|
environment,
|
||||||
new FormHelpTopic("LET", "create new lexical variable bindings",
|
new FormHelpTopic("LET", "create new lexical variable bindings",
|
||||||
"(let (([<var> <init-form>])*) <form>*) => <result>",
|
"(let (([<var> <init-form>])*) <form>*) => <result>",
|
||||||
@ -705,6 +861,7 @@ public abstract class SpecialFormEntry implements FormEntry {
|
|||||||
// ----
|
// ----
|
||||||
|
|
||||||
final SpecialFormEntry LET_STAR = new SpecialFormEntry(
|
final SpecialFormEntry LET_STAR = new SpecialFormEntry(
|
||||||
|
new Symbol("LET*"),
|
||||||
environment,
|
environment,
|
||||||
new FormHelpTopic("LET*", "create new lexical variable bindings",
|
new FormHelpTopic("LET*", "create new lexical variable bindings",
|
||||||
"(let (([<var> <init-form>])*) <form>*) => <result>",
|
"(let (([<var> <init-form>])*) <form>*) => <result>",
|
||||||
@ -794,6 +951,7 @@ public abstract class SpecialFormEntry implements FormEntry {
|
|||||||
// ----
|
// ----
|
||||||
|
|
||||||
final SpecialFormEntry LIST = new SpecialFormEntry(
|
final SpecialFormEntry LIST = new SpecialFormEntry(
|
||||||
|
new Symbol("LIST"),
|
||||||
environment,
|
environment,
|
||||||
new FormHelpTopic("LIST", "create a list",
|
new FormHelpTopic("LIST", "create a list",
|
||||||
"(list <object>*) => list",
|
"(list <object>*) => list",
|
||||||
@ -829,6 +987,7 @@ public abstract class SpecialFormEntry implements FormEntry {
|
|||||||
// -----
|
// -----
|
||||||
|
|
||||||
final SpecialFormEntry QUOTE = new SpecialFormEntry(
|
final SpecialFormEntry QUOTE = new SpecialFormEntry(
|
||||||
|
new Symbol("QUOTE"),
|
||||||
environment,
|
environment,
|
||||||
new FormHelpTopic("QUOTE", "Return objects unevaluated.",
|
new FormHelpTopic("QUOTE", "Return objects unevaluated.",
|
||||||
"(quote <object>) => <object>",
|
"(quote <object>) => <object>",
|
||||||
@ -851,6 +1010,7 @@ public abstract class SpecialFormEntry implements FormEntry {
|
|||||||
// -----
|
// -----
|
||||||
|
|
||||||
final SpecialFormEntry PROGN = new SpecialFormEntry(
|
final SpecialFormEntry PROGN = new SpecialFormEntry(
|
||||||
|
new Symbol("PROGN"),
|
||||||
environment,
|
environment,
|
||||||
new FormHelpTopic("PROGN",
|
new FormHelpTopic("PROGN",
|
||||||
"evaluate forms in the order they are given",
|
"evaluate forms in the order they are given",
|
||||||
@ -883,6 +1043,7 @@ public abstract class SpecialFormEntry implements FormEntry {
|
|||||||
// ----
|
// ----
|
||||||
|
|
||||||
final SpecialFormEntry SETQ = new SpecialFormEntry(
|
final SpecialFormEntry SETQ = new SpecialFormEntry(
|
||||||
|
new Symbol("SETQ"),
|
||||||
environment,
|
environment,
|
||||||
new FormHelpTopic("SETQ", "Assigns values to variables.",
|
new FormHelpTopic("SETQ", "Assigns values to variables.",
|
||||||
"(setq [<name> <form>]*)",
|
"(setq [<name> <form>]*)",
|
||||||
@ -943,6 +1104,7 @@ public abstract class SpecialFormEntry implements FormEntry {
|
|||||||
// -----
|
// -----
|
||||||
|
|
||||||
final SpecialFormEntry TRACE = new SpecialFormEntry(
|
final SpecialFormEntry TRACE = new SpecialFormEntry(
|
||||||
|
new Symbol("TRACE"),
|
||||||
environment,
|
environment,
|
||||||
new FormHelpTopic("TRACE",
|
new FormHelpTopic("TRACE",
|
||||||
"enable trace information for a function",
|
"enable trace information for a function",
|
||||||
@ -975,24 +1137,27 @@ public abstract class SpecialFormEntry implements FormEntry {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
environment.globalSymbolTable.bind(new Symbol("-"), DIF);
|
environment.globalSymbolTable.bind(DIF.name, DIF);
|
||||||
environment.globalSymbolTable.bind(new Symbol("/"), DIV);
|
environment.globalSymbolTable.bind(DIV.name, DIV);
|
||||||
environment.globalSymbolTable.bind(new Symbol("*"), MUL);
|
environment.globalSymbolTable.bind(MUL.name, MUL);
|
||||||
environment.globalSymbolTable.bind(new Symbol("+"), SUM);
|
environment.globalSymbolTable.bind(SUM.name, SUM);
|
||||||
environment.globalSymbolTable.bind(new Symbol("CONS"), CONS);
|
environment.globalSymbolTable.bind(CONS.name, CONS);
|
||||||
environment.globalSymbolTable.bind(new Symbol("DEFUN"), DEFUN);
|
environment.globalSymbolTable.bind(DEFUN.name, DEFUN);
|
||||||
environment.globalSymbolTable.bind(new Symbol("DEFPARAMETER"), DEFPARAMETER);
|
environment.globalSymbolTable.bind(DEFPARAMETER.name, DEFPARAMETER);
|
||||||
environment.globalSymbolTable.bind(new Symbol("DEFVAR"), DEFVAR);
|
environment.globalSymbolTable.bind(DEFVAR.name, DEFVAR);
|
||||||
environment.globalSymbolTable.bind(new Symbol("ENABLE-DEBUG-AST"), ENABLEDEBUGAST);
|
environment.globalSymbolTable.bind(ENABLEDEBUGAST.name, ENABLEDEBUGAST);
|
||||||
environment.globalSymbolTable.bind(new Symbol("GETF"), GETF);
|
environment.globalSymbolTable.bind(FUNCALL.name, FUNCALL);
|
||||||
environment.globalSymbolTable.bind(new Symbol("HELP"), HELP);
|
environment.globalSymbolTable.bind(FUNCTION.name, FUNCTION);
|
||||||
environment.globalSymbolTable.bind(new Symbol("IF"), IF);
|
environment.globalSymbolTable.bind(GETF.name, GETF);
|
||||||
environment.globalSymbolTable.bind(new Symbol("LET"), LET);
|
environment.globalSymbolTable.bind(HELP.name, HELP);
|
||||||
environment.globalSymbolTable.bind(new Symbol("LET*"), LET_STAR);
|
environment.globalSymbolTable.bind(IF.name, IF);
|
||||||
environment.globalSymbolTable.bind(new Symbol("LIST"), LIST);
|
environment.globalSymbolTable.bind(LAMBDA.name, LAMBDA);
|
||||||
environment.globalSymbolTable.bind(new Symbol("QUOTE"), QUOTE);
|
environment.globalSymbolTable.bind(LET.name, LET);
|
||||||
environment.globalSymbolTable.bind(new Symbol("PROGN"), PROGN);
|
environment.globalSymbolTable.bind(LET_STAR.name, LET_STAR);
|
||||||
environment.globalSymbolTable.bind(new Symbol("SETQ"), SETQ);
|
environment.globalSymbolTable.bind(LIST.name, LIST);
|
||||||
environment.globalSymbolTable.bind(new Symbol("TRACE"), TRACE);
|
environment.globalSymbolTable.bind(QUOTE.name, QUOTE);
|
||||||
|
environment.globalSymbolTable.bind(PROGN.name, PROGN);
|
||||||
|
environment.globalSymbolTable.bind(SETQ.name, SETQ);
|
||||||
|
environment.globalSymbolTable.bind(TRACE.name, TRACE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,4 +99,5 @@ public class SymbolTable {
|
|||||||
// search outer scope
|
// search outer scope
|
||||||
return enclosingTable.lookupVariable(s);
|
return enclosingTable.lookupVariable(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
9
todo.txt
9
todo.txt
@ -1,11 +1,15 @@
|
|||||||
Outstanding
|
Outstanding
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
|
- Implement CAR
|
||||||
|
- Implement CDR
|
||||||
- Implement FORMAT
|
- Implement FORMAT
|
||||||
- Implement GETF
|
- Implement FIRST
|
||||||
- Implement lambdas
|
- Implement lambdas
|
||||||
|
- Implement LAST
|
||||||
- Implement LIST*
|
- Implement LIST*
|
||||||
- Implement macros
|
- Implement macros
|
||||||
|
- Implement arithmetic comparisons
|
||||||
- Implement packages
|
- Implement packages
|
||||||
- Implement READ and PRINT
|
- Implement READ and PRINT
|
||||||
- Implement SETF
|
- Implement SETF
|
||||||
@ -20,11 +24,12 @@ Outstanding
|
|||||||
Partially Done
|
Partially Done
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
P Implement keywords
|
|
||||||
|
|
||||||
Done
|
Done
|
||||||
----
|
----
|
||||||
|
|
||||||
|
D Implement keywords
|
||||||
|
D Implement GETF
|
||||||
D Add ' notation for quote
|
D Add ' notation for quote
|
||||||
D Define NIL
|
D Define NIL
|
||||||
D Define T
|
D Define T
|
||||||
|
Loading…
x
Reference in New Issue
Block a user