Polished build process. Added CONS special form.
This commit is contained in:
parent
e6a608ee2b
commit
2c0e932f89
@ -1,28 +1,29 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project name="Common Build Versioning" >
|
<project name="Common Build Versioning" >
|
||||||
<property name="cbv-basedir" value="nbproject" />
|
<property name="cbv-basedir" value="${basedir}" />
|
||||||
|
<property name="cbv-property-file" value="project.properties"/>
|
||||||
|
|
||||||
<target name="-cbv-init">
|
<target name="-cbv-init">
|
||||||
<property file="${cbv-basedir}/project.versioning.properties" />
|
<property file="${cbv-basedir}/${cbv-property-file}" />
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
<target name="-pre-set-version" />
|
<target name="-pre-set-version" />
|
||||||
<target name="-do-set-version">
|
<target name="-do-set-version">
|
||||||
<input message="Current version is ${application.version}. Enter new version: " addproperty="new-version"/>
|
<input message="Current version is ${application.version}. Enter new version: " addproperty="new-version"/>
|
||||||
<propertyfile file="${cbv-basedir}/project.versioning.properties">
|
<propertyfile file="${cbv-basedir}/${cbv-property-file}">
|
||||||
<entry key="application.version" value="${new-version}" />
|
<entry key="application.version" value="${new-version}" />
|
||||||
<entry key="build.number" value="0" />
|
<entry key="build.number" value="0" />
|
||||||
</propertyfile>
|
</propertyfile>
|
||||||
<property file="${cbv-basedir}/project.versioning.properties" />
|
<property file="${cbv-basedir}/${cbv-property-file}" />
|
||||||
</target>
|
</target>
|
||||||
<target name="-post-set-version" />
|
<target name="-post-set-version" />
|
||||||
<target name="set-version" depends="-cbv-init,-pre-set-version,-do-set-version,-post-set-version"/>
|
<target name="set-version" depends="-cbv-init,-pre-set-version,-do-set-version,-post-set-version"/>
|
||||||
|
|
||||||
<target name="increment-build-number">
|
<target name="increment-build-number">
|
||||||
<propertyfile file="${cbv-basedir}/project.versioning.properties">
|
<propertyfile file="${cbv-basedir}/${cbv-property-file}">
|
||||||
<entry key="build.number" operation="+" type="int" default="0"/>
|
<entry key="build.number" operation="+" type="int" default="0"/>
|
||||||
</propertyfile>
|
</propertyfile>
|
||||||
<property file="${cbv-basedir}/project.versioning.properties" />
|
<property file="${cbv-basedir}/${cbv-property-file}" />
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
28
build.xml
28
build.xml
@ -12,7 +12,7 @@
|
|||||||
<!-- This path represents all run-time dependancies -->
|
<!-- This path represents all run-time dependancies -->
|
||||||
<path id="java.path">
|
<path id="java.path">
|
||||||
<path refid="javac.path"/>
|
<path refid="javac.path"/>
|
||||||
<pathelement path="${build.dir}"/>
|
<pathelement path="${build.classes.dir}"/>
|
||||||
</path>
|
</path>
|
||||||
|
|
||||||
<target name="init">
|
<target name="init">
|
||||||
@ -35,20 +35,38 @@
|
|||||||
|
|
||||||
<target name="compile" depends="compile-parser">
|
<target name="compile" depends="compile-parser">
|
||||||
<!-- Make build directory if it does not exist -->
|
<!-- Make build directory if it does not exist -->
|
||||||
<mkdir dir="${build.dir}"/>
|
<mkdir dir="${build.classes.dir}"/>
|
||||||
|
|
||||||
<!-- Compile all sources to build directory -->
|
<!-- Compile all sources to build directory -->
|
||||||
<javac
|
<javac
|
||||||
srcdir="${src.dir}"
|
srcdir="${src.dir}"
|
||||||
destdir="${build.dir}"
|
destdir="${build.classes.dir}"
|
||||||
classpathref="javac.path"
|
classpathref="javac.path"
|
||||||
debug="on"
|
debug="on"
|
||||||
debuglevel="source,vars,lines"/>
|
debuglevel="source,vars,lines"/>
|
||||||
|
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
<target name="dist" depends="init,compile">
|
<target name="build" depends="compile,increment-build-number">
|
||||||
<mkdir dir="${dist.dir}"/>
|
<jar
|
||||||
|
basedir="${build.classes.dir}"
|
||||||
|
destfile="${build.jar}">
|
||||||
|
<manifest>
|
||||||
|
<attribute
|
||||||
|
name="Main-Class"
|
||||||
|
value="edu.utexas.cs345.jdblisp.LISPRuntime"/>
|
||||||
|
<attribute
|
||||||
|
name="Built-By"
|
||||||
|
value="Jonathan Bernard (jdbernard@gmail.com)"/>
|
||||||
|
</manifest>
|
||||||
|
</jar>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="dist" depends="build">
|
||||||
|
<mkdir dir="${dist.dir}/lib"/>
|
||||||
|
<move file="${build.jar}" tofile="${dist.jar}" />
|
||||||
|
<copy todir="${dist.dir}/lib">
|
||||||
|
<fileset dir="${lib.dir}"/>
|
||||||
|
</copy>
|
||||||
</target>
|
</target>
|
||||||
</project>
|
</project>
|
||||||
|
@ -1,7 +1,12 @@
|
|||||||
src.dir=src
|
#Tue Nov 24 11:54:14 CST 2009
|
||||||
build.dir=build
|
build.dir=build
|
||||||
|
src.dir=src
|
||||||
|
grammar.output.dir=${src.dir}/edu/utexas/cs345/jdblisp/parser
|
||||||
|
build.jar=${build.dir}/JCLisp-${application.version}.${build.number}.jar
|
||||||
|
build.number=6
|
||||||
dist.dir=dist
|
dist.dir=dist
|
||||||
|
dist.jar=${dist.dir}/JCLisp-${application.version}.jar
|
||||||
lib.dir=lib
|
lib.dir=lib
|
||||||
grammar.file=${src.dir}/edu/utexas/cs345/jdblisp/Parser.jj
|
grammar.file=${src.dir}/edu/utexas/cs345/jdblisp/Parser.jj
|
||||||
grammar.output.dir=${src.dir}/edu/utexas/cs345/jdblisp/parser
|
build.classes.dir=${build.dir}/classes
|
||||||
project.version=0.1.0
|
application.version=0.1.0
|
||||||
|
46
src/edu/utexas/cs345/jdblisp/Cons.java
Normal file
46
src/edu/utexas/cs345/jdblisp/Cons.java
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
package edu.utexas.cs345.jdblisp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cons
|
||||||
|
* @author Jonathan Bernard (jdbernard@gmail.com)
|
||||||
|
*/
|
||||||
|
public class Cons extends Seq {
|
||||||
|
|
||||||
|
public final SExp cdr;
|
||||||
|
|
||||||
|
public Cons(SExp car, SExp cdr) {
|
||||||
|
super(car, (cdr == null ||
|
||||||
|
cdr == SExp.NIL ||
|
||||||
|
!(cdr instanceof Seq) ?
|
||||||
|
null : (Seq) cdr));
|
||||||
|
this.cdr = (cdr == SExp.NIL ? null : cdr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Cons(SExp car, List list) {
|
||||||
|
super(car, list.seq);
|
||||||
|
this.cdr = list.seq;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String display(String offset) {
|
||||||
|
if (this.cdr == super.cdr)
|
||||||
|
return super.display(offset);
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append(offset);
|
||||||
|
sb.append("Cons: \n");
|
||||||
|
|
||||||
|
sb.append(car.display(offset + " "));
|
||||||
|
|
||||||
|
if (cdr != null) sb.append(cdr.display(offset));
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
if (this.cdr == super.cdr) return super.toString();
|
||||||
|
|
||||||
|
else return car.toString() + " . " + cdr.toString();
|
||||||
|
}
|
||||||
|
}
|
@ -94,7 +94,7 @@ public class HelpTopic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// any left over, it will fit on one line
|
// any left over, it will fit on one line
|
||||||
if (i - lineStartIdx > 1) {
|
if (i - lineStartIdx > 0) {
|
||||||
String lastLine = message.substring(lineStartIdx);
|
String lastLine = message.substring(lineStartIdx);
|
||||||
printer.print(lastLine);
|
printer.print(lastLine);
|
||||||
curLineLength += lastLine.length();
|
curLineLength += lastLine.length();
|
||||||
|
@ -30,7 +30,12 @@ public class List implements SExp {
|
|||||||
// look up in the symbol table
|
// look up in the symbol table
|
||||||
FormEntry functionEntry = table.lookupFunction((Symbol) seq.car);
|
FormEntry functionEntry = table.lookupFunction((Symbol) seq.car);
|
||||||
|
|
||||||
// call function
|
// throw an eror if it is not defined
|
||||||
|
if (functionEntry == null)
|
||||||
|
throw new LispException("Undefined function "
|
||||||
|
+ ((Symbol) seq.car).name);
|
||||||
|
|
||||||
|
// call function if it is
|
||||||
return functionEntry.call(table, seq.cdr);
|
return functionEntry.call(table, seq.cdr);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@ public class Seq implements SExp {
|
|||||||
return 1 + cdr.length();
|
return 1 + cdr.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String display(String offset) {
|
public String display(String offset) {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append(offset);
|
sb.append(offset);
|
||||||
|
@ -222,6 +222,41 @@ public abstract class SpecialFormEntry implements FormEntry {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ----
|
||||||
|
// CONS
|
||||||
|
// ----
|
||||||
|
|
||||||
|
SpecialFormEntry CONS = new SpecialFormEntry(
|
||||||
|
environment,
|
||||||
|
new FormHelpTopic("CONS", "create a cons",
|
||||||
|
"(cons <object-1> <object-2>) => <cons>",
|
||||||
|
"Creates a fresh cons, the car of which is object-1 and the "
|
||||||
|
+ "cdr of which is object-2.",
|
||||||
|
"object-1", "an object",
|
||||||
|
"object-2", "an object",
|
||||||
|
"cons", "a cons"))
|
||||||
|
{
|
||||||
|
public SExp call(SymbolTable symbolTable, Seq arguments)
|
||||||
|
throws LispException {
|
||||||
|
|
||||||
|
SExp object1, object2;
|
||||||
|
Cons cons;
|
||||||
|
|
||||||
|
if (arguments.length() != 2)
|
||||||
|
throw new InvalidArgumentQuantityException(2,
|
||||||
|
arguments.length());
|
||||||
|
|
||||||
|
// get the two objects
|
||||||
|
object1 = arguments.car.eval(symbolTable);
|
||||||
|
object2 = arguments.cdr.car.eval(symbolTable);
|
||||||
|
|
||||||
|
if (object2 instanceof List) cons = new Cons(object1, (List) object2);
|
||||||
|
else cons = new Cons(object1, object2);
|
||||||
|
|
||||||
|
return new List(cons);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// -----
|
// -----
|
||||||
// DEFUN
|
// DEFUN
|
||||||
// -----
|
// -----
|
||||||
@ -326,17 +361,18 @@ public abstract class SpecialFormEntry implements FormEntry {
|
|||||||
|
|
||||||
// second argument: initial value
|
// second argument: initial value
|
||||||
arguments = arguments.cdr;
|
arguments = arguments.cdr;
|
||||||
if (arguments != null)
|
if (arguments != null) {
|
||||||
initValue = arguments.car.eval(symbolTable);
|
initValue = arguments.car.eval(symbolTable);
|
||||||
|
|
||||||
// thrid argument: documentation
|
// third argument: documentation
|
||||||
arguments = arguments.cdr;
|
arguments = arguments.cdr;
|
||||||
if (arguments != null) {
|
if (arguments != null) {
|
||||||
if (!(arguments.car instanceof Str))
|
if (!(arguments.car instanceof Str))
|
||||||
throw new TypeException(arguments.car, Str.class);
|
throw new TypeException(arguments.car, Str.class);
|
||||||
|
|
||||||
helpinfo = new HelpTopic(name.name, "variable",
|
helpinfo = new HelpTopic(name.toString(), "variable",
|
||||||
((Str) arguments.car).value);
|
((Str) arguments.car).value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
symbolTable.bind(name,
|
symbolTable.bind(name,
|
||||||
@ -421,6 +457,69 @@ public abstract class SpecialFormEntry implements FormEntry {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ----
|
||||||
|
// GETF
|
||||||
|
// ----
|
||||||
|
|
||||||
|
SpecialFormEntry GETF = new SpecialFormEntry(
|
||||||
|
environment,
|
||||||
|
new FormHelpTopic("GETF", "",
|
||||||
|
"(getf <plist> <indicator> [<default>]) => <value>",
|
||||||
|
"getf finds a property on the plist whose property indicator "
|
||||||
|
+ "is identical to indicator, and returns its "
|
||||||
|
+ "corresponding property value. If there are multiple "
|
||||||
|
+ "properties with that property indicator, getf uses the "
|
||||||
|
+ "first such property. If there is no property with that "
|
||||||
|
+ "property indicator, default is returned.",
|
||||||
|
"plist", "a property list.",
|
||||||
|
"indicator", "an object",
|
||||||
|
"default", "an object. The default is NIL",
|
||||||
|
"value", "an object"))
|
||||||
|
{
|
||||||
|
public SExp call(SymbolTable symbolTable, Seq arguments)
|
||||||
|
throws LispException {
|
||||||
|
|
||||||
|
SExp plistEval;
|
||||||
|
Seq plistSeq;
|
||||||
|
SExp indicator;
|
||||||
|
SExp retVal = SExp.NIL;
|
||||||
|
|
||||||
|
// check number of arguments
|
||||||
|
if (arguments.length() < 2)
|
||||||
|
throw new InvalidArgumentQuantityException(
|
||||||
|
"form requires at least 2 arguments.");
|
||||||
|
|
||||||
|
// first argument: property list
|
||||||
|
plistEval = arguments.car.eval(symbolTable);
|
||||||
|
if (!(plistEval instanceof List))
|
||||||
|
throw new TypeException(arguments.car, List.class);
|
||||||
|
|
||||||
|
plistSeq = ((List) plistEval).seq;
|
||||||
|
|
||||||
|
// second argument: indicator
|
||||||
|
arguments = arguments.cdr;
|
||||||
|
indicator = arguments.car.eval(symbolTable);
|
||||||
|
|
||||||
|
// third argument: default value
|
||||||
|
arguments = arguments.cdr;
|
||||||
|
if (arguments != null)
|
||||||
|
retVal = arguments.car.eval(symbolTable);
|
||||||
|
|
||||||
|
while(plistSeq != null) {
|
||||||
|
|
||||||
|
// check this value for equality
|
||||||
|
if (plistSeq.car.equals(indicator))
|
||||||
|
if (plistSeq.cdr != null)
|
||||||
|
return plistSeq.cdr.car;
|
||||||
|
|
||||||
|
// advance to the next pair (or terminate)
|
||||||
|
plistSeq = (plistSeq.cdr == null ? null : plistSeq.cdr.cdr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// ----
|
// ----
|
||||||
// HELP
|
// HELP
|
||||||
// ----
|
// ----
|
||||||
@ -429,48 +528,45 @@ public abstract class SpecialFormEntry implements FormEntry {
|
|||||||
environment,
|
environment,
|
||||||
new FormHelpTopic("HELP",
|
new FormHelpTopic("HELP",
|
||||||
"Display online help information for a topic.",
|
"Display online help information for a topic.",
|
||||||
"(help <topic>)",
|
"(help [<topic>*])",
|
||||||
null,
|
null,
|
||||||
"topic",
|
"topic",
|
||||||
"either a string representing the topic to lookup or a symbol"))
|
"either a string representing the topic to lookup or a symbol"))
|
||||||
{
|
{
|
||||||
public SExp call(SymbolTable symbolTable, Seq arguments)
|
public SExp call(SymbolTable symbolTable, Seq arguments)
|
||||||
throws LispException {
|
throws LispException {
|
||||||
|
|
||||||
HelpTopic topic = null;
|
ArrayList<HelpTopic> topics = new ArrayList<HelpTopic>();
|
||||||
|
|
||||||
// no arguments: print help for HELP
|
// no arguments: print help for HELP
|
||||||
if (arguments == null)
|
if (arguments == null)
|
||||||
return this.call(symbolTable,
|
return this.call(symbolTable,
|
||||||
new Seq(new Symbol("HELP"), null));
|
new Seq(new Symbol("HELP"), null));
|
||||||
|
|
||||||
// too many arguments
|
while (arguments != null) {
|
||||||
if (arguments.length() > 1)
|
// try to find the topic or function help
|
||||||
throw new InvalidArgumentQuantityException(1,
|
if (arguments.car instanceof Str) {
|
||||||
arguments.length());
|
topics.add(HelpTopic.helpTopics.get(
|
||||||
|
((Str) arguments.car).value));
|
||||||
|
} else if (arguments.car instanceof Symbol) {
|
||||||
|
|
||||||
// try to find the topic or function help
|
// lookup help for funtion
|
||||||
if (arguments.car instanceof Str) {
|
|
||||||
topic = HelpTopic.helpTopics.get(
|
|
||||||
((Str) arguments.car).value);
|
|
||||||
} else if (arguments.car instanceof Symbol) {
|
|
||||||
try {
|
|
||||||
FormEntry fe = symbolTable.lookupFunction(
|
FormEntry fe = symbolTable.lookupFunction(
|
||||||
(Symbol) arguments.car);
|
(Symbol) arguments.car);
|
||||||
topic = fe.helpinfo();
|
if (fe != null) topics.add(fe.helpinfo());
|
||||||
} catch (LispException le) { topic = null; }
|
|
||||||
|
// lookup help for variable
|
||||||
|
VariableEntry ve = symbolTable.lookupVariable(
|
||||||
|
(Symbol) arguments.car);
|
||||||
|
if (ve != null) topics.add(ve.helpinfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
arguments = arguments.cdr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// no topic found
|
for (HelpTopic topic : topics)
|
||||||
if (topic == null) {
|
topic.print(environment.getOutputStream());
|
||||||
new PrintWriter(environment.getOutputStream(), true)
|
|
||||||
.println(
|
|
||||||
"No help information found for topic '"
|
|
||||||
+ arguments.car.toString() + "'.");
|
|
||||||
return SExp.NIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
topic.print(environment.getOutputStream());
|
|
||||||
return SExp.NIL;
|
return SExp.NIL;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -866,7 +962,13 @@ public abstract class SpecialFormEntry implements FormEntry {
|
|||||||
|
|
||||||
FormEntry fe = symbolTable.lookupFunction((Symbol) arguments.car);
|
FormEntry fe = symbolTable.lookupFunction((Symbol) arguments.car);
|
||||||
|
|
||||||
if (fe instanceof FunctionEntry) ((FunctionEntry) fe).enableTrace(true);
|
if (fe == null)
|
||||||
|
throw new UndefinedFunctionException(
|
||||||
|
((Symbol) arguments.car));
|
||||||
|
|
||||||
|
if (fe instanceof FunctionEntry)
|
||||||
|
((FunctionEntry) fe).enableTrace(true);
|
||||||
|
|
||||||
// TODO: else throw error
|
// TODO: else throw error
|
||||||
|
|
||||||
return SExp.NIL;
|
return SExp.NIL;
|
||||||
@ -877,9 +979,12 @@ public abstract class SpecialFormEntry implements FormEntry {
|
|||||||
environment.globalSymbolTable.bind(new Symbol("/"), DIV);
|
environment.globalSymbolTable.bind(new Symbol("/"), DIV);
|
||||||
environment.globalSymbolTable.bind(new Symbol("*"), MUL);
|
environment.globalSymbolTable.bind(new Symbol("*"), MUL);
|
||||||
environment.globalSymbolTable.bind(new Symbol("+"), SUM);
|
environment.globalSymbolTable.bind(new Symbol("+"), SUM);
|
||||||
|
environment.globalSymbolTable.bind(new Symbol("CONS"), CONS);
|
||||||
environment.globalSymbolTable.bind(new Symbol("DEFUN"), DEFUN);
|
environment.globalSymbolTable.bind(new Symbol("DEFUN"), DEFUN);
|
||||||
|
environment.globalSymbolTable.bind(new Symbol("DEFPARAMETER"), DEFPARAMETER);
|
||||||
environment.globalSymbolTable.bind(new Symbol("DEFVAR"), DEFVAR);
|
environment.globalSymbolTable.bind(new Symbol("DEFVAR"), DEFVAR);
|
||||||
environment.globalSymbolTable.bind(new Symbol("ENABLE-DEBUG-AST"), ENABLEDEBUGAST);
|
environment.globalSymbolTable.bind(new Symbol("ENABLE-DEBUG-AST"), ENABLEDEBUGAST);
|
||||||
|
environment.globalSymbolTable.bind(new Symbol("GETF"), GETF);
|
||||||
environment.globalSymbolTable.bind(new Symbol("HELP"), HELP);
|
environment.globalSymbolTable.bind(new Symbol("HELP"), HELP);
|
||||||
environment.globalSymbolTable.bind(new Symbol("IF"), IF);
|
environment.globalSymbolTable.bind(new Symbol("IF"), IF);
|
||||||
environment.globalSymbolTable.bind(new Symbol("LET"), LET);
|
environment.globalSymbolTable.bind(new Symbol("LET"), LET);
|
||||||
|
@ -10,7 +10,12 @@ public class Symbol implements SExp {
|
|||||||
|
|
||||||
/** {@inheritdoc}*/
|
/** {@inheritdoc}*/
|
||||||
public SExp eval(SymbolTable table) throws LispException {
|
public SExp eval(SymbolTable table) throws LispException {
|
||||||
|
// lookup value in the symbol table
|
||||||
VariableEntry ve = table.lookupVariable(this);
|
VariableEntry ve = table.lookupVariable(this);
|
||||||
|
|
||||||
|
// err if not defined
|
||||||
|
if (ve == null) throw new UndefinedVariableException(this);
|
||||||
|
|
||||||
return ve.value;
|
return ve.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,8 +81,7 @@ public class SymbolTable {
|
|||||||
if (fe != null) return fe;
|
if (fe != null) return fe;
|
||||||
|
|
||||||
// did not find function, and there is no outer scope
|
// did not find function, and there is no outer scope
|
||||||
if (enclosingTable == null)
|
if (enclosingTable == null) return null;
|
||||||
throw new LispException("Undefined function " + s.toString());
|
|
||||||
|
|
||||||
// search outer scope
|
// search outer scope
|
||||||
return enclosingTable.lookupFunction(s);
|
return enclosingTable.lookupFunction(s);
|
||||||
@ -95,8 +94,7 @@ public class SymbolTable {
|
|||||||
if (ve != null) return ve;
|
if (ve != null) return ve;
|
||||||
|
|
||||||
// did not find variable entry and there is no outer scope
|
// did not find variable entry and there is no outer scope
|
||||||
if (enclosingTable == null)
|
if (enclosingTable == null) return null;
|
||||||
throw new LispException("Undefined variable " + s.toString());
|
|
||||||
|
|
||||||
// search outer scope
|
// search outer scope
|
||||||
return enclosingTable.lookupVariable(s);
|
return enclosingTable.lookupVariable(s);
|
||||||
|
15
src/edu/utexas/cs345/jdblisp/UndefinedFunctionException.java
Normal file
15
src/edu/utexas/cs345/jdblisp/UndefinedFunctionException.java
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package edu.utexas.cs345.jdblisp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UndefinedFunctionException
|
||||||
|
* @author Jonathan Bernard (jdbernard@gmail.com)
|
||||||
|
*/
|
||||||
|
public class UndefinedFunctionException extends LispException {
|
||||||
|
|
||||||
|
Symbol symbol;
|
||||||
|
|
||||||
|
public UndefinedFunctionException(Symbol symbol) {
|
||||||
|
super("Undefined function: " + symbol.toString());
|
||||||
|
this.symbol = symbol;
|
||||||
|
}
|
||||||
|
}
|
15
src/edu/utexas/cs345/jdblisp/UndefinedVariableException.java
Normal file
15
src/edu/utexas/cs345/jdblisp/UndefinedVariableException.java
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package edu.utexas.cs345.jdblisp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UndefinedVariableException
|
||||||
|
* @author Jonathan Bernard
|
||||||
|
*/
|
||||||
|
public class UndefinedVariableException extends LispException {
|
||||||
|
|
||||||
|
public final Symbol symbol;
|
||||||
|
|
||||||
|
public UndefinedVariableException(Symbol symbol) {
|
||||||
|
super("Undefined variable: " + symbol.toString());
|
||||||
|
this.symbol = symbol;
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,10 @@
|
|||||||
(defun make-cd (title artist rating ripped)
|
(defun make-cd (title artist rating ripped)
|
||||||
(list title artist rating ripped))
|
(list :title title :artist artist :rating rating :ripped ripped))
|
||||||
|
|
||||||
(make-cd "Roses" "Kathy Mattea" 7 t)
|
|
||||||
|
|
||||||
(defvar *db* nil)
|
(defvar *db* nil)
|
||||||
|
|
||||||
|
(defun add-record (cd) (setq *db* (cons cd *db*)))
|
||||||
|
|
||||||
|
(add-record (make-cd "Roses" "Kathy Mattea" 7 t))
|
||||||
|
(add-record (make-cd "Fly" "Dixie Chicks" 8 t))
|
||||||
|
(add-record (make-cd "Home" "Dixie Chicks" 9 t))
|
||||||
|
8
todo.txt
8
todo.txt
@ -2,12 +2,20 @@ Outstanding
|
|||||||
-----------
|
-----------
|
||||||
|
|
||||||
- Implement FORMAT
|
- Implement FORMAT
|
||||||
|
- Implement GETF
|
||||||
- Implement lambdas
|
- Implement lambdas
|
||||||
- Implement LIST*
|
- Implement LIST*
|
||||||
- Implement macros
|
- Implement macros
|
||||||
- Implement packages
|
- Implement packages
|
||||||
- Implement READ and PRINT
|
- Implement READ and PRINT
|
||||||
|
- Implement SETF
|
||||||
- Redefine DEFUN as a macro
|
- Redefine DEFUN as a macro
|
||||||
|
- Help for property list
|
||||||
|
- Help for keyword
|
||||||
|
- Help for symbol
|
||||||
|
- Help for sexp
|
||||||
|
- Help for number
|
||||||
|
- Help for string
|
||||||
|
|
||||||
Partially Done
|
Partially Done
|
||||||
--------------
|
--------------
|
||||||
|
Loading…
x
Reference in New Issue
Block a user