release
import-0.36
parent
059c70d1d7
commit
79a60d07cc
113
.cvskeywords
113
.cvskeywords
|
@ -1,45 +1,68 @@
|
|||
./factor/random.factor:! $Id: random.factor,v 1.3 2004/01/09 01:51:30 slava Exp $
|
||||
./factor/FactorExternalizable.java: * $Id: FactorExternalizable.java,v 1.3 2003/12/09 09:40:18 slava Exp $
|
||||
./factor/FactorJava.java: * $Id: FactorJava.java,v 1.12 2004/01/06 06:59:38 slava Exp $
|
||||
./factor/FactorDictionary.java: * $Id: FactorDictionary.java,v 1.12 2004/01/14 01:58:37 slava Exp $
|
||||
./factor/combinators.factor:! $Id: combinators.factor,v 1.17 2004/01/11 23:00:34 slava Exp $
|
||||
./factor/FactorDataStack.java: * $Id: FactorCallStack.java,v 1.1 2003/12/20 02:13:09 slava Exp $
|
||||
./factor/continuations.factor:! $Id: continuations.factor,v 1.8 2003/12/20 05:31:01 slava Exp $
|
||||
./factor/network.factor:! $Id: io.factor,v 1.2 2003/12/20 05:31:01 slava Exp $
|
||||
./factor/FactorLib.java: * $Id: FactorLib.java,v 1.10 2004/01/03 20:58:09 slava Exp $
|
||||
./factor/FactorRuntimeException.java: * $Id: FactorRuntimeException.java,v 1.3 2003/12/09 09:40:18 slava Exp $
|
||||
./factor/FactorRatio.java: * $Id: FactorRatio.java,v 1.1 2003/12/16 08:03:08 slava Exp $
|
||||
./factor/FactorCallStack.java: * $Id: FactorCallStack.java,v 1.1 2003/12/20 02:13:09 slava Exp $
|
||||
./factor/FactorStackException.java: * $Id: FactorStackException.java,v 1.3 2003/12/09 09:40:18 slava Exp $
|
||||
./factor/FactorUndefinedWordException.java: * $Id: FactorUndefinedWordException.java,v 1.1 2003/12/09 09:52:26 slava Exp $
|
||||
./factor/lists.factor:! $Id: lists.factor,v 1.10 2004/01/06 06:59:38 slava Exp $
|
||||
./factor/FactorCallFrame.java: * $Id: FactorCallFrame.java,v 1.3 2003/12/26 00:36:30 slava Exp $
|
||||
./factor/examples/httpd.factor:! $Id: httpd.factor,v 1.1 2004/01/15 03:00:18 slava Exp $
|
||||
./factor/FactorPrimitive.java: * $Id: FactorPrimitive.java,v 1.5 2004/01/11 23:00:34 slava Exp $
|
||||
./factor/FactorList.java: * $Id: FactorList.java,v 1.9 2004/01/03 20:58:09 slava Exp $
|
||||
./factor/FactorNamespace.java: * $Id: FactorNamespace.java,v 1.10 2004/01/08 04:14:14 slava Exp $
|
||||
./factor/PublicCloneable.java: * $Id: PublicCloneable.java,v 1.3 2003/12/09 09:40:18 slava Exp $
|
||||
./factor/examples.factor:! $Id: examples.factor,v 1.4 2004/01/12 02:07:31 slava Exp $
|
||||
./factor/FactorCompoundDefinition.java:* $Id: FactorCompoundDefinition.java,v 1.2 2004/01/14 01:58:37 slava Exp $
|
||||
./factor/FactorObject.java: * $Id: FactorObject.java,v 1.5 2003/12/19 21:40:00 slava Exp $
|
||||
./factor/FactorParser.java: * $Id: FactorParser.java,v 1.13 2004/01/10 23:24:30 slava Exp $
|
||||
./factor/FactorMath.java: * $Id: FactorMath.java,v 1.7 2003/12/26 00:36:30 slava Exp $
|
||||
./factor/parser.factor:! $Id: parser.factor,v 1.2 2003/12/20 04:30:06 slava Exp $
|
||||
./factor/FactorMissingDefinition.java: * $Id: FactorWordDefinition.java,v 1.10 2003/12/18 00:01:39 slava Exp $
|
||||
./factor/stream.factor:! $Id: stream.factor,v 1.1 2004/01/03 20:58:09 slava Exp $
|
||||
./factor/FactorReflectionForm.java:* $Id: FactorReflectionForm.java,v 1.1 2004/01/14 01:58:37 slava Exp $
|
||||
./factor/strings.factor:! $Id: strings.factor,v 1.4 2004/01/06 06:59:38 slava Exp $
|
||||
./factor/FactorInterpreter.java: * $Id: FactorInterpreter.java,v 1.32 2004/01/12 02:07:31 slava Exp $
|
||||
./factor/FactorDomainException.java: * $Id: FactorDomainException.java,v 1.3 2003/12/09 09:40:18 slava Exp $
|
||||
./factor/FactorWord.java: * $Id: FactorWord.java,v 1.10 2004/01/08 04:14:14 slava Exp $
|
||||
./factor/math.factor:! $Id: math.factor,v 1.11 2004/01/11 23:00:34 slava Exp $
|
||||
./factor/FactorWordDefinition.java: * $Id: FactorWordDefinition.java,v 1.17 2004/01/14 01:58:37 slava Exp $
|
||||
./factor/interpreter.factor:! $Id: interpreter.factor,v 1.14 2004/01/11 23:00:34 slava Exp $
|
||||
./factor/miscellaneous.factor:! $Id: miscellaneous.factor,v 1.5 2003/12/21 05:29:46 slava Exp $
|
||||
./factor/FactorArrayStack.java: * $Id: FactorArrayStack.java,v 1.3 2003/12/20 05:31:01 slava Exp $
|
||||
./factor/boot.factor:! $Id: boot.factor,v 1.12 2004/01/12 02:07:31 slava Exp $
|
||||
./factor/FactorParseException.java: * $Id: FactorParseException.java,v 1.3 2003/12/09 09:40:18 slava Exp $
|
||||
./factor/namespaces.factor:! $Id: namespaces.factor,v 1.4 2004/01/05 05:03:36 slava Exp $
|
||||
./factor/FactorException.java: * $Id: FactorException.java,v 1.3 2003/12/09 09:40:18 slava Exp $
|
||||
./factor/FactorShuffleDefinition.java: * $Id: FactorShuffleDefinition.java,v 1.5 2004/01/14 01:58:37 slava Exp $
|
||||
./factor/dictionary.factor:! $Id: dictionary.factor,v 1.6 2004/01/12 02:07:31 slava Exp $
|
||||
./factor/compiler/StackEffect.java: * $Id: StackEffect.java,v 1.6 2004/02/15 22:24:19 slava Exp $
|
||||
./factor/compiler/LocalAllocator.java: * $Id: LocalAllocator.java,v 1.9 2004/02/17 20:36:09 slava Exp $
|
||||
./factor/compiler/FactorCompilerException.java: * $Id: FactorCompilerException.java,v 1.1 2004/01/27 19:55:40 slava Exp $
|
||||
./factor/compiler/CompiledDefinition.java:* $Id: CompiledDefinition.java,v 1.4 2004/02/15 22:24:19 slava Exp $
|
||||
./factor/random.factor:! $Id: random.factor,v 1.6 2004/02/18 00:48:47 slava Exp $
|
||||
./factor/FactorExternalizable.java: * $Id: FactorExternalizable.java,v 1.1 2004/01/25 19:55:39 slava Exp $
|
||||
./factor/FactorJava.java: * $Id: FactorJava.java,v 1.7 2004/02/15 05:44:54 slava Exp $
|
||||
./factor/FactorDictionary.java: * $Id: FactorDictionary.java,v 1.8 2004/02/15 22:24:19 slava Exp $
|
||||
./factor/combinators.factor:! $Id: combinators.factor,v 1.4 2004/02/13 23:19:43 slava Exp $
|
||||
./factor/FactorDataStack.java: * $Id: FactorDataStack.java,v 1.3 2004/02/15 22:24:19 slava Exp $
|
||||
./factor/continuations.factor:! $Id: continuations.factor,v 1.1 2004/01/25 19:55:39 slava Exp $
|
||||
./factor/network.factor:! $Id: network.factor,v 1.2 2004/02/10 05:43:37 slava Exp $
|
||||
./factor/FactorLib.java: * $Id: FactorLib.java,v 1.4 2004/02/15 22:24:19 slava Exp $
|
||||
./factor/FactorRuntimeException.java: * $Id: FactorRuntimeException.java,v 1.1 2004/01/25 19:55:39 slava Exp $
|
||||
./factor/FactorRatio.java: * $Id: FactorRatio.java,v 1.1 2004/01/25 19:55:39 slava Exp $
|
||||
./factor/FactorCallStack.java: * $Id: FactorCallStack.java,v 1.2 2004/02/15 22:24:19 slava Exp $
|
||||
./factor/FactorStackException.java: * $Id: FactorStackException.java,v 1.1 2004/01/25 19:55:39 slava Exp $
|
||||
./factor/FactorUndefinedWordException.java: * $Id: FactorUndefinedWordException.java,v 1.1 2004/01/25 19:55:39 slava Exp $
|
||||
./factor/lists.factor:! $Id: lists.factor,v 1.7 2004/02/15 22:24:19 slava Exp $
|
||||
./factor/FactorCallFrame.java: * $Id: FactorCallFrame.java,v 1.3 2004/02/05 04:47:05 slava Exp $
|
||||
./factor/examples/httpd.factor:! $Id: httpd.factor,v 1.3 2004/02/13 23:19:43 slava Exp $
|
||||
./factor/FactorNamespace.java: * $Id: FactorNamespace.java,v 1.4 2004/02/05 04:47:05 slava Exp $
|
||||
./factor/PublicCloneable.java: * $Id: PublicCloneable.java,v 1.1 2004/01/25 19:55:39 slava Exp $
|
||||
./factor/examples.factor:! $Id: examples.factor,v 1.1 2004/01/25 19:55:39 slava Exp $
|
||||
./factor/Cons.java: * $Id: Cons.java,v 1.4 2004/02/11 03:49:45 slava Exp $
|
||||
./factor/FactorCompoundDefinition.java:* $Id: FactorCompoundDefinition.java,v 1.9 2004/02/15 22:24:19 slava Exp $
|
||||
./factor/FactorObject.java: * $Id: FactorObject.java,v 1.1 2004/01/25 19:55:39 slava Exp $
|
||||
./factor/FactorParser.java: * $Id: FactorParser.java,v 1.3 2004/01/26 03:16:54 slava Exp $
|
||||
./factor/FactorMath.java: * $Id: FactorMath.java,v 1.3 2004/02/17 20:36:09 slava Exp $
|
||||
./factor/parser.factor:! $Id: parser.factor,v 1.2 2004/02/10 05:43:37 slava Exp $
|
||||
./factor/FactorMissingDefinition.java: * $Id: FactorMissingDefinition.java,v 1.7 2004/02/15 22:24:19 slava Exp $
|
||||
./factor/stream.factor:! $Id: stream.factor,v 1.3 2004/02/10 05:43:37 slava Exp $
|
||||
./factor/strings.factor:! $Id: strings.factor,v 1.9 2004/02/18 00:48:47 slava Exp $
|
||||
./factor/FactorInterpreter.java: * $Id: FactorInterpreter.java,v 1.6 2004/02/17 20:36:09 slava Exp $
|
||||
./factor/FactorDomainException.java: * $Id: FactorDomainException.java,v 1.1 2004/01/25 19:55:39 slava Exp $
|
||||
./factor/FactorWord.java: * $Id: FactorWord.java,v 1.7 2004/02/15 05:44:54 slava Exp $
|
||||
./factor/math.factor:! $Id: math.factor,v 1.5 2004/02/17 20:36:09 slava Exp $
|
||||
./factor/FactorWordDefinition.java: * $Id: FactorWordDefinition.java,v 1.14 2004/02/15 22:24:19 slava Exp $
|
||||
./factor/primitives/CallstackSet.java: * $Id: CallstackSet.java,v 1.2 2004/02/15 22:24:19 slava Exp $
|
||||
./factor/primitives/JInvokeStatic.java: * $Id: JInvokeStatic.java,v 1.2 2004/02/15 22:24:20 slava Exp $
|
||||
./factor/primitives/Unwind.java: * $Id: Unwind.java,v 1.2 2004/02/15 22:24:20 slava Exp $
|
||||
./factor/primitives/JVarGetStatic.java: * $Id: JVarGetStatic.java,v 1.2 2004/02/15 22:24:20 slava Exp $
|
||||
./factor/primitives/Unstack.java: * $Id: Unstack.java,v 1.2 2004/02/15 22:24:20 slava Exp $
|
||||
./factor/primitives/JInvoke.java: * $Id: JInvoke.java,v 1.2 2004/02/15 22:24:20 slava Exp $
|
||||
./factor/primitives/Get.java: * $Id: Get.java,v 1.2 2004/02/15 22:24:20 slava Exp $
|
||||
./factor/primitives/Define.java: * $Id: Define.java,v 1.2 2004/02/15 22:24:20 slava Exp $
|
||||
./factor/primitives/Clear.java: * $Id: Clear.java,v 1.2 2004/02/15 22:24:20 slava Exp $
|
||||
./factor/primitives/Bind.java: * $Id: Bind.java,v 1.3 2004/02/17 20:36:09 slava Exp $
|
||||
./factor/primitives/Choice.java: * $Id: Choice.java,v 1.3 2004/02/17 03:49:46 slava Exp $
|
||||
./factor/primitives/JNew.java: * $Id: JNew.java,v 1.2 2004/02/15 22:24:20 slava Exp $
|
||||
./factor/primitives/Call.java: * $Id: Call.java,v 1.2 2004/02/15 22:24:19 slava Exp $
|
||||
./factor/primitives/CallstackGet.java: * $Id: CallstackGet.java,v 1.2 2004/02/15 22:24:19 slava Exp $
|
||||
./factor/primitives/DatastackGet.java: * $Id: DatastackGet.java,v 1.2 2004/02/15 22:24:20 slava Exp $
|
||||
./factor/primitives/JVarSet.java: * $Id: JVarSet.java,v 1.2 2004/02/15 22:24:20 slava Exp $
|
||||
./factor/primitives/Set.java: * $Id: Set.java,v 1.2 2004/02/15 22:24:20 slava Exp $
|
||||
./factor/primitives/Restack.java: * $Id: Restack.java,v 1.2 2004/02/15 22:24:20 slava Exp $
|
||||
./factor/primitives/DatastackSet.java: * $Id: DatastackSet.java,v 1.2 2004/02/15 22:24:20 slava Exp $
|
||||
./factor/primitives/JVarSetStatic.java: * $Id: JVarSetStatic.java,v 1.2 2004/02/15 22:24:20 slava Exp $
|
||||
./factor/primitives/JVarGet.java: * $Id: JVarGet.java,v 1.2 2004/02/15 22:24:20 slava Exp $
|
||||
./factor/interpreter.factor:! $Id: interpreter.factor,v 1.6 2004/02/10 05:43:37 slava Exp $
|
||||
./factor/miscellaneous.factor:! $Id: miscellaneous.factor,v 1.5 2004/02/15 22:24:19 slava Exp $
|
||||
./factor/FactorArrayStack.java: * $Id: FactorArrayStack.java,v 1.2 2004/01/26 03:16:54 slava Exp $
|
||||
./factor/boot.factor:! $Id: boot.factor,v 1.5 2004/02/18 00:48:47 slava Exp $
|
||||
./factor/FactorParseException.java: * $Id: FactorParseException.java,v 1.1 2004/01/25 19:55:39 slava Exp $
|
||||
./factor/namespaces.factor:! $Id: namespaces.factor,v 1.4 2004/02/10 05:43:37 slava Exp $
|
||||
./factor/FactorException.java: * $Id: FactorException.java,v 1.1 2004/01/25 19:55:39 slava Exp $
|
||||
./factor/FactorShuffleDefinition.java: * $Id: FactorShuffleDefinition.java,v 1.12 2004/02/15 22:24:19 slava Exp $
|
||||
./factor/dictionary.factor:! $Id: dictionary.factor,v 1.8 2004/02/10 05:43:37 slava Exp $
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2003 Slava Pestov.
|
||||
* Copyright (C) 2003, 2004 Slava Pestov.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
|
@ -29,20 +29,18 @@
|
|||
|
||||
package factor;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
/**
|
||||
* Used to build up linked lists.
|
||||
*/
|
||||
public class FactorList implements PublicCloneable, FactorExternalizable
|
||||
public class Cons implements PublicCloneable, FactorExternalizable
|
||||
{
|
||||
public static int COUNT;
|
||||
|
||||
public Object car;
|
||||
public Object cdr;
|
||||
|
||||
//{{{ FactorList constructor
|
||||
public FactorList(Object car, Object cdr)
|
||||
//{{{ Cons constructor
|
||||
public Cons(Object car, Object cdr)
|
||||
{
|
||||
this.car = car;
|
||||
this.cdr = cdr;
|
||||
|
@ -63,9 +61,9 @@ public class FactorList implements PublicCloneable, FactorExternalizable
|
|||
} //}}}
|
||||
|
||||
//{{{ next() method
|
||||
public FactorList next()
|
||||
public Cons next()
|
||||
{
|
||||
return (FactorList)cdr;
|
||||
return (Cons)cdr;
|
||||
} //}}}
|
||||
|
||||
//{{{ get() method
|
||||
|
@ -75,12 +73,12 @@ public class FactorList implements PublicCloneable, FactorExternalizable
|
|||
} //}}}
|
||||
|
||||
//{{{ _get() method
|
||||
public FactorList _get(int index)
|
||||
public Cons _get(int index)
|
||||
{
|
||||
FactorList iter = this;
|
||||
Cons iter = this;
|
||||
while(index != 0)
|
||||
{
|
||||
iter = (FactorList)iter.cdr;
|
||||
iter = (Cons)iter.cdr;
|
||||
index--;
|
||||
}
|
||||
return iter;
|
||||
|
@ -89,7 +87,7 @@ public class FactorList implements PublicCloneable, FactorExternalizable
|
|||
//{{{ contains() method
|
||||
public boolean contains(Object obj)
|
||||
{
|
||||
FactorList iter = this;
|
||||
Cons iter = this;
|
||||
while(iter != null)
|
||||
{
|
||||
if(FactorLib.objectsEqual(obj,iter.car))
|
||||
|
@ -99,100 +97,33 @@ public class FactorList implements PublicCloneable, FactorExternalizable
|
|||
return false;
|
||||
} //}}}
|
||||
|
||||
//{{{ set() method
|
||||
/**
|
||||
* Returns a new list where the item at the given index is changed.
|
||||
*/
|
||||
public FactorList set(int index, Object car, Object cdr)
|
||||
//{{{ contains() method
|
||||
public static boolean contains(Cons list, Object obj)
|
||||
{
|
||||
if(index == 0)
|
||||
return new FactorList(car,cdr);
|
||||
if(list == null)
|
||||
return false;
|
||||
else
|
||||
{
|
||||
return new FactorList(this.car,
|
||||
this.next().set(index - 1,car,cdr));
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ set() method
|
||||
/**
|
||||
* Returns a new list containing the first n elements of this list.
|
||||
*/
|
||||
public FactorList head(int n)
|
||||
{
|
||||
if(n == 0)
|
||||
return null;
|
||||
else if(cdr == null && n == 1)
|
||||
return this;
|
||||
else
|
||||
{
|
||||
FactorList head = next().head(n - 1);
|
||||
if(head == cdr)
|
||||
return this;
|
||||
else
|
||||
return new FactorList(car,head);
|
||||
}
|
||||
return list.contains(obj);
|
||||
} //}}}
|
||||
|
||||
//{{{ length() method
|
||||
public int length()
|
||||
{
|
||||
int size = 0;
|
||||
FactorList iter = this;
|
||||
Cons iter = this;
|
||||
while(iter != null)
|
||||
{
|
||||
iter = (FactorList)iter.cdr;
|
||||
iter = (Cons)iter.cdr;
|
||||
size++;
|
||||
}
|
||||
return size;
|
||||
} //}}}
|
||||
|
||||
//{{{ append() method
|
||||
public FactorList append(FactorList list)
|
||||
{
|
||||
if(list == null)
|
||||
return this;
|
||||
|
||||
FactorList returnValue = null;
|
||||
FactorList end = null;
|
||||
FactorList iter = this;
|
||||
for(;;)
|
||||
{
|
||||
FactorList cons = new FactorList(iter.car,null);
|
||||
if(end != null)
|
||||
end.cdr = cons;
|
||||
end = cons;
|
||||
if(returnValue == null)
|
||||
returnValue = cons;
|
||||
if(iter.cdr == null)
|
||||
{
|
||||
end.cdr = list;
|
||||
break;
|
||||
}
|
||||
else
|
||||
iter = iter.next();
|
||||
}
|
||||
return returnValue;
|
||||
} //}}}
|
||||
|
||||
//{{{ reverse() method
|
||||
public FactorList reverse()
|
||||
{
|
||||
FactorList returnValue = null;
|
||||
FactorList iter = this;
|
||||
while(iter != null)
|
||||
{
|
||||
returnValue = new FactorList(iter.car,returnValue);
|
||||
iter = iter.next();
|
||||
}
|
||||
return returnValue;
|
||||
} //}}}
|
||||
|
||||
//{{{ isProperList() method
|
||||
public boolean isProperList()
|
||||
{
|
||||
return cdr == null || (cdr instanceof FactorList
|
||||
&& ((FactorList)cdr).isProperList());
|
||||
return cdr == null || (cdr instanceof Cons
|
||||
&& ((Cons)cdr).isProperList());
|
||||
} //}}}
|
||||
|
||||
//{{{ elementsToString() method
|
||||
|
@ -203,17 +134,17 @@ public class FactorList implements PublicCloneable, FactorExternalizable
|
|||
public String elementsToString()
|
||||
{
|
||||
StringBuffer buf = new StringBuffer();
|
||||
FactorList iter = this;
|
||||
Cons iter = this;
|
||||
while(iter != null)
|
||||
{
|
||||
if(iter.car == this)
|
||||
buf.append("<circular reference>");
|
||||
else
|
||||
buf.append(FactorJava.factorTypeToString(iter.car));
|
||||
if(iter.cdr instanceof FactorList)
|
||||
if(iter.cdr instanceof Cons)
|
||||
{
|
||||
buf.append(' ');
|
||||
iter = (FactorList)iter.cdr;
|
||||
iter = (Cons)iter.cdr;
|
||||
continue;
|
||||
}
|
||||
else if(iter.cdr == null)
|
||||
|
@ -238,19 +169,6 @@ public class FactorList implements PublicCloneable, FactorExternalizable
|
|||
return "[ " + elementsToString() + " ]";
|
||||
} //}}}
|
||||
|
||||
//{{{ toJavaList() method
|
||||
public List toJavaList()
|
||||
{
|
||||
LinkedList returnValue = new LinkedList();
|
||||
FactorList iter = this;
|
||||
while(iter != null)
|
||||
{
|
||||
returnValue.add(iter.car);
|
||||
iter = (FactorList)iter.cdr;
|
||||
}
|
||||
return returnValue;
|
||||
} //}}}
|
||||
|
||||
//{{{ toArray() method
|
||||
/**
|
||||
* Note that unlike Java list toArray(), the given array must already
|
||||
|
@ -259,7 +177,7 @@ public class FactorList implements PublicCloneable, FactorExternalizable
|
|||
public Object[] toArray(Object[] returnValue)
|
||||
{
|
||||
int i = 0;
|
||||
FactorList iter = this;
|
||||
Cons iter = this;
|
||||
while(iter != null)
|
||||
{
|
||||
returnValue[i++] = iter.car;
|
||||
|
@ -269,17 +187,17 @@ public class FactorList implements PublicCloneable, FactorExternalizable
|
|||
} //}}}
|
||||
|
||||
//{{{ fromArray() method
|
||||
public static FactorList fromArray(Object[] array)
|
||||
public static Cons fromArray(Object[] array)
|
||||
{
|
||||
if(array == null || array.length == 0)
|
||||
return null;
|
||||
else
|
||||
{
|
||||
FactorList first = new FactorList(array[0],null);
|
||||
FactorList last = first;
|
||||
Cons first = new Cons(array[0],null);
|
||||
Cons last = first;
|
||||
for(int i = 1; i < array.length; i++)
|
||||
{
|
||||
FactorList cons = new FactorList(array[i],null);
|
||||
Cons cons = new Cons(array[i],null);
|
||||
last.cdr = cons;
|
||||
last = cons;
|
||||
}
|
||||
|
@ -290,9 +208,9 @@ public class FactorList implements PublicCloneable, FactorExternalizable
|
|||
//{{{ equals() method
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
if(o instanceof FactorList)
|
||||
if(o instanceof Cons)
|
||||
{
|
||||
FactorList l = (FactorList)o;
|
||||
Cons l = (Cons)o;
|
||||
return FactorLib.objectsEqual(car,l.car)
|
||||
&& FactorLib.objectsEqual(cdr,l.cdr);
|
||||
}
|
||||
|
@ -312,10 +230,10 @@ public class FactorList implements PublicCloneable, FactorExternalizable
|
|||
//{{{ clone() method
|
||||
public Object clone()
|
||||
{
|
||||
if(cdr instanceof FactorList)
|
||||
return new FactorList(car,((FactorList)cdr).clone());
|
||||
if(cdr instanceof Cons)
|
||||
return new Cons(car,((Cons)cdr).clone());
|
||||
else
|
||||
return new FactorList(car,cdr);
|
||||
return new Cons(car,cdr);
|
||||
} //}}}
|
||||
|
||||
//{{{ deepClone() method
|
||||
|
@ -326,13 +244,13 @@ public class FactorList implements PublicCloneable, FactorExternalizable
|
|||
ccar = ((PublicCloneable)car).clone();
|
||||
else
|
||||
ccar = car;
|
||||
if(cdr instanceof FactorList)
|
||||
if(cdr instanceof Cons)
|
||||
{
|
||||
return new FactorList(ccar,next().deepClone());
|
||||
return new Cons(ccar,next().deepClone());
|
||||
}
|
||||
else if(cdr == null)
|
||||
{
|
||||
return new FactorList(ccar,null);
|
||||
return new Cons(ccar,null);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -341,7 +259,7 @@ public class FactorList implements PublicCloneable, FactorExternalizable
|
|||
ccdr = ((PublicCloneable)cdr).clone();
|
||||
else
|
||||
ccdr = cdr;
|
||||
return new FactorList(ccar,ccdr);
|
||||
return new Cons(ccar,ccdr);
|
||||
}
|
||||
} //}}}
|
||||
}
|
|
@ -44,7 +44,7 @@ public abstract class FactorArrayStack implements FactorExternalizable
|
|||
} //}}}
|
||||
|
||||
//{{{ FactorArrayStack constructor
|
||||
public FactorArrayStack(FactorList list)
|
||||
public FactorArrayStack(Cons list)
|
||||
{
|
||||
if(list != null)
|
||||
{
|
||||
|
@ -126,12 +126,12 @@ public abstract class FactorArrayStack implements FactorExternalizable
|
|||
} //}}}
|
||||
|
||||
//{{{ toList() method
|
||||
public FactorList toList()
|
||||
public Cons toList()
|
||||
{
|
||||
FactorList first = null, last = null;
|
||||
Cons first = null, last = null;
|
||||
for(int i = 0; i < top; i++)
|
||||
{
|
||||
FactorList cons = new FactorList(stack[i],null);
|
||||
Cons cons = new Cons(stack[i],null);
|
||||
if(first == null)
|
||||
first = cons;
|
||||
else
|
||||
|
|
|
@ -44,13 +44,18 @@ public class FactorCallFrame implements PublicCloneable, FactorExternalizable
|
|||
/**
|
||||
* Next word to be evaluated.
|
||||
*/
|
||||
public FactorList ip;
|
||||
public Cons ip;
|
||||
|
||||
/**
|
||||
* Collapsed tail calls? See call().
|
||||
*/
|
||||
public boolean collapsed;
|
||||
|
||||
/**
|
||||
* Compiled code?
|
||||
*/
|
||||
public boolean compiled;
|
||||
|
||||
//{{{ FactorCallFrame constructor
|
||||
public FactorCallFrame()
|
||||
{
|
||||
|
@ -59,7 +64,7 @@ public class FactorCallFrame implements PublicCloneable, FactorExternalizable
|
|||
//{{{ FactorCallFrame constructor
|
||||
public FactorCallFrame(FactorWord word,
|
||||
FactorNamespace namespace,
|
||||
FactorList ip)
|
||||
Cons ip)
|
||||
{
|
||||
this.word = word;
|
||||
this.namespace = namespace;
|
||||
|
@ -90,12 +95,17 @@ public class FactorCallFrame implements PublicCloneable, FactorExternalizable
|
|||
|
||||
buf.append("at ").append(word);
|
||||
|
||||
if(compiled)
|
||||
buf.append(" ( compiled )");
|
||||
else if(ip != null)
|
||||
{
|
||||
buf.append(" ( ip: ").append(ip.elementsToString())
|
||||
.append(" )");
|
||||
}
|
||||
|
||||
buf.append('\n').append(indent);
|
||||
|
||||
buf.append(" namespace: ").append(namespace)
|
||||
.append('\n').append(indent);
|
||||
|
||||
buf.append(" ip: ").append(ip);
|
||||
buf.append(namespace);
|
||||
|
||||
return buf.toString();
|
||||
} //}}}
|
||||
|
|
|
@ -60,6 +60,12 @@ public class FactorCallStack extends FactorArrayStack implements PublicCloneable
|
|||
//{{{ clone() method
|
||||
public Object clone()
|
||||
{
|
||||
return new FactorCallStack(FactorLib.deepCloneArray(stack),top);
|
||||
if(stack == null)
|
||||
return new FactorCallStack();
|
||||
else
|
||||
{
|
||||
return new FactorCallStack(
|
||||
FactorLib.deepCloneArray(stack),top);
|
||||
}
|
||||
} //}}}
|
||||
}
|
||||
|
|
|
@ -29,289 +29,356 @@
|
|||
|
||||
package factor;
|
||||
|
||||
import factor.compiler.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.io.FileOutputStream;
|
||||
import java.util.*;
|
||||
import org.objectweb.asm.*;
|
||||
import org.objectweb.asm.util.*;
|
||||
|
||||
/**
|
||||
* : name ... ;
|
||||
*/
|
||||
public class FactorCompoundDefinition extends FactorWordDefinition
|
||||
{
|
||||
public FactorList definition;
|
||||
private static int compileCount;
|
||||
|
||||
public FactorCompoundDefinition(FactorList definition)
|
||||
public Cons definition;
|
||||
|
||||
//{{{ FactorCompiledDefinition constructor
|
||||
public FactorCompoundDefinition(FactorWord word, Cons definition)
|
||||
{
|
||||
super(word);
|
||||
this.definition = definition;
|
||||
}
|
||||
} //}}}
|
||||
|
||||
public void eval(FactorWord word, FactorInterpreter interp)
|
||||
//{{{ eval() method
|
||||
public void eval(FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
interp.call(word,definition);
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ canCompile() method
|
||||
boolean canCompile()
|
||||
//{{{ getStackEffect() method
|
||||
public StackEffect getStackEffect(Set recursiveCheck,
|
||||
LocalAllocator state) throws Exception
|
||||
{
|
||||
return true;
|
||||
if(recursiveCheck.contains(this))
|
||||
return null;
|
||||
|
||||
try
|
||||
{
|
||||
recursiveCheck.add(this);
|
||||
|
||||
return StackEffect.getStackEffect(definition,
|
||||
recursiveCheck,state);
|
||||
}
|
||||
finally
|
||||
{
|
||||
recursiveCheck.remove(this);
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ getSanitizedName() method
|
||||
private String getSanitizedName(String name)
|
||||
{
|
||||
StringBuffer sanitizedName = new StringBuffer();
|
||||
for(int i = 0; i < name.length(); i++)
|
||||
{
|
||||
char ch = name.charAt(i);
|
||||
if(!Character.isJavaIdentifierStart(ch))
|
||||
sanitizedName.append("_");
|
||||
else
|
||||
sanitizedName.append(ch);
|
||||
}
|
||||
return "factor/compiler/gen/" + sanitizedName
|
||||
+ "_" + (compileCount++);
|
||||
} //}}}
|
||||
|
||||
//{{{ compile() method
|
||||
/**
|
||||
* Compile the given word, returning a new word definition.
|
||||
*/
|
||||
FactorWordDefinition compile(FactorInterpreter interp,
|
||||
Set recursiveCheck) throws Exception
|
||||
{
|
||||
StackEffect effect = getStackEffect(
|
||||
recursiveCheck,new LocalAllocator());
|
||||
if(effect == null)
|
||||
throw new FactorCompilerException("Cannot deduce stack effect of " + word);
|
||||
if(effect.outD > 1)
|
||||
throw new FactorCompilerException("Cannot compile word that returns more than 1 value");
|
||||
|
||||
/* StringBuffer buf = new StringBuffer();
|
||||
for(int i = 0; i < recursiveCheck.size(); i++)
|
||||
{
|
||||
buf.append(' ');
|
||||
}
|
||||
buf.append("Compiling ").append(word);
|
||||
System.err.println(buf); */
|
||||
|
||||
String className = getSanitizedName(word.name);
|
||||
|
||||
ClassWriter cw = new ClassWriter(false);
|
||||
cw.visit(ACC_PUBLIC, className,
|
||||
"factor/compiler/CompiledDefinition", null, null);
|
||||
|
||||
compileConstructor(cw,className);
|
||||
|
||||
CompileResult result = compileEval(interp,cw,
|
||||
className,effect,recursiveCheck);
|
||||
|
||||
compileToString(cw,effect);
|
||||
|
||||
// Generate fields for storing literals and word references
|
||||
result.allocator.generateFields(cw);
|
||||
|
||||
// gets the bytecode of the class, and loads it dynamically
|
||||
byte[] code = cw.toByteArray();
|
||||
|
||||
if(interp.compileDump)
|
||||
{
|
||||
FileOutputStream fos = new FileOutputStream(className + ".class");
|
||||
fos.write(code);
|
||||
fos.close();
|
||||
}
|
||||
|
||||
Class compiledWordClass = loader._defineClass(
|
||||
className.replace('/','.'),
|
||||
code, 0, code.length);
|
||||
|
||||
result.allocator.setFields(compiledWordClass);
|
||||
|
||||
Constructor constructor = compiledWordClass.getConstructor(
|
||||
new Class[] { FactorWord.class, StackEffect.class });
|
||||
|
||||
FactorWordDefinition compiledWord = (FactorWordDefinition)
|
||||
constructor.newInstance(new Object[] { word, effect });
|
||||
|
||||
// store disassembly for the 'asm' word.
|
||||
compiledWord.getNamespace(interp).setVariable("asm",
|
||||
result.asm);
|
||||
|
||||
return compiledWord;
|
||||
} //}}}
|
||||
|
||||
//{{{ compileConstructor() method
|
||||
private void compileConstructor(ClassVisitor cw, String className)
|
||||
{
|
||||
// creates a MethodWriter for the constructor
|
||||
CodeVisitor mw = cw.visitMethod(ACC_PUBLIC,
|
||||
"<init>",
|
||||
"(Lfactor/FactorWord;Lfactor/compiler/StackEffect;)V",
|
||||
null, null);
|
||||
// pushes the 'this' variable
|
||||
mw.visitVarInsn(ALOAD, 0);
|
||||
// pushes the word parameter
|
||||
mw.visitVarInsn(ALOAD, 1);
|
||||
// pushes the stack effect parameter
|
||||
mw.visitVarInsn(ALOAD, 2);
|
||||
// invokes the super class constructor
|
||||
mw.visitMethodInsn(INVOKESPECIAL,
|
||||
"factor/compiler/CompiledDefinition", "<init>",
|
||||
"(Lfactor/FactorWord;Lfactor/compiler/StackEffect;)V");
|
||||
mw.visitInsn(RETURN);
|
||||
mw.visitMaxs(3, 3);
|
||||
} //}}}
|
||||
|
||||
//{{{ compileToString() method
|
||||
private void compileToString(ClassVisitor cw, StackEffect effect)
|
||||
{
|
||||
// creates a MethodWriter for the 'toString' method
|
||||
CodeVisitor mw = cw.visitMethod(ACC_PUBLIC,
|
||||
"toString", "()Ljava/lang/String;", null, null);
|
||||
mw.visitLdcInsn("( compiled: " + effect + " ) " + toString());
|
||||
mw.visitInsn(ARETURN);
|
||||
mw.visitMaxs(1, 1);
|
||||
} //}}}
|
||||
|
||||
//{{{ compileEval() method
|
||||
static class CompileResult
|
||||
{
|
||||
LocalAllocator allocator;
|
||||
String asm;
|
||||
|
||||
CompileResult(LocalAllocator allocator, String asm)
|
||||
{
|
||||
this.allocator = allocator;
|
||||
this.asm = asm;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the definition of the eval() method in the compiled word.
|
||||
* Local 0 -- this
|
||||
* Local 1 -- word
|
||||
* Local 2 -- interpreter
|
||||
* Local 1 -- interpreter
|
||||
*/
|
||||
boolean compile(FactorWord word, FactorInterpreter interp,
|
||||
ClassWriter cw, CodeVisitor mw)
|
||||
throws Exception
|
||||
protected CompileResult compileEval(FactorInterpreter interp,
|
||||
ClassWriter cw, String className, StackEffect effect,
|
||||
Set recursiveCheck) throws Exception
|
||||
{
|
||||
if(definition == null)
|
||||
{
|
||||
// creates a MethodWriter for the 'eval' method
|
||||
CodeVisitor _mw = cw.visitMethod(ACC_PUBLIC,
|
||||
"eval", "(Lfactor/FactorInterpreter;)V",
|
||||
null, null);
|
||||
|
||||
TraceCodeVisitor mw = new TraceCodeVisitor(_mw);
|
||||
|
||||
// eval() method calls core
|
||||
mw.visitVarInsn(ALOAD,1);
|
||||
|
||||
compileDataStackToJVMStack(effect,mw);
|
||||
|
||||
String signature = effect.getCorePrototype();
|
||||
|
||||
mw.visitMethodInsn(INVOKESTATIC,
|
||||
className,"core",signature);
|
||||
|
||||
compileJVMStackToDataStack(effect,mw);
|
||||
|
||||
mw.visitInsn(RETURN);
|
||||
mw.visitMaxs(Math.max(4,2 + effect.inD),4);
|
||||
|
||||
String evalAsm = getDisassembly(mw);
|
||||
|
||||
// generate core
|
||||
_mw = cw.visitMethod(ACC_PUBLIC | ACC_STATIC,
|
||||
"core",signature,null,null);
|
||||
|
||||
mw = new TraceCodeVisitor(_mw);
|
||||
|
||||
LocalAllocator allocator = new LocalAllocator(interp,
|
||||
className,1,effect.inD);
|
||||
|
||||
int maxJVMStack = allocator.compile(definition,mw,
|
||||
recursiveCheck);
|
||||
|
||||
if(effect.outD == 0)
|
||||
mw.visitInsn(RETURN);
|
||||
// Max stack and locals
|
||||
mw.visitMaxs(1,1);
|
||||
return true;
|
||||
}
|
||||
|
||||
FactorList fdef = compilePass1(interp,definition);
|
||||
if(fdef.car instanceof FactorReflectionForm
|
||||
&& fdef.cdr == null)
|
||||
else
|
||||
{
|
||||
return ((FactorReflectionForm)fdef.car).compile(
|
||||
word,interp,cw,mw);
|
||||
allocator.pop(mw);
|
||||
mw.visitInsn(ARETURN);
|
||||
maxJVMStack = Math.max(maxJVMStack,1);
|
||||
}
|
||||
/* else
|
||||
System.err.println("WARNING: cannot compile reflection & more"); */
|
||||
|
||||
return false;
|
||||
mw.visitMaxs(maxJVMStack,allocator.maxLocals());
|
||||
|
||||
String coreAsm = getDisassembly(mw);
|
||||
|
||||
return new CompileResult(allocator,
|
||||
"eval(Lfactor/FactorInterpreter;)V:\n" + evalAsm
|
||||
+ "core" + signature + "\n" + coreAsm);
|
||||
} //}}}
|
||||
|
||||
//{{{ compilePass1() method
|
||||
//{{{ getDisassembly() method
|
||||
protected String getDisassembly(TraceCodeVisitor mw)
|
||||
{
|
||||
// Save the disassembly of the eval() method
|
||||
StringBuffer buf = new StringBuffer();
|
||||
Iterator bytecodes = mw.getText().iterator();
|
||||
while(bytecodes.hasNext())
|
||||
{
|
||||
buf.append(bytecodes.next());
|
||||
}
|
||||
return buf.toString();
|
||||
} //}}}
|
||||
|
||||
//{{{ compileDataStackToJVMStack() method
|
||||
private void compileDataStackToJVMStack(StackEffect effect,
|
||||
CodeVisitor mw)
|
||||
{
|
||||
if(effect.inD != 0)
|
||||
{
|
||||
mw.visitVarInsn(ALOAD,1);
|
||||
mw.visitFieldInsn(GETFIELD,
|
||||
"factor/FactorInterpreter", "datastack",
|
||||
"Lfactor/FactorDataStack;");
|
||||
|
||||
// ensure the stack has enough elements
|
||||
mw.visitInsn(DUP);
|
||||
mw.visitIntInsn(BIPUSH,effect.inD);
|
||||
mw.visitMethodInsn(INVOKEVIRTUAL,
|
||||
"factor/FactorArrayStack", "ensurePop",
|
||||
"(I)V");
|
||||
|
||||
// datastack.stack -> 2
|
||||
mw.visitInsn(DUP);
|
||||
mw.visitFieldInsn(GETFIELD,
|
||||
"factor/FactorArrayStack", "stack",
|
||||
"[Ljava/lang/Object;");
|
||||
mw.visitVarInsn(ASTORE,2);
|
||||
// datastack.top-args.length -> 3
|
||||
mw.visitInsn(DUP);
|
||||
mw.visitFieldInsn(GETFIELD,
|
||||
"factor/FactorArrayStack", "top",
|
||||
"I");
|
||||
mw.visitIntInsn(BIPUSH,effect.inD);
|
||||
mw.visitInsn(ISUB);
|
||||
|
||||
// datastack.top -= args.length
|
||||
mw.visitInsn(DUP_X1);
|
||||
mw.visitFieldInsn(PUTFIELD,
|
||||
"factor/FactorArrayStack", "top",
|
||||
"I");
|
||||
|
||||
mw.visitVarInsn(ISTORE,3);
|
||||
|
||||
for(int i = 0; i < effect.inD; i++)
|
||||
{
|
||||
mw.visitVarInsn(ALOAD,2);
|
||||
mw.visitVarInsn(ILOAD,3);
|
||||
mw.visitInsn(AALOAD);
|
||||
if(i != effect.inD - 1)
|
||||
mw.visitIincInsn(3,1);
|
||||
}
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ compileJVMStackToDataStack() method
|
||||
private void compileJVMStackToDataStack(StackEffect effect,
|
||||
CodeVisitor mw)
|
||||
{
|
||||
if(effect.outD == 1)
|
||||
{
|
||||
// ( datastack )
|
||||
mw.visitVarInsn(ALOAD,1);
|
||||
mw.visitFieldInsn(GETFIELD,
|
||||
"factor/FactorInterpreter", "datastack",
|
||||
"Lfactor/FactorDataStack;");
|
||||
|
||||
mw.visitInsn(SWAP);
|
||||
mw.visitMethodInsn(INVOKEVIRTUAL,
|
||||
"factor/FactorArrayStack", "push",
|
||||
"(Ljava/lang/Object;)V");
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ compileImmediate() method
|
||||
/**
|
||||
* Turn reflection calls into ReflectionForm objects.
|
||||
* Compile a call to this word. Returns maximum JVM stack use.
|
||||
*/
|
||||
private FactorList compilePass1(FactorInterpreter interp, FactorList def)
|
||||
public int compileImmediate(CodeVisitor mw, LocalAllocator allocator,
|
||||
Set recursiveCheck) throws Exception
|
||||
{
|
||||
if(!def.isProperList())
|
||||
return def;
|
||||
|
||||
FactorList rdef = def.reverse();
|
||||
|
||||
FactorDictionary dict = interp.dict;
|
||||
|
||||
// A list of words and Java reflection forms
|
||||
FactorList fdef = null;
|
||||
while(rdef != null)
|
||||
{
|
||||
Object car = rdef.car;
|
||||
if(car == dict.jvarGet
|
||||
|| car == dict.jvarSet
|
||||
|| car == dict.jvarGetStatic
|
||||
|| car == dict.jvarSetStatic
|
||||
|| car == dict.jnew)
|
||||
{
|
||||
FactorList form = rdef;
|
||||
rdef = form._get(3);
|
||||
fdef = new FactorList(new FactorReflectionForm(form),
|
||||
fdef);
|
||||
}
|
||||
else if(car == dict.jinvoke
|
||||
|| car == dict.jinvokeStatic)
|
||||
{
|
||||
FactorList form = rdef;
|
||||
rdef = form._get(4);
|
||||
fdef = new FactorList(new FactorReflectionForm(form),
|
||||
fdef);
|
||||
}
|
||||
else if(car instanceof FactorList)
|
||||
{
|
||||
fdef = new FactorList(compilePass1(
|
||||
interp,((FactorList)car)),fdef);
|
||||
}
|
||||
else
|
||||
fdef = new FactorList(car,fdef);
|
||||
|
||||
rdef = rdef.next();
|
||||
}
|
||||
|
||||
return fdef;
|
||||
} //}}}
|
||||
|
||||
//{{{ precompile() method
|
||||
void precompile(FactorWord newWord, FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
FactorDictionary dict = interp.dict;
|
||||
|
||||
if(definition != null)
|
||||
{
|
||||
FactorList before = definition;
|
||||
FactorList fed = definition.reverse();
|
||||
precompile(interp,newWord,fed);
|
||||
definition = fed.reverse();
|
||||
/* if(!def.equals(before))
|
||||
{
|
||||
System.out.println("BEFORE: " + before);
|
||||
System.out.println("AFTER: " + def);
|
||||
} */
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ precompile() method
|
||||
/**
|
||||
* Precompiling turns jconstructor, jfield and jmethod calls
|
||||
* with all-literal arguments into inline
|
||||
* Constructor/Field/Method literals. This improves performance.
|
||||
*/
|
||||
private void precompile(FactorInterpreter interp,
|
||||
FactorWord newWord, FactorList list)
|
||||
throws Exception
|
||||
{
|
||||
if(interp.compile)
|
||||
return;
|
||||
|
||||
FactorDictionary dict = interp.dict;
|
||||
|
||||
while(list != null)
|
||||
{
|
||||
Object o = list.car;
|
||||
if(o instanceof FactorWord)
|
||||
{
|
||||
FactorWord word = (FactorWord)o;
|
||||
if(word.def != FactorMissingDefinition.INSTANCE)
|
||||
{
|
||||
word.def.references++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*System.err.println(
|
||||
"WARNING: "
|
||||
+ newWord
|
||||
+ " references "
|
||||
+ o
|
||||
+ " before its defined");*/
|
||||
}
|
||||
|
||||
if(o == dict.jconstructor)
|
||||
{
|
||||
jconstructorPrecompile(
|
||||
interp,list);
|
||||
}
|
||||
else if(o == dict.jmethod)
|
||||
{
|
||||
jmethodPrecompile(
|
||||
interp,list);
|
||||
}
|
||||
else if(o == dict.jfield)
|
||||
{
|
||||
jfieldPrecompile(
|
||||
interp,list);
|
||||
}
|
||||
}
|
||||
else if(o instanceof FactorList)
|
||||
{
|
||||
if(((FactorList)o).isProperList())
|
||||
{
|
||||
FactorList l = (FactorList)o;
|
||||
FactorList _l = l.reverse();
|
||||
precompile(interp,newWord,_l);
|
||||
list.car = _l.reverse();
|
||||
}
|
||||
}
|
||||
list = list.next();
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ jconstructorPrecompile() method
|
||||
private void jconstructorPrecompile(
|
||||
FactorInterpreter interp, FactorList list)
|
||||
throws Exception
|
||||
{
|
||||
FactorList cdr = list.next();
|
||||
if(cdr == null)
|
||||
return;
|
||||
if(!(cdr.car instanceof String))
|
||||
return;
|
||||
String clazz = (String)cdr.car;
|
||||
|
||||
FactorList cddr = cdr.next();
|
||||
if(cddr == null)
|
||||
return;
|
||||
if(!(cddr.car instanceof FactorList))
|
||||
return;
|
||||
FactorList args = (FactorList)cddr.car;
|
||||
|
||||
Constructor c = FactorJava.jconstructor(clazz,args);
|
||||
|
||||
list.car = c;
|
||||
list.cdr = cddr.next();
|
||||
} //}}}
|
||||
|
||||
//{{{ jfieldPrecompile() method
|
||||
private void jfieldPrecompile(
|
||||
FactorInterpreter interp, FactorList list)
|
||||
throws Exception
|
||||
{
|
||||
FactorList cdr = list.next();
|
||||
if(cdr == null)
|
||||
return;
|
||||
if(!(cdr.car instanceof String))
|
||||
return;
|
||||
String field = (String)cdr.car;
|
||||
|
||||
FactorList cddr = cdr.next();
|
||||
if(cddr == null)
|
||||
return;
|
||||
if(!(cddr.car instanceof String))
|
||||
return;
|
||||
String clazz = (String)cddr.car;
|
||||
|
||||
Field f = FactorJava.jfield(field,clazz);
|
||||
|
||||
list.car = f;
|
||||
list.cdr = cddr.next();
|
||||
} //}}}
|
||||
|
||||
//{{{ jmethodPrecompile() method
|
||||
/**
|
||||
* Check if this jmethod has all-literal arguments, and if so,
|
||||
* inline the result.
|
||||
*/
|
||||
private void jmethodPrecompile(
|
||||
FactorInterpreter interp, FactorList list)
|
||||
throws Exception
|
||||
{
|
||||
FactorList cdr = list.next();
|
||||
if(cdr == null)
|
||||
return;
|
||||
if(!(cdr.car instanceof String))
|
||||
return;
|
||||
String method = (String)cdr.car;
|
||||
|
||||
FactorList cddr = cdr.next();
|
||||
if(cddr == null)
|
||||
return;
|
||||
if(!(cddr.car instanceof String))
|
||||
return;
|
||||
String clazz = (String)cddr.car;
|
||||
|
||||
FactorList cdddr = cddr.next();
|
||||
if(cdddr == null)
|
||||
return;
|
||||
if(!(cdddr.car instanceof FactorList))
|
||||
return;
|
||||
FactorList args = (FactorList)cdddr.car;
|
||||
|
||||
Method m = FactorJava.jmethod(method,clazz,args);
|
||||
|
||||
list.car = m;
|
||||
list.cdr = cdddr.next();
|
||||
return allocator.compile(definition,mw,recursiveCheck);
|
||||
} //}}}
|
||||
|
||||
//{{{ toString() method
|
||||
public String toString()
|
||||
{
|
||||
return definition.elementsToString();
|
||||
}
|
||||
} //}}}
|
||||
|
||||
private static SimpleClassLoader loader = new SimpleClassLoader();
|
||||
|
||||
//{{{ SimpleClassLoader class
|
||||
static class SimpleClassLoader extends ClassLoader
|
||||
{
|
||||
public Class _defineClass(String name,
|
||||
byte[] code, int off, int len)
|
||||
{
|
||||
return defineClass(name,code,off,len);
|
||||
}
|
||||
} //}}}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ public class FactorDataStack extends FactorArrayStack implements PublicCloneable
|
|||
} //}}}
|
||||
|
||||
//{{{ FactorDataStack constructor
|
||||
public FactorDataStack(FactorList list)
|
||||
public FactorDataStack(Cons list)
|
||||
{
|
||||
super(list);
|
||||
} //}}}
|
||||
|
@ -66,6 +66,12 @@ public class FactorDataStack extends FactorArrayStack implements PublicCloneable
|
|||
//{{{ clone() method
|
||||
public Object clone()
|
||||
{
|
||||
return new FactorDataStack(FactorLib.cloneArray(stack),top);
|
||||
if(stack == null)
|
||||
return new FactorDataStack();
|
||||
else
|
||||
{
|
||||
return new FactorDataStack(
|
||||
FactorLib.cloneArray(stack),top);
|
||||
}
|
||||
} //}}}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2003 Slava Pestov.
|
||||
* Copyright (C) 2003, 2004 Slava Pestov.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
|
@ -29,23 +29,36 @@
|
|||
|
||||
package factor;
|
||||
|
||||
import factor.primitives.*;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public class FactorDictionary
|
||||
{
|
||||
// these are defined here for use by the precompiler
|
||||
FactorWord jconstructor;
|
||||
public FactorWord last;
|
||||
|
||||
FactorWord datastackGet;
|
||||
FactorWord datastackSet;
|
||||
FactorWord clear;
|
||||
FactorWord callstackGet;
|
||||
FactorWord callstackSet;
|
||||
FactorWord restack;
|
||||
FactorWord unstack;
|
||||
FactorWord unwind;
|
||||
FactorWord jnew;
|
||||
FactorWord jfield;
|
||||
FactorWord jvarGet;
|
||||
FactorWord jvarSet;
|
||||
FactorWord jvarGetStatic;
|
||||
FactorWord jvarSetStatic;
|
||||
FactorWord jmethod;
|
||||
FactorWord jinvoke;
|
||||
FactorWord jinvokeStatic;
|
||||
FactorWord get;
|
||||
FactorWord set;
|
||||
FactorWord define;
|
||||
FactorWord call;
|
||||
FactorWord bind;
|
||||
FactorWord choice;
|
||||
|
||||
private Map intern;
|
||||
|
||||
|
@ -55,50 +68,65 @@ public class FactorDictionary
|
|||
intern = new TreeMap();
|
||||
|
||||
// data stack primitives
|
||||
intern("datastack$").def = new FactorPrimitive.P_datastackGet();
|
||||
intern("datastack@").def = new FactorPrimitive.P_datastackSet();
|
||||
intern("clear").def = new FactorPrimitive.P_clear();
|
||||
datastackGet = intern("datastack$");
|
||||
datastackGet.def = new DatastackGet(
|
||||
datastackGet);
|
||||
datastackSet = intern("datastack@");
|
||||
datastackSet.def = new DatastackSet(
|
||||
datastackSet);
|
||||
clear = intern("clear");
|
||||
clear.def = new Clear(clear);
|
||||
|
||||
// call stack primitives
|
||||
intern("callstack$").def = new FactorPrimitive.P_callstackGet();
|
||||
intern("callstack@").def = new FactorPrimitive.P_callstackSet();
|
||||
intern("restack").def = new FactorPrimitive.P_restack();
|
||||
intern("unstack").def = new FactorPrimitive.P_unstack();
|
||||
intern("unwind").def = new FactorPrimitive.P_unwind();
|
||||
callstackGet = intern("callstack$");
|
||||
callstackGet.def = new CallstackGet(
|
||||
callstackGet);
|
||||
callstackSet = intern("callstack@");
|
||||
callstackSet.def = new CallstackSet(
|
||||
callstackSet);
|
||||
restack = intern("restack");
|
||||
restack.def = new Restack(restack);
|
||||
unstack = intern("unstack");
|
||||
unstack.def = new Unstack(unstack);
|
||||
unwind = intern("unwind");
|
||||
unwind.def = new Unwind(unwind);
|
||||
|
||||
// reflection primitives
|
||||
jconstructor = intern("jconstructor");
|
||||
jconstructor.def = new FactorPrimitive.P_jconstructor();
|
||||
jfield = intern("jfield");
|
||||
jfield.def = new FactorPrimitive.P_jfield();
|
||||
jinvoke = intern("jinvoke");
|
||||
jinvoke.def = new FactorPrimitive.P_jinvoke();
|
||||
jinvokeStatic = intern("jinvokeStatic");
|
||||
jinvokeStatic.def = new FactorPrimitive.P_jinvokeStatic();
|
||||
jmethod = intern("jmethod");
|
||||
jmethod.def = new FactorPrimitive.P_jmethod();
|
||||
jinvoke.def = new JInvoke(jinvoke);
|
||||
jinvokeStatic = intern("jinvoke-static");
|
||||
jinvokeStatic.def = new JInvokeStatic(
|
||||
jinvokeStatic);
|
||||
jnew = intern("jnew");
|
||||
jnew.def = new FactorPrimitive.P_jnew();
|
||||
jnew.def = new JNew(jnew);
|
||||
jvarGet = intern("jvar$");
|
||||
jvarGet.def = new FactorPrimitive.P_jvarGet();
|
||||
jvarGetStatic = intern("jvarStatic$");
|
||||
jvarGetStatic.def = new FactorPrimitive.P_jvarGetStatic();
|
||||
jvarGet.def = new JVarGet(jvarGet);
|
||||
jvarGetStatic = intern("jvar-static$");
|
||||
jvarGetStatic.def = new JVarGetStatic(
|
||||
jvarGetStatic);
|
||||
jvarSet = intern("jvar@");
|
||||
jvarSet.def = new FactorPrimitive.P_jvarSet();
|
||||
jvarSetStatic = intern("jvarStatic@");
|
||||
jvarSetStatic.def = new FactorPrimitive.P_jvarSetStatic();
|
||||
jvarSet.def = new JVarSet(jvarSet);
|
||||
jvarSetStatic = intern("jvar-static@");
|
||||
jvarSetStatic.def = new JVarSetStatic(
|
||||
jvarSetStatic);
|
||||
|
||||
// namespaces
|
||||
intern("$").def = new FactorPrimitive.P_get();
|
||||
intern("@").def = new FactorPrimitive.P_set();
|
||||
intern("s@").def = new FactorPrimitive.P_swap_set();
|
||||
get = intern("$");
|
||||
get.def = new Get(get);
|
||||
set = intern("@");
|
||||
set.def = new Set(set);
|
||||
|
||||
// definition
|
||||
intern("define").def = new FactorPrimitive.P_define();
|
||||
define = intern("define");
|
||||
define.def = new Define(define);
|
||||
|
||||
// combinators
|
||||
intern("call").def = new FactorPrimitive.P_call();
|
||||
intern("bind").def = new FactorPrimitive.P_bind();
|
||||
call = intern("call");
|
||||
call.def = new Call(call);
|
||||
bind = intern("bind");
|
||||
bind.def = new Bind(bind);
|
||||
choice = intern("?");
|
||||
choice.def = new Choice(choice);
|
||||
} //}}}
|
||||
|
||||
//{{{ intern() method
|
||||
|
@ -114,17 +142,17 @@ public class FactorDictionary
|
|||
} //}}}
|
||||
|
||||
//{{{ toWordList() method
|
||||
public FactorList toWordList()
|
||||
public Cons toWordList()
|
||||
{
|
||||
FactorList first = null;
|
||||
FactorList last = null;
|
||||
Cons first = null;
|
||||
Cons last = null;
|
||||
Iterator iter = intern.values().iterator();
|
||||
while(iter.hasNext())
|
||||
{
|
||||
FactorWord word = (FactorWord)iter.next();
|
||||
if(word.def != FactorMissingDefinition.INSTANCE)
|
||||
if(!(word.def instanceof FactorMissingDefinition))
|
||||
{
|
||||
FactorList cons = new FactorList(word,null);
|
||||
Cons cons = new Cons(word,null);
|
||||
if(first == null)
|
||||
first = cons;
|
||||
else
|
||||
|
|
|
@ -33,15 +33,15 @@ import java.io.*;
|
|||
|
||||
public class FactorInterpreter
|
||||
{
|
||||
/**
|
||||
* boot.factor checks this, if its true, an interpreter is run on
|
||||
* standard input.
|
||||
*/
|
||||
public boolean interactive = false;
|
||||
// command line arguments are stored here.
|
||||
public Cons args;
|
||||
|
||||
// boot.factor sets these.
|
||||
public boolean interactive = true;
|
||||
public boolean trace = false;
|
||||
public boolean errorFlag = false;
|
||||
public boolean compile = true;
|
||||
public boolean compileDump = false;
|
||||
|
||||
public FactorCallFrame callframe;
|
||||
public FactorCallStack callstack = new FactorCallStack();
|
||||
|
@ -57,21 +57,9 @@ public class FactorInterpreter
|
|||
{
|
||||
FactorInterpreter interp = new FactorInterpreter();
|
||||
|
||||
boolean virgin = false;
|
||||
interp.init(args,null);
|
||||
|
||||
for(int i = 0; i < args.length; i++)
|
||||
{
|
||||
if(args[i].equals("-trace"))
|
||||
interp.trace = true;
|
||||
else if(args[i].equals("-virgin"))
|
||||
virgin = true;
|
||||
else if(args[i].equals("-interp"))
|
||||
interp.compile = false;
|
||||
}
|
||||
|
||||
interp.interactive = true;
|
||||
interp.init(null,!virgin);
|
||||
if(virgin)
|
||||
/* if(virgin)
|
||||
{
|
||||
System.out.println("Mini-interpreter");
|
||||
BufferedReader in = new BufferedReader(
|
||||
|
@ -89,7 +77,7 @@ public class FactorInterpreter
|
|||
FactorParser parser = new FactorParser(
|
||||
"<mini>",new StringReader(line),
|
||||
interp.dict);
|
||||
FactorList parsed = parser.parse();
|
||||
Cons parsed = parser.parse();
|
||||
interp.call(parsed);
|
||||
interp.run();
|
||||
System.out.println(interp.datastack);
|
||||
|
@ -98,21 +86,22 @@ public class FactorInterpreter
|
|||
else
|
||||
{
|
||||
interp.run();
|
||||
}
|
||||
} */
|
||||
|
||||
System.exit(0);
|
||||
} //}}}
|
||||
|
||||
//{{{ init() method
|
||||
public void init(Object root, boolean bootstrap) throws Exception
|
||||
public void init(String[] args, Object root) throws Exception
|
||||
{
|
||||
this.args = Cons.fromArray(args);
|
||||
|
||||
callstack.top = 0;
|
||||
datastack.top = 0;
|
||||
dict.init();
|
||||
initNamespace(root);
|
||||
topLevel();
|
||||
if(bootstrap)
|
||||
runBootstrap();
|
||||
runBootstrap();
|
||||
} //}}}
|
||||
|
||||
//{{{ initNamespace() method
|
||||
|
@ -122,8 +111,9 @@ public class FactorInterpreter
|
|||
|
||||
global.setVariable("interpreter",this);
|
||||
|
||||
String[] boundFields = { "compile", "interactive", "trace",
|
||||
"dict", "errorFlag" };
|
||||
String[] boundFields = { "compile", "compileDump",
|
||||
"interactive", "trace",
|
||||
"dict", "errorFlag", "args" };
|
||||
for(int i = 0; i < boundFields.length; i++)
|
||||
{
|
||||
global.setVariable(boundFields[i],
|
||||
|
@ -160,7 +150,7 @@ public class FactorInterpreter
|
|||
if(callframe == null)
|
||||
break;
|
||||
|
||||
FactorList ip = callframe.ip;
|
||||
Cons ip = callframe.ip;
|
||||
|
||||
if(ip == null)
|
||||
{
|
||||
|
@ -213,6 +203,8 @@ public class FactorInterpreter
|
|||
System.err.println("Factor callstack:");
|
||||
System.err.println(callstack);
|
||||
|
||||
topLevel();
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
@ -231,6 +223,8 @@ public class FactorInterpreter
|
|||
System.err.println("Factor callstack:");
|
||||
System.err.println(callstack);
|
||||
|
||||
topLevel();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -240,7 +234,7 @@ public class FactorInterpreter
|
|||
/**
|
||||
* Pushes the given list of code onto the callstack.
|
||||
*/
|
||||
public final void call(FactorList code)
|
||||
public final void call(Cons code)
|
||||
{
|
||||
call(dict.intern("call"),code);
|
||||
} //}}}
|
||||
|
@ -249,7 +243,7 @@ public class FactorInterpreter
|
|||
/**
|
||||
* Pushes the given list of code onto the callstack.
|
||||
*/
|
||||
public final void call(FactorWord word, FactorList code)
|
||||
public final void call(FactorWord word, Cons code)
|
||||
{
|
||||
if(callframe == null)
|
||||
call(word,global,code);
|
||||
|
@ -261,7 +255,7 @@ public class FactorInterpreter
|
|||
/**
|
||||
* Pushes the given list of code onto the callstack.
|
||||
*/
|
||||
public final void call(FactorWord word, FactorNamespace namespace, FactorList code)
|
||||
public final void call(FactorWord word, FactorNamespace namespace, Cons code)
|
||||
{
|
||||
FactorCallFrame newcf;
|
||||
|
||||
|
@ -321,17 +315,15 @@ public class FactorInterpreter
|
|||
|
||||
if(obj instanceof FactorWord)
|
||||
{
|
||||
FactorWord w = (FactorWord)obj;
|
||||
|
||||
try
|
||||
{
|
||||
w.def.eval(w,this);
|
||||
((FactorWord)obj).def.eval(this);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
callstack.push(callframe);
|
||||
callframe = new FactorCallFrame(
|
||||
w,
|
||||
(FactorWord)obj,
|
||||
callframe.namespace,
|
||||
null);
|
||||
throw e;
|
||||
|
|
|
@ -29,22 +29,24 @@
|
|||
|
||||
package factor;
|
||||
|
||||
import factor.compiler.LocalAllocator;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import org.objectweb.asm.*;
|
||||
|
||||
/**
|
||||
* A few methods for converting between Java types, and making reflection calls.
|
||||
* Note that the compiler incorporates calls to some of these methods in
|
||||
* generated bytecode.
|
||||
*/
|
||||
public class FactorJava
|
||||
public class FactorJava implements Constants
|
||||
{
|
||||
public static final Class[] EMPTY_ARRAY = new Class[0];
|
||||
|
||||
//{{{ classNameToClassList() method
|
||||
public static Class[] classNameToClassList(FactorList classes)
|
||||
public static Class[] classNameToClassList(Cons classes)
|
||||
throws Exception
|
||||
{
|
||||
if(classes == null)
|
||||
|
@ -54,7 +56,31 @@ public class FactorJava
|
|||
int i = 0;
|
||||
while(classes != null)
|
||||
{
|
||||
_classes[i++] = (Class)classes.car(Class.class);
|
||||
Object car = classes.car;
|
||||
if(car instanceof Cons)
|
||||
{
|
||||
Cons classSpec = (Cons)car;
|
||||
if(classSpec.cdr != null)
|
||||
{
|
||||
throw new FactorRuntimeException(
|
||||
"Bad class spec: " + car);
|
||||
}
|
||||
Class clazz = (Class)classSpec.car(Class.class);
|
||||
if(clazz.isPrimitive())
|
||||
{
|
||||
_classes[i] = getClass("["
|
||||
+ javaClassToVMClass(clazz));
|
||||
}
|
||||
else
|
||||
{
|
||||
_classes[i] = getClass("[L"
|
||||
+ clazz.getName() + ";");
|
||||
}
|
||||
}
|
||||
else
|
||||
_classes[i] = (Class)classes.car(Class.class);
|
||||
|
||||
i++;
|
||||
classes = classes.next();
|
||||
}
|
||||
|
||||
|
@ -183,6 +209,29 @@ public class FactorJava
|
|||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ toNamespace() method
|
||||
public static FactorNamespace toNamespace(Object obj,
|
||||
FactorInterpreter interp) throws Exception
|
||||
{
|
||||
if(obj instanceof FactorNamespace)
|
||||
return (FactorNamespace)obj;
|
||||
else if(obj instanceof FactorObject)
|
||||
{
|
||||
FactorNamespace ns = ((FactorObject)obj)
|
||||
.getNamespace(interp);
|
||||
if(ns == null)
|
||||
throw new FactorRuntimeException(
|
||||
obj + " has a null"
|
||||
+ " namespace");
|
||||
return ns;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new FactorDomainException(obj,
|
||||
FactorObject.class);
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ toArray() method
|
||||
public static Object[] toArray(Object arg)
|
||||
throws FactorDomainException
|
||||
|
@ -194,9 +243,9 @@ public class FactorJava
|
|||
public static Object[] toArray(Object arg, Class clas)
|
||||
throws FactorDomainException
|
||||
{
|
||||
if(arg instanceof FactorList)
|
||||
if(arg instanceof Cons)
|
||||
{
|
||||
FactorList list = (FactorList)arg;
|
||||
Cons list = (Cons)arg;
|
||||
Object[] array = (Object[])
|
||||
Array.newInstance(
|
||||
clas.getComponentType(),
|
||||
|
@ -205,7 +254,21 @@ public class FactorJava
|
|||
return array;
|
||||
}
|
||||
else if(arg.getClass().isArray())
|
||||
return (Object[])arg;
|
||||
{
|
||||
if(arg.getClass() == clas)
|
||||
return (Object[])arg;
|
||||
else
|
||||
{
|
||||
Object[] _arg = (Object[])arg;
|
||||
Object[] array = (Object[])
|
||||
Array.newInstance(
|
||||
clas.getComponentType(),
|
||||
_arg.length);
|
||||
System.arraycopy(arg,0,array,0,
|
||||
_arg.length);
|
||||
return array;
|
||||
}
|
||||
}
|
||||
else
|
||||
throw new FactorDomainException(arg,Object[].class);
|
||||
} //}}}
|
||||
|
@ -296,7 +359,7 @@ public class FactorJava
|
|||
else if(obj instanceof Character)
|
||||
return "#\\" + ((Character)obj).charValue();
|
||||
else
|
||||
return "(" + obj + ")";
|
||||
return "( " + obj + " )";
|
||||
} //}}}
|
||||
|
||||
//{{{ javaClassToVMClass() method
|
||||
|
@ -387,7 +450,7 @@ public class FactorJava
|
|||
} //}}}
|
||||
|
||||
//{{{ jconstructor() method
|
||||
public static Constructor jconstructor(String inClass, FactorList args)
|
||||
public static Constructor jconstructor(String inClass, Cons args)
|
||||
throws Exception
|
||||
{
|
||||
return Class.forName(inClass).getConstructor(
|
||||
|
@ -458,7 +521,7 @@ public class FactorJava
|
|||
|
||||
//{{{ jmethod() method
|
||||
public static Method jmethod(String method, String inClass,
|
||||
FactorList args) throws Exception
|
||||
Cons args) throws Exception
|
||||
{
|
||||
return Class.forName(inClass).getMethod(method,
|
||||
classNameToClassList(args));
|
||||
|
@ -519,4 +582,126 @@ public class FactorJava
|
|||
else
|
||||
return e;
|
||||
} //}}}
|
||||
|
||||
//{{{ generateFromConversion() method
|
||||
/**
|
||||
* Unbox value at top of the stack.
|
||||
*/
|
||||
public static void generateFromConversion(CodeVisitor mw, Class type)
|
||||
throws Exception
|
||||
{
|
||||
if(type == Object.class)
|
||||
return;
|
||||
|
||||
String methodName = null;
|
||||
boolean interpArg = false;
|
||||
|
||||
if(type == Number.class)
|
||||
methodName = "toNumber";
|
||||
else if(type == String.class)
|
||||
methodName = "toString";
|
||||
else if(type == boolean.class)
|
||||
methodName = "toBoolean";
|
||||
else if(type == char.class)
|
||||
methodName = "toChar";
|
||||
else if(type == int.class)
|
||||
methodName = "toInt";
|
||||
else if(type == long.class)
|
||||
methodName = "toLong";
|
||||
else if(type == float.class)
|
||||
methodName = "toFloat";
|
||||
else if(type == double.class)
|
||||
methodName = "toDouble";
|
||||
else if(type == Class.class)
|
||||
methodName = "toClass";
|
||||
else if(type == FactorNamespace.class)
|
||||
{
|
||||
methodName = "toNamespace";
|
||||
interpArg = true;
|
||||
}
|
||||
else if(type.isArray())
|
||||
methodName = "toArray";
|
||||
|
||||
if(methodName == null)
|
||||
{
|
||||
mw.visitTypeInsn(CHECKCAST,
|
||||
type.getName()
|
||||
.replace('.','/'));
|
||||
}
|
||||
else
|
||||
{
|
||||
if(interpArg)
|
||||
{
|
||||
mw.visitVarInsn(ALOAD,0);
|
||||
mw.visitMethodInsn(INVOKESTATIC,
|
||||
"factor/FactorJava",
|
||||
methodName,
|
||||
"(Ljava/lang/Object;Lfactor/FactorInterpreter;)"
|
||||
+ FactorJava.javaClassToVMClass(type));
|
||||
}
|
||||
else
|
||||
{
|
||||
mw.visitMethodInsn(INVOKESTATIC,
|
||||
"factor/FactorJava",
|
||||
methodName,
|
||||
"(Ljava/lang/Object;)"
|
||||
+ FactorJava.javaClassToVMClass(type));
|
||||
}
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ generateToConversionPre() method
|
||||
/**
|
||||
* Avoid having to deal with category 1/2 computational type
|
||||
* distinction.
|
||||
*/
|
||||
public static boolean generateToConversionPre(CodeVisitor mw,
|
||||
Class type) throws Exception
|
||||
{
|
||||
if(type != boolean.class)
|
||||
{
|
||||
Class boxingType = FactorJava.javaBoxingType(type);
|
||||
if(boxingType != null)
|
||||
{
|
||||
String boxingName = boxingType.getName()
|
||||
.replace('.','/');
|
||||
mw.visitTypeInsn(NEW,boxingName);
|
||||
mw.visitInsn(DUP);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
} //}}}
|
||||
|
||||
//{{{ generateToConversion() method
|
||||
/**
|
||||
* Box return value, if needed.
|
||||
*/
|
||||
public static void generateToConversion(CodeVisitor mw, Class type)
|
||||
throws Exception
|
||||
{
|
||||
if(type == boolean.class)
|
||||
{
|
||||
// this case is handled specially
|
||||
mw.visitMethodInsn(INVOKESTATIC,
|
||||
"factor/FactorJava",
|
||||
"fromBoolean",
|
||||
"(Z)Ljava/lang/Object;");
|
||||
}
|
||||
else
|
||||
{
|
||||
Class boxingType = FactorJava.javaBoxingType(type);
|
||||
if(boxingType != null)
|
||||
{
|
||||
String boxingName = boxingType.getName()
|
||||
.replace('.','/');
|
||||
mw.visitMethodInsn(INVOKESPECIAL,boxingName,
|
||||
"<init>",
|
||||
"(" + FactorJava.javaClassToVMClass(
|
||||
type) + ")V");
|
||||
}
|
||||
}
|
||||
} //}}}
|
||||
}
|
||||
|
|
|
@ -36,12 +36,6 @@ import java.io.*;
|
|||
*/
|
||||
public class FactorLib
|
||||
{
|
||||
//{{{ branch2() method
|
||||
public static Object branch2(boolean condition, Object o1, Object o2)
|
||||
{
|
||||
return (condition ? o1 : o2);
|
||||
} //}}}
|
||||
|
||||
//{{{ branch3() method
|
||||
public static Object branch3(float x, float y,
|
||||
Object o1, Object o2, Object o3)
|
||||
|
@ -54,36 +48,6 @@ public class FactorLib
|
|||
return o3;
|
||||
} //}}}
|
||||
|
||||
//{{{ cat() method
|
||||
public static String cat(FactorList list)
|
||||
{
|
||||
StringBuffer buf = new StringBuffer();
|
||||
|
||||
while(list != null)
|
||||
{
|
||||
if(list.car instanceof FactorList)
|
||||
buf.append(cat((FactorList)list.car));
|
||||
else
|
||||
buf.append(list.car);
|
||||
list = list.next();
|
||||
}
|
||||
|
||||
return buf.toString();
|
||||
} //}}}
|
||||
|
||||
//{{{ cat2() method
|
||||
public static String cat2(Object str1, Object str2)
|
||||
{
|
||||
return new StringBuffer().append(str1).append(str2).toString();
|
||||
} //}}}
|
||||
|
||||
//{{{ cat3() method
|
||||
public static String cat3(Object str1, Object str2, Object str3)
|
||||
{
|
||||
return new StringBuffer().append(str1).append(str2).append(str3)
|
||||
.toString();
|
||||
} //}}}
|
||||
|
||||
//{{{ cloneArray() method
|
||||
public static Object[] cloneArray(Object[] array)
|
||||
{
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2003 Slava Pestov.
|
||||
* Copyright (C) 2003,2004 Slava Pestov.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
|
@ -282,6 +282,12 @@ public class FactorMath
|
|||
return min + Math.abs(nextInt % (max - min + 1));
|
||||
} //}}}
|
||||
|
||||
//{{{ randomFloat() method
|
||||
public static float randomFloat(int min, int max, float scale)
|
||||
{
|
||||
return randomInt(min,max) / scale;
|
||||
} //}}}
|
||||
|
||||
//{{{ sgn() method
|
||||
public static int sgn(float num)
|
||||
{
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2003 Slava Pestov.
|
||||
* Copyright (C) 2003, 2004 Slava Pestov.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
|
@ -29,16 +29,22 @@
|
|||
|
||||
package factor;
|
||||
|
||||
import factor.compiler.*;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A placeholder for an undefined word.
|
||||
*/
|
||||
public class FactorMissingDefinition extends FactorWordDefinition
|
||||
{
|
||||
public static final FactorMissingDefinition INSTANCE
|
||||
= new FactorMissingDefinition();
|
||||
//{{{ FactorMissingDefinition constructor
|
||||
public FactorMissingDefinition(FactorWord word)
|
||||
{
|
||||
super(word);
|
||||
} //}}}
|
||||
|
||||
//{{{ eval() method
|
||||
public void eval(FactorWord word, FactorInterpreter interp)
|
||||
public void eval(FactorInterpreter interp)
|
||||
throws FactorUndefinedWordException
|
||||
{
|
||||
throw new FactorUndefinedWordException(word);
|
||||
|
|
|
@ -115,7 +115,7 @@ public class FactorNamespace implements PublicCloneable
|
|||
/**
|
||||
* Defines a variable bound to a Java field.
|
||||
*/
|
||||
public void importVars(String clazz, FactorList vars)
|
||||
public void importVars(String clazz, Cons vars)
|
||||
throws Exception
|
||||
{
|
||||
Class clas = Class.forName(clazz);
|
||||
|
@ -157,16 +157,6 @@ public class FactorNamespace implements PublicCloneable
|
|||
return o;
|
||||
} //}}}
|
||||
|
||||
//{{{ _setVariable() method
|
||||
/**
|
||||
* Alternative form for bindings.
|
||||
*/
|
||||
public void _setVariable(Object value, String name)
|
||||
throws Exception
|
||||
{
|
||||
setVariable(name,value);
|
||||
} //}}}
|
||||
|
||||
//{{{ setVariable() method
|
||||
public void setVariable(String name, Object value)
|
||||
throws Exception
|
||||
|
@ -214,10 +204,10 @@ public class FactorNamespace implements PublicCloneable
|
|||
/**
|
||||
* Returns a list of variable and word names defined in this namespace.
|
||||
*/
|
||||
public FactorList toVarList()
|
||||
public Cons toVarList()
|
||||
{
|
||||
FactorList first = null;
|
||||
FactorList last = null;
|
||||
Cons first = null;
|
||||
Cons last = null;
|
||||
Iterator iter = words.entrySet().iterator();
|
||||
while(iter.hasNext())
|
||||
{
|
||||
|
@ -226,7 +216,7 @@ public class FactorNamespace implements PublicCloneable
|
|||
continue;
|
||||
|
||||
String name = (String)entry.getKey();
|
||||
FactorList cons = new FactorList(name,null);
|
||||
Cons cons = new Cons(name,null);
|
||||
if(first == null)
|
||||
first = last = cons;
|
||||
else
|
||||
|
@ -243,10 +233,10 @@ public class FactorNamespace implements PublicCloneable
|
|||
/**
|
||||
* Returns a list of pairs of variable and word names, and their values.
|
||||
*/
|
||||
public FactorList toValueList()
|
||||
public Cons toValueList()
|
||||
{
|
||||
FactorList first = null;
|
||||
FactorList last = null;
|
||||
Cons first = null;
|
||||
Cons last = null;
|
||||
Iterator iter = words.entrySet().iterator();
|
||||
while(iter.hasNext())
|
||||
{
|
||||
|
@ -254,8 +244,8 @@ public class FactorNamespace implements PublicCloneable
|
|||
if(entry.getValue() == CHECK_PARENT)
|
||||
continue;
|
||||
|
||||
FactorList cons = new FactorList(
|
||||
new FactorList(entry.getKey(),
|
||||
Cons cons = new Cons(
|
||||
new Cons(entry.getKey(),
|
||||
entry.getValue()),null);
|
||||
if(first == null)
|
||||
first = last = cons;
|
||||
|
@ -299,7 +289,13 @@ public class FactorNamespace implements PublicCloneable
|
|||
//{{{ toString() method
|
||||
public String toString()
|
||||
{
|
||||
return "Namespace[" + obj + "]";
|
||||
if(obj == null)
|
||||
{
|
||||
return "( Namespace #" + Integer.toString(hashCode(),16)
|
||||
+ " )";
|
||||
}
|
||||
else
|
||||
return "( Namespace: " + obj + " #" + hashCode() + " )";
|
||||
} //}}}
|
||||
|
||||
//{{{ clone() method
|
||||
|
|
|
@ -108,10 +108,10 @@ public class FactorParser
|
|||
* Reads the file being parsed, and returns a list of all tokens that
|
||||
* were read in. This list can be evaluated to run the file.
|
||||
*/
|
||||
public FactorList parse() throws IOException, FactorParseException
|
||||
public Cons parse() throws IOException, FactorParseException
|
||||
{
|
||||
FactorList first = null;
|
||||
FactorList last = null;
|
||||
Cons first = null;
|
||||
Cons last = null;
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -131,12 +131,15 @@ public class FactorParser
|
|||
error("Expected word name after " + next);
|
||||
}
|
||||
|
||||
FactorWordDefinition def = readDef();
|
||||
FactorWord word = (FactorWord)obj;
|
||||
|
||||
FactorList l = new FactorList(DEFINE,null);
|
||||
FactorList cons = new FactorList(
|
||||
((FactorWord)obj).name,
|
||||
new FactorList(def,l));
|
||||
FactorWordDefinition def
|
||||
= readDef(word);
|
||||
|
||||
Cons l = new Cons(DEFINE,null);
|
||||
Cons cons = new Cons(
|
||||
word.name,
|
||||
new Cons(def,l));
|
||||
if(first == null)
|
||||
first = cons;
|
||||
else
|
||||
|
@ -152,12 +155,15 @@ public class FactorParser
|
|||
error("Expected word name after " + next);
|
||||
}
|
||||
|
||||
FactorWordDefinition def = readShuffle();
|
||||
FactorWord word = (FactorWord)obj;
|
||||
|
||||
FactorList l = new FactorList(DEFINE,null);
|
||||
FactorList cons = new FactorList(
|
||||
((FactorWord)obj).name,
|
||||
new FactorList(def,l));
|
||||
FactorWordDefinition def
|
||||
= readShuffle(word);
|
||||
|
||||
Cons l = new Cons(DEFINE,null);
|
||||
Cons cons = new Cons(
|
||||
word.name,
|
||||
new Cons(def,l));
|
||||
if(first == null)
|
||||
first = cons;
|
||||
else
|
||||
|
@ -166,7 +172,7 @@ public class FactorParser
|
|||
}
|
||||
else if(next == BRA)
|
||||
{
|
||||
FactorList cons = new FactorList(
|
||||
Cons cons = new Cons(
|
||||
readList(),null);
|
||||
if(first == null)
|
||||
first = cons;
|
||||
|
@ -180,7 +186,7 @@ public class FactorParser
|
|||
}
|
||||
else
|
||||
{
|
||||
FactorList cons = new FactorList(next,null);
|
||||
Cons cons = new Cons(next,null);
|
||||
if(first == null)
|
||||
first = cons;
|
||||
else
|
||||
|
@ -323,10 +329,10 @@ public class FactorParser
|
|||
/**
|
||||
* Read list until ;.
|
||||
*/
|
||||
private FactorWordDefinition readDef()
|
||||
private FactorWordDefinition readDef(FactorWord word)
|
||||
throws IOException, FactorParseException
|
||||
{
|
||||
return new FactorCompoundDefinition(readList(INE,false));
|
||||
return new FactorCompoundDefinition(word,readList(INE,false));
|
||||
} //}}}
|
||||
|
||||
//{{{ readShuffle() method
|
||||
|
@ -336,7 +342,7 @@ public class FactorParser
|
|||
* On the left is inputs, on the right is their arrangement on the
|
||||
* stack.
|
||||
*/
|
||||
private FactorWordDefinition readShuffle()
|
||||
private FactorWordDefinition readShuffle(FactorWord word)
|
||||
throws IOException, FactorParseException
|
||||
{
|
||||
// 0 in consume map is last consumed, n is first consumed.
|
||||
|
@ -377,13 +383,14 @@ public class FactorParser
|
|||
}
|
||||
}
|
||||
|
||||
FactorList _shuffle = readList(FLE,false);
|
||||
Cons _shuffle = readList(FLE,false);
|
||||
|
||||
int consume = consumeMap.size();
|
||||
|
||||
if(_shuffle == null)
|
||||
{
|
||||
return new FactorShuffleDefinition(consumeD,consumeR,
|
||||
return new FactorShuffleDefinition(word,
|
||||
consumeD,consumeR,
|
||||
null,0,null,0);
|
||||
}
|
||||
|
||||
|
@ -397,12 +404,12 @@ public class FactorParser
|
|||
{
|
||||
if(_shuffle.car instanceof FactorWord)
|
||||
{
|
||||
FactorWord word = ((FactorWord)_shuffle.car);
|
||||
String name = word.name;
|
||||
FactorWord w = ((FactorWord)_shuffle.car);
|
||||
String name = w.name;
|
||||
if(name.startsWith("r:"))
|
||||
word = dict.intern(name.substring(2));
|
||||
w = dict.intern(name.substring(2));
|
||||
|
||||
Integer _index = (Integer)consumeMap.get(word);
|
||||
Integer _index = (Integer)consumeMap.get(w);
|
||||
if(_index == null)
|
||||
error("Does not appear in shuffle LHS: " + _shuffle.car);
|
||||
int index = _index.intValue();
|
||||
|
@ -445,7 +452,7 @@ public class FactorParser
|
|||
shuffleD[k++] = index;
|
||||
}
|
||||
|
||||
return new FactorShuffleDefinition(consumeD,consumeR,
|
||||
return new FactorShuffleDefinition(word,consumeD,consumeR,
|
||||
shuffleD,shuffleDlength,shuffleR,shuffleRlength);
|
||||
} //}}}
|
||||
|
||||
|
@ -453,7 +460,7 @@ public class FactorParser
|
|||
/**
|
||||
* Read list until ].
|
||||
*/
|
||||
private FactorList readList()
|
||||
private Cons readList()
|
||||
throws IOException, FactorParseException
|
||||
{
|
||||
return readList(KET,true);
|
||||
|
@ -463,11 +470,11 @@ public class FactorParser
|
|||
/**
|
||||
* Read list until a given word.
|
||||
*/
|
||||
private FactorList readList(FactorWord until, boolean allowCommaPair)
|
||||
private Cons readList(FactorWord until, boolean allowCommaPair)
|
||||
throws IOException, FactorParseException
|
||||
{
|
||||
FactorList first = null;
|
||||
FactorList last = null;
|
||||
Cons first = null;
|
||||
Cons last = null;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
|
@ -509,12 +516,12 @@ public class FactorParser
|
|||
}
|
||||
else if(next == BRA)
|
||||
{
|
||||
FactorList list = readList();
|
||||
Cons list = readList();
|
||||
if(first == null)
|
||||
first = last = new FactorList(list,null);
|
||||
first = last = new Cons(list,null);
|
||||
else
|
||||
{
|
||||
FactorList nextList = new FactorList(list,null);
|
||||
Cons nextList = new Cons(list,null);
|
||||
last.cdr = nextList;
|
||||
last = nextList;
|
||||
}
|
||||
|
@ -522,10 +529,10 @@ public class FactorParser
|
|||
else if(isParsingWord(next))
|
||||
error("Unexpected " + next);
|
||||
else if(first == null)
|
||||
first = last = new FactorList(next,null);
|
||||
first = last = new Cons(next,null);
|
||||
else
|
||||
{
|
||||
FactorList nextList = new FactorList(next,null);
|
||||
Cons nextList = new Cons(next,null);
|
||||
last.cdr = nextList;
|
||||
last = nextList;
|
||||
}
|
||||
|
|
|
@ -1,374 +0,0 @@
|
|||
/* :folding=explicit:collapseFolds=1: */
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2003 Slava Pestov.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package factor;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
|
||||
public abstract class FactorPrimitive extends FactorWordDefinition
|
||||
{
|
||||
//{{{ P_callstackGet class
|
||||
static class P_callstackGet extends FactorPrimitive
|
||||
{
|
||||
public void eval(FactorWord word, FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
interp.datastack.push(interp.callstack.clone());
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ P_callstackSet class
|
||||
static class P_callstackSet extends FactorPrimitive
|
||||
{
|
||||
public void eval(FactorWord word, FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
interp.callstack = (FactorCallStack)((FactorCallStack)
|
||||
interp.datastack.pop(FactorCallStack.class))
|
||||
.clone();
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ P_datastackGet class
|
||||
static class P_datastackGet extends FactorPrimitive
|
||||
{
|
||||
public void eval(FactorWord word, FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
interp.datastack.push(interp.datastack.clone());
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ P_datastackSet class
|
||||
static class P_datastackSet extends FactorPrimitive
|
||||
{
|
||||
public void eval(FactorWord word, FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
interp.datastack = (FactorDataStack)((FactorDataStack)
|
||||
interp.datastack.pop(FactorDataStack.class))
|
||||
.clone();
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ P_clear class
|
||||
static class P_clear extends FactorPrimitive
|
||||
{
|
||||
public void eval(FactorWord word, FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
interp.datastack.top = 0;
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ P_restack class
|
||||
static class P_restack extends FactorPrimitive
|
||||
{
|
||||
public void eval(FactorWord word, FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
FactorDataStack datastack = interp.datastack;
|
||||
FactorList list = (FactorList)datastack.pop(FactorList.class);
|
||||
interp.callstack.push(datastack);
|
||||
interp.datastack = new FactorDataStack(list);
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ P_unstack class
|
||||
static class P_unstack extends FactorPrimitive
|
||||
{
|
||||
public void eval(FactorWord word, FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
FactorList unstack = interp.datastack.toList();
|
||||
interp.datastack = (FactorDataStack)interp.callstack.pop();
|
||||
interp.datastack.push(unstack);
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ P_unwind class
|
||||
static class P_unwind extends FactorPrimitive
|
||||
{
|
||||
public void eval(FactorWord word, FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
interp.callstack.top = 0;
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ P_jconstructor class
|
||||
static class P_jconstructor extends FactorPrimitive
|
||||
{
|
||||
public void eval(FactorWord word, FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
FactorDataStack datastack = interp.datastack;
|
||||
datastack.push(
|
||||
FactorJava.jconstructor(
|
||||
(String)datastack.pop(String.class),
|
||||
(FactorList)datastack.pop(FactorList.class)));
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ P_jfield class
|
||||
static class P_jfield extends FactorPrimitive
|
||||
{
|
||||
public void eval(FactorWord word, FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
FactorDataStack datastack = interp.datastack;
|
||||
datastack.push(
|
||||
FactorJava.jfield(
|
||||
(String)datastack.pop(String.class),
|
||||
(String)datastack.pop(String.class)));
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ P_jinvoke class
|
||||
static class P_jinvoke extends FactorPrimitive
|
||||
{
|
||||
public void eval(FactorWord word, FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
FactorDataStack datastack = interp.datastack;
|
||||
FactorJava.jinvoke(datastack,
|
||||
(Method)datastack.pop(),
|
||||
datastack.pop());
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ P_jinvokeStatic class
|
||||
static class P_jinvokeStatic extends FactorPrimitive
|
||||
{
|
||||
public void eval(FactorWord word, FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
FactorDataStack datastack = interp.datastack;
|
||||
FactorJava.jinvokeStatic(datastack,
|
||||
(Method)datastack.pop());
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ P_jmethod class
|
||||
static class P_jmethod extends FactorPrimitive
|
||||
{
|
||||
public void eval(FactorWord word, FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
FactorDataStack datastack = interp.datastack;
|
||||
datastack.push(
|
||||
FactorJava.jmethod(
|
||||
(String)datastack.pop(String.class),
|
||||
(String)datastack.pop(String.class),
|
||||
(FactorList)datastack.pop(FactorList.class)));
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ P_jnew class
|
||||
static class P_jnew extends FactorPrimitive
|
||||
{
|
||||
public void eval(FactorWord word, FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
FactorDataStack datastack = interp.datastack;
|
||||
FactorJava.jnew(datastack,
|
||||
(Constructor)datastack.pop());
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ P_jvarGet class
|
||||
static class P_jvarGet extends FactorPrimitive
|
||||
{
|
||||
public void eval(FactorWord word, FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
FactorDataStack datastack = interp.datastack;
|
||||
datastack.push(
|
||||
FactorJava.jvarGet(
|
||||
(Field)datastack.pop(Field.class),
|
||||
datastack.pop()));
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ P_jvarGetStatic class
|
||||
static class P_jvarGetStatic extends FactorPrimitive
|
||||
{
|
||||
public void eval(FactorWord word, FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
FactorDataStack datastack = interp.datastack;
|
||||
datastack.push(
|
||||
FactorJava.jvarGetStatic(
|
||||
(Field)datastack.pop(Field.class)));
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ P_jvarSet class
|
||||
static class P_jvarSet extends FactorPrimitive
|
||||
{
|
||||
public void eval(FactorWord word, FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
FactorDataStack datastack = interp.datastack;
|
||||
FactorJava.jvarSet(
|
||||
(Field)datastack.pop(Field.class),
|
||||
datastack.pop(),
|
||||
datastack.pop());
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ P_jvarSetStatic class
|
||||
static class P_jvarSetStatic extends FactorPrimitive
|
||||
{
|
||||
public void eval(FactorWord word, FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
FactorDataStack datastack = interp.datastack;
|
||||
FactorJava.jvarSetStatic(
|
||||
(Field)datastack.pop(Field.class),
|
||||
datastack.pop());
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ P_get class
|
||||
static class P_get extends FactorPrimitive
|
||||
{
|
||||
public void eval(FactorWord word, FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
FactorDataStack datastack = interp.datastack;
|
||||
datastack.push(interp.callframe.namespace.getVariable(
|
||||
(String)datastack.pop(String.class)));
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ P_set class
|
||||
static class P_set extends FactorPrimitive
|
||||
{
|
||||
public void eval(FactorWord word, FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
FactorDataStack datastack = interp.datastack;
|
||||
interp.callframe.namespace.setVariable(
|
||||
(String)datastack.pop(String.class),
|
||||
datastack.pop());
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ P_swap_set class
|
||||
static class P_swap_set extends FactorPrimitive
|
||||
{
|
||||
public void eval(FactorWord word, FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
FactorDataStack datastack = interp.datastack;
|
||||
interp.callframe.namespace._setVariable(datastack.pop(),
|
||||
(String)datastack.pop(String.class));
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ P_define class
|
||||
static class P_define extends FactorPrimitive
|
||||
{
|
||||
public void eval(FactorWord word, FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
FactorDataStack datastack = interp.datastack;
|
||||
FactorDictionary dict = interp.dict;
|
||||
// handle old define syntax
|
||||
Object obj = datastack.pop();
|
||||
if(obj instanceof FactorList)
|
||||
obj = new FactorCompoundDefinition((FactorList)obj);
|
||||
FactorWordDefinition def = (FactorWordDefinition)obj;
|
||||
|
||||
FactorWord newWord = interp.dict.intern(
|
||||
(String)datastack.pop(String.class));
|
||||
|
||||
def.precompile(newWord,interp);
|
||||
try
|
||||
{
|
||||
if(interp.compile)
|
||||
def = def.compile(newWord,interp);
|
||||
}
|
||||
catch(Throwable t)
|
||||
{
|
||||
System.err.println("WARNING: cannot compile " + newWord);
|
||||
t.printStackTrace();
|
||||
}
|
||||
|
||||
if(newWord.def != FactorMissingDefinition.INSTANCE)
|
||||
{
|
||||
System.err.println("WARNING: redefining " + newWord);
|
||||
newWord.history = new FactorList(newWord.def,
|
||||
newWord.history);
|
||||
}
|
||||
newWord.def = def;
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ P_call class
|
||||
static class P_call extends FactorPrimitive
|
||||
{
|
||||
public void eval(FactorWord word, FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
interp.call(word,(FactorList)interp.datastack.pop(
|
||||
FactorList.class));
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ P_bind class
|
||||
static class P_bind extends FactorPrimitive
|
||||
{
|
||||
public void eval(FactorWord word, FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
FactorDataStack datastack = interp.datastack;
|
||||
FactorList code = (FactorList)datastack.pop(FactorList.class);
|
||||
Object obj = datastack.pop();
|
||||
FactorNamespace ns;
|
||||
if(obj instanceof FactorNamespace)
|
||||
ns = (FactorNamespace)obj;
|
||||
else if(obj instanceof FactorObject)
|
||||
{
|
||||
ns = ((FactorObject)obj).getNamespace(interp);
|
||||
if(ns == null)
|
||||
throw new FactorRuntimeException(
|
||||
obj + " has a null"
|
||||
+ " namespace");
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new FactorDomainException(obj,
|
||||
FactorObject.class);
|
||||
}
|
||||
interp.call(word,ns,code);
|
||||
}
|
||||
} //}}}
|
||||
}
|
|
@ -1,394 +0,0 @@
|
|||
/* :folding=explicit:collapseFolds=1: */
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2003, 2004 Slava Pestov.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package factor;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
import org.objectweb.asm.*;
|
||||
|
||||
class FactorReflectionForm implements Constants
|
||||
{
|
||||
private FactorList form;
|
||||
|
||||
//{{{ FactorReflectionForm constructor
|
||||
FactorReflectionForm(FactorList form)
|
||||
{
|
||||
this.form = form;
|
||||
} //}}}
|
||||
|
||||
//{{{ compile() method
|
||||
boolean compile(FactorWord word, FactorInterpreter interp,
|
||||
ClassWriter cw, CodeVisitor mw)
|
||||
throws Exception
|
||||
{
|
||||
FactorDictionary dict = interp.dict;
|
||||
if(form.car == dict.jvarGet)
|
||||
{
|
||||
return compileVarGet(word,interp,cw,mw,
|
||||
form.next(),false);
|
||||
}
|
||||
else if(form.car == dict.jvarGetStatic)
|
||||
{
|
||||
return compileVarGet(word,interp,cw,mw,
|
||||
form.next(),true);
|
||||
}
|
||||
else if(form.car == dict.jinvoke)
|
||||
{
|
||||
return compileInvoke(word,interp,cw,mw,
|
||||
form.next(),false);
|
||||
}
|
||||
else if(form.car == dict.jinvokeStatic)
|
||||
{
|
||||
return compileInvoke(word,interp,cw,mw,
|
||||
form.next(),true);
|
||||
}
|
||||
else if(form.car == dict.jnew)
|
||||
{
|
||||
return compileNew(word,interp,cw,mw,
|
||||
form.next());
|
||||
}
|
||||
else
|
||||
throw new FactorRuntimeException("Cannot compile " + form.car);
|
||||
} //}}}
|
||||
|
||||
//{{{ compileVarGet() method
|
||||
private boolean compileVarGet(FactorWord word,
|
||||
FactorInterpreter interp,
|
||||
ClassWriter cw,
|
||||
CodeVisitor mw,
|
||||
FactorList form,
|
||||
boolean staticGet) throws Exception
|
||||
{
|
||||
FactorDictionary dict = interp.dict;
|
||||
if(form.car != dict.jfield)
|
||||
return false;
|
||||
|
||||
form = form.next();
|
||||
String field = (String)form.car;
|
||||
String clazz = (String)form.next().car;
|
||||
|
||||
mw.visitVarInsn(ALOAD,2);
|
||||
mw.visitFieldInsn(GETFIELD,
|
||||
"factor/FactorInterpreter", "datastack",
|
||||
"Lfactor/FactorDataStack;");
|
||||
|
||||
if(!staticGet)
|
||||
{
|
||||
mw.visitInsn(DUP);
|
||||
mw.visitMethodInsn(INVOKEVIRTUAL,
|
||||
"factor/FactorArrayStack", "pop",
|
||||
"()Ljava/lang/Object;");
|
||||
}
|
||||
|
||||
Class cls = FactorJava.getClass(clazz);
|
||||
|
||||
generateFromConversion(mw,cls);
|
||||
|
||||
Field fld = cls.getField(field);
|
||||
|
||||
clazz = clazz.replace('.','/');
|
||||
|
||||
mw.visitFieldInsn(staticGet ? GETSTATIC : GETFIELD,
|
||||
clazz,
|
||||
field,
|
||||
FactorJava.javaClassToVMClass(fld.getType()));
|
||||
|
||||
generateToConversion(mw,fld.getType());
|
||||
|
||||
mw.visitMethodInsn(INVOKEVIRTUAL,
|
||||
"factor/FactorArrayStack", "push",
|
||||
"(Ljava/lang/Object;)V");
|
||||
|
||||
mw.visitInsn(RETURN);
|
||||
|
||||
mw.visitMaxs(3,3);
|
||||
|
||||
return true;
|
||||
} //}}}
|
||||
|
||||
//{{{ compileInvoke() method
|
||||
private boolean compileInvoke(FactorWord word,
|
||||
FactorInterpreter interp,
|
||||
ClassWriter cw,
|
||||
CodeVisitor mw,
|
||||
FactorList form,
|
||||
boolean staticInvoke) throws Exception
|
||||
{
|
||||
FactorDictionary dict = interp.dict;
|
||||
if(form.car != dict.jmethod)
|
||||
return false;
|
||||
|
||||
form = form.next();
|
||||
String method = (String)form.car;
|
||||
String clazz = (String)form.next().car;
|
||||
Class[] args = FactorJava.classNameToClassList(
|
||||
(FactorList)form.next().next().car);
|
||||
|
||||
mw.visitVarInsn(ALOAD,2);
|
||||
mw.visitFieldInsn(GETFIELD,
|
||||
"factor/FactorInterpreter", "datastack",
|
||||
"Lfactor/FactorDataStack;");
|
||||
|
||||
Class cls = FactorJava.getClass(clazz);
|
||||
clazz = clazz.replace('.','/');
|
||||
|
||||
if(!staticInvoke)
|
||||
{
|
||||
mw.visitInsn(DUP);
|
||||
mw.visitMethodInsn(INVOKEVIRTUAL,
|
||||
"factor/FactorArrayStack", "pop",
|
||||
"()Ljava/lang/Object;");
|
||||
generateFromConversion(mw,cls);
|
||||
if(args.length != 0)
|
||||
mw.visitInsn(SWAP);
|
||||
}
|
||||
|
||||
generateArgs(mw,args,!staticInvoke);
|
||||
|
||||
Method mth = cls.getMethod(method,args);
|
||||
|
||||
Class returnType = mth.getReturnType();
|
||||
int opcode;
|
||||
if(staticInvoke)
|
||||
opcode = INVOKESTATIC;
|
||||
else if(cls.isInterface())
|
||||
opcode = INVOKEINTERFACE;
|
||||
else
|
||||
opcode = INVOKEVIRTUAL;
|
||||
mw.visitMethodInsn(opcode,
|
||||
clazz,
|
||||
method,
|
||||
FactorJava.javaSignatureToVMSignature(
|
||||
args,returnType));
|
||||
|
||||
if(returnType != Void.TYPE)
|
||||
{
|
||||
generateToConversion(mw,returnType);
|
||||
mw.visitMethodInsn(INVOKEVIRTUAL,
|
||||
"factor/FactorArrayStack", "push",
|
||||
"(Ljava/lang/Object;)V");
|
||||
}
|
||||
else
|
||||
mw.visitInsn(POP);
|
||||
|
||||
mw.visitInsn(RETURN);
|
||||
|
||||
mw.visitMaxs(4 + args.length,5);
|
||||
|
||||
return true;
|
||||
} //}}}
|
||||
|
||||
//{{{ compileNew() method
|
||||
private boolean compileNew(FactorWord word,
|
||||
FactorInterpreter interp,
|
||||
ClassWriter cw,
|
||||
CodeVisitor mw,
|
||||
FactorList form) throws Exception
|
||||
{
|
||||
FactorDictionary dict = interp.dict;
|
||||
if(form.car != dict.jconstructor)
|
||||
return false;
|
||||
|
||||
form = form.next();
|
||||
String clazz = (String)form.car;
|
||||
Class[] args = FactorJava.classNameToClassList(
|
||||
(FactorList)form.next().car);
|
||||
|
||||
clazz = clazz.replace('.','/');
|
||||
mw.visitTypeInsn(NEW,clazz);
|
||||
mw.visitInsn(DUP);
|
||||
|
||||
mw.visitVarInsn(ALOAD,2);
|
||||
mw.visitFieldInsn(GETFIELD,
|
||||
"factor/FactorInterpreter", "datastack",
|
||||
"Lfactor/FactorDataStack;");
|
||||
|
||||
generateArgs(mw,args,true);
|
||||
|
||||
mw.visitMethodInsn(INVOKESPECIAL,
|
||||
clazz,
|
||||
"<init>",
|
||||
FactorJava.javaSignatureToVMSignature(
|
||||
args,void.class));
|
||||
|
||||
mw.visitInsn(SWAP);
|
||||
mw.visitMethodInsn(INVOKEVIRTUAL,
|
||||
"factor/FactorArrayStack", "push",
|
||||
"(Ljava/lang/Object;)V");
|
||||
|
||||
mw.visitInsn(RETURN);
|
||||
|
||||
mw.visitMaxs(5 + args.length,5);
|
||||
|
||||
return true;
|
||||
} //}}}
|
||||
|
||||
//{{{ generateArgs() method
|
||||
/**
|
||||
* Generate instructions for copying arguments from the Factor
|
||||
* datastack to the JVM stack. The types array is used to
|
||||
* perform type conversions.
|
||||
*/
|
||||
private void generateArgs(CodeVisitor mw, Class[] args,
|
||||
boolean generateSwap) throws Exception
|
||||
{
|
||||
if(args.length != 0)
|
||||
{
|
||||
// ensure the stack has enough elements
|
||||
mw.visitInsn(DUP);
|
||||
mw.visitIntInsn(BIPUSH,args.length);
|
||||
mw.visitMethodInsn(INVOKEVIRTUAL,
|
||||
"factor/FactorArrayStack", "ensurePop",
|
||||
"(I)V");
|
||||
|
||||
// datastack.stack -> 3
|
||||
mw.visitInsn(DUP);
|
||||
mw.visitFieldInsn(GETFIELD,
|
||||
"factor/FactorArrayStack", "stack",
|
||||
"[Ljava/lang/Object;");
|
||||
mw.visitVarInsn(ASTORE,3);
|
||||
// datastack.top-args.length -> 4
|
||||
mw.visitInsn(DUP);
|
||||
mw.visitFieldInsn(GETFIELD,
|
||||
"factor/FactorArrayStack", "top",
|
||||
"I");
|
||||
mw.visitIntInsn(BIPUSH,args.length);
|
||||
mw.visitInsn(ISUB);
|
||||
|
||||
// datastack.top -= args.length
|
||||
mw.visitInsn(DUP2);
|
||||
mw.visitFieldInsn(PUTFIELD,
|
||||
"factor/FactorArrayStack", "top",
|
||||
"I");
|
||||
|
||||
mw.visitVarInsn(ISTORE,4);
|
||||
|
||||
if(generateSwap)
|
||||
mw.visitInsn(SWAP);
|
||||
|
||||
for(int i = 0; i < args.length; i++)
|
||||
{
|
||||
mw.visitVarInsn(ALOAD,3);
|
||||
mw.visitVarInsn(ILOAD,4);
|
||||
mw.visitInsn(AALOAD);
|
||||
generateFromConversion(mw,args[i]);
|
||||
if(i != args.length - 1)
|
||||
mw.visitIincInsn(4,1);
|
||||
}
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ generateFromConversion() method
|
||||
/**
|
||||
* Unbox value at top of the stack.
|
||||
*/
|
||||
private void generateFromConversion(CodeVisitor mw, Class type)
|
||||
throws Exception
|
||||
{
|
||||
if(type == Object.class)
|
||||
return;
|
||||
|
||||
String methodName = null;
|
||||
|
||||
if(type == Number.class)
|
||||
methodName = "toNumber";
|
||||
else if(type == String.class)
|
||||
methodName = "toString";
|
||||
else if(type == boolean.class)
|
||||
methodName = "toBoolean";
|
||||
else if(type == char.class)
|
||||
methodName = "toChar";
|
||||
else if(type == int.class)
|
||||
methodName = "toInt";
|
||||
else if(type == long.class)
|
||||
methodName = "toLong";
|
||||
else if(type == float.class)
|
||||
methodName = "toFloat";
|
||||
else if(type == double.class)
|
||||
methodName = "toDouble";
|
||||
else if(type == Class.class)
|
||||
methodName = "toClass";
|
||||
else if(type.isArray())
|
||||
methodName = "toArray";
|
||||
|
||||
if(methodName == null)
|
||||
{
|
||||
mw.visitTypeInsn(CHECKCAST,
|
||||
type.getName()
|
||||
.replace('.','/'));
|
||||
}
|
||||
else
|
||||
{
|
||||
mw.visitMethodInsn(INVOKESTATIC,
|
||||
"factor/FactorJava",
|
||||
methodName,
|
||||
"(Ljava/lang/Object;)"
|
||||
+ FactorJava.javaClassToVMClass(type));
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ generateToConversion() method
|
||||
/**
|
||||
* Box return value, if needed.
|
||||
*/
|
||||
private void generateToConversion(CodeVisitor mw, Class type)
|
||||
throws Exception
|
||||
{
|
||||
if(type == boolean.class)
|
||||
{
|
||||
// this case is handled specially
|
||||
mw.visitMethodInsn(INVOKESTATIC,
|
||||
"factor/FactorJava",
|
||||
"fromBoolean",
|
||||
"(Z)Ljava/lang/Object;");
|
||||
}
|
||||
else
|
||||
{
|
||||
Class boxingType = FactorJava.javaBoxingType(type);
|
||||
if(boxingType != null)
|
||||
{
|
||||
String boxingName = boxingType.getName()
|
||||
.replace('.','/');
|
||||
mw.visitTypeInsn(NEW,boxingName);
|
||||
mw.visitInsn(DUP_X1);
|
||||
mw.visitInsn(SWAP);
|
||||
mw.visitMethodInsn(INVOKESPECIAL,boxingName,
|
||||
"<init>",
|
||||
"(" + FactorJava.javaClassToVMClass(
|
||||
type) + ")V");
|
||||
}
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ toString() method
|
||||
public String toString()
|
||||
{
|
||||
return form.toString();
|
||||
} //}}}
|
||||
}
|
|
@ -29,7 +29,10 @@
|
|||
|
||||
package factor;
|
||||
|
||||
import factor.compiler.*;
|
||||
import java.util.Set;
|
||||
import org.objectweb.asm.*;
|
||||
import org.objectweb.asm.util.*;
|
||||
|
||||
/**
|
||||
* ~<< name ... -- >>~
|
||||
|
@ -63,10 +66,13 @@ public class FactorShuffleDefinition extends FactorWordDefinition
|
|||
private Object[] temporaryR;
|
||||
|
||||
//{{{ FactorShuffleDefinition constructor
|
||||
public FactorShuffleDefinition(int consumeD, int consumeR,
|
||||
public FactorShuffleDefinition(FactorWord word,
|
||||
int consumeD, int consumeR,
|
||||
int[] shuffleD, int shuffleDlength,
|
||||
int[] shuffleR, int shuffleRlength)
|
||||
{
|
||||
super(word);
|
||||
|
||||
this.consumeD = consumeD;
|
||||
this.consumeR = consumeR;
|
||||
this.shuffleD = shuffleD;
|
||||
|
@ -102,295 +108,49 @@ public class FactorShuffleDefinition extends FactorWordDefinition
|
|||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ canCompile() method
|
||||
boolean canCompile()
|
||||
//{{{ getStackEffect() method
|
||||
public StackEffect getStackEffect(Set recursiveCheck,
|
||||
LocalAllocator state) throws FactorStackException
|
||||
{
|
||||
return true;
|
||||
state.ensure(state.datastack,consumeD);
|
||||
state.ensure(state.callstack,consumeR);
|
||||
eval(state.datastack,state.callstack);
|
||||
return new StackEffect(consumeD,shuffleDlength,
|
||||
consumeR,shuffleRlength);
|
||||
} //}}}
|
||||
|
||||
//{{{ compile() method
|
||||
/**
|
||||
* Write the definition of the eval() method in the compiled word.
|
||||
* Local 0 -- this
|
||||
* Local 1 -- word
|
||||
* Local 2 -- interpreter
|
||||
* Compile the given word, returning a new word definition.
|
||||
*/
|
||||
boolean compile(FactorWord word, FactorInterpreter interp,
|
||||
ClassWriter cw, CodeVisitor mw)
|
||||
throws Exception
|
||||
FactorWordDefinition compile(FactorInterpreter interp,
|
||||
Set recursiveCheck) throws Exception
|
||||
{
|
||||
boolean fromD = false;
|
||||
boolean fromR = false;
|
||||
for(int i = 0; i < shuffleDlength; i++)
|
||||
{
|
||||
fromD = true;
|
||||
if((shuffleD[i] & FROM_R_MASK) == FROM_R_MASK)
|
||||
{
|
||||
fromR = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(int i = 0; i < shuffleRlength; i++)
|
||||
{
|
||||
fromR = true;
|
||||
if((shuffleR[i] & FROM_R_MASK) == FROM_R_MASK)
|
||||
{
|
||||
fromR = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
} //}}}
|
||||
|
||||
// Local 3 -- datastack
|
||||
// Local 4 -- datastack top-consumeD
|
||||
// Local 5 -- datastack array
|
||||
if(consumeD != 0 || fromD)
|
||||
{
|
||||
// (datastack datastack datastack)
|
||||
mw.visitVarInsn(ALOAD,2);
|
||||
mw.visitFieldInsn(GETFIELD,
|
||||
"factor/FactorInterpreter", "datastack",
|
||||
"Lfactor/FactorDataStack;");
|
||||
mw.visitInsn(DUP);
|
||||
if(consumeD != 0)
|
||||
{
|
||||
mw.visitInsn(DUP);
|
||||
mw.visitIntInsn(BIPUSH,consumeD);
|
||||
mw.visitMethodInsn(INVOKEVIRTUAL,
|
||||
"factor/FactorArrayStack", "ensurePop",
|
||||
"(I)V");
|
||||
}
|
||||
|
||||
mw.visitInsn(DUP);
|
||||
// datastack -> 3
|
||||
mw.visitVarInsn(ASTORE,3);
|
||||
// datastack.top-consumeD -> 4
|
||||
mw.visitFieldInsn(GETFIELD,
|
||||
"factor/FactorArrayStack", "top",
|
||||
"I");
|
||||
if(consumeD != 0)
|
||||
{
|
||||
mw.visitIntInsn(BIPUSH,consumeD);
|
||||
mw.visitInsn(ISUB);
|
||||
}
|
||||
mw.visitVarInsn(ISTORE,4);
|
||||
// datastack.stack -> 5
|
||||
mw.visitFieldInsn(GETFIELD,
|
||||
"factor/FactorArrayStack", "stack",
|
||||
"[Ljava/lang/Object;");
|
||||
mw.visitVarInsn(ASTORE,5);
|
||||
}
|
||||
|
||||
// Local 6 -- callstack
|
||||
// Local 7 -- callstack top-consumeR
|
||||
// Local 8 -- callstack array
|
||||
if(consumeR != 0 || fromR)
|
||||
{
|
||||
// (callstack callstack)
|
||||
mw.visitVarInsn(ALOAD,2);
|
||||
mw.visitFieldInsn(GETFIELD,
|
||||
"factor/FactorInterpreter", "callstack",
|
||||
"Lfactor/FactorCallStack;");
|
||||
mw.visitInsn(DUP);
|
||||
if(consumeR != 0)
|
||||
{
|
||||
mw.visitInsn(DUP);
|
||||
mw.visitIntInsn(BIPUSH,consumeR);
|
||||
mw.visitMethodInsn(INVOKEVIRTUAL,
|
||||
"factor/FactorArrayStack", "ensurePop",
|
||||
"(I)V");
|
||||
}
|
||||
|
||||
mw.visitInsn(DUP);
|
||||
// callstack -> 6
|
||||
mw.visitVarInsn(ASTORE,6);
|
||||
// callstack.top-consumeR -> 7
|
||||
mw.visitFieldInsn(GETFIELD,
|
||||
"factor/FactorArrayStack", "top",
|
||||
"I");
|
||||
if(consumeR != 0)
|
||||
{
|
||||
mw.visitIntInsn(BIPUSH,consumeR);
|
||||
mw.visitInsn(ISUB);
|
||||
}
|
||||
mw.visitVarInsn(ISTORE,7);
|
||||
// callstack.stack -> 8
|
||||
mw.visitFieldInsn(GETFIELD,
|
||||
"factor/FactorArrayStack", "stack",
|
||||
"[Ljava/lang/Object;");
|
||||
mw.visitVarInsn(ASTORE,8);
|
||||
}
|
||||
|
||||
int locals = 9;
|
||||
|
||||
if(shuffleD != null)
|
||||
{
|
||||
for(int i = shuffleDstart; i < shuffleDlength; i++)
|
||||
{
|
||||
// stack[top-consumeD+shuffleD[i]] -> 9+i
|
||||
int index = shuffleD[i];
|
||||
if((index & FROM_R_MASK) == FROM_R_MASK)
|
||||
{
|
||||
mw.visitVarInsn(ALOAD,8);
|
||||
mw.visitVarInsn(ILOAD,7);
|
||||
index &= ~FROM_R_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
mw.visitVarInsn(ALOAD,5);
|
||||
mw.visitVarInsn(ILOAD,4);
|
||||
}
|
||||
|
||||
if(index != 0)
|
||||
{
|
||||
mw.visitIntInsn(BIPUSH,index);
|
||||
mw.visitInsn(IADD);
|
||||
}
|
||||
|
||||
mw.visitInsn(AALOAD);
|
||||
mw.visitVarInsn(ASTORE,9 + i);
|
||||
}
|
||||
|
||||
locals += shuffleDlength;
|
||||
}
|
||||
|
||||
if(shuffleR != null)
|
||||
{
|
||||
for(int i = shuffleRstart; i < shuffleRlength; i++)
|
||||
{
|
||||
// stack[top-consumeR+shuffleR[i]] -> 9+i
|
||||
int index = shuffleR[i];
|
||||
if((index & FROM_R_MASK) == FROM_R_MASK)
|
||||
{
|
||||
mw.visitVarInsn(ALOAD,8);
|
||||
mw.visitVarInsn(ILOAD,7);
|
||||
index &= ~FROM_R_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
mw.visitVarInsn(ALOAD,5);
|
||||
mw.visitVarInsn(ILOAD,4);
|
||||
}
|
||||
|
||||
if(index != 0)
|
||||
{
|
||||
mw.visitIntInsn(BIPUSH,index);
|
||||
mw.visitInsn(IADD);
|
||||
}
|
||||
|
||||
mw.visitInsn(AALOAD);
|
||||
mw.visitVarInsn(ASTORE,locals + i);
|
||||
}
|
||||
}
|
||||
|
||||
if(shuffleD != null)
|
||||
{
|
||||
// ensure that the stack array has enough space.
|
||||
mw.visitVarInsn(ALOAD,3);
|
||||
mw.visitInsn(DUP);
|
||||
mw.visitIntInsn(BIPUSH,shuffleDlength);
|
||||
mw.visitMethodInsn(INVOKEVIRTUAL,
|
||||
"factor/FactorArrayStack", "ensurePush", "(I)V");
|
||||
// the datastack.stack array might have changed.
|
||||
// reload it.
|
||||
mw.visitFieldInsn(GETFIELD,
|
||||
"factor/FactorArrayStack", "stack",
|
||||
"[Ljava/lang/Object;");
|
||||
mw.visitVarInsn(ASTORE,5);
|
||||
|
||||
for(int i = shuffleDstart; i < shuffleDlength; i++)
|
||||
{
|
||||
// stack[top - consumeD + i] <- 9+i
|
||||
mw.visitVarInsn(ALOAD,5);
|
||||
mw.visitVarInsn(ILOAD,4);
|
||||
if(i != 0)
|
||||
{
|
||||
mw.visitIntInsn(BIPUSH,i);
|
||||
mw.visitInsn(IADD);
|
||||
}
|
||||
mw.visitVarInsn(ALOAD,9 + i);
|
||||
mw.visitInsn(AASTORE);
|
||||
}
|
||||
|
||||
// increment the 'top' field.
|
||||
mw.visitVarInsn(ALOAD,3);
|
||||
mw.visitVarInsn(ILOAD,4);
|
||||
mw.visitIntInsn(BIPUSH,shuffleDlength);
|
||||
mw.visitInsn(IADD);
|
||||
mw.visitFieldInsn(PUTFIELD,
|
||||
"factor/FactorArrayStack", "top",
|
||||
"I");
|
||||
}
|
||||
else if(consumeD != 0)
|
||||
{
|
||||
mw.visitVarInsn(ALOAD,3);
|
||||
mw.visitVarInsn(ILOAD,4);
|
||||
mw.visitFieldInsn(PUTFIELD,
|
||||
"factor/FactorArrayStack", "top",
|
||||
"I");
|
||||
}
|
||||
|
||||
if(shuffleR != null)
|
||||
{
|
||||
// ensure that the stack array has enough space.
|
||||
mw.visitVarInsn(ALOAD,6);
|
||||
mw.visitInsn(DUP);
|
||||
mw.visitIntInsn(BIPUSH,shuffleDlength);
|
||||
mw.visitMethodInsn(INVOKEVIRTUAL,
|
||||
"factor/FactorArrayStack", "ensurePush", "(I)V");
|
||||
// the callstack.stack array might have changed.
|
||||
// reload it.
|
||||
mw.visitFieldInsn(GETFIELD,
|
||||
"factor/FactorArrayStack", "stack",
|
||||
"[Ljava/lang/Object;");
|
||||
mw.visitVarInsn(ASTORE,8);
|
||||
|
||||
for(int i = shuffleRstart; i < shuffleRlength; i++)
|
||||
{
|
||||
// stack[top - consumeD + i] <- locals+i
|
||||
mw.visitVarInsn(ALOAD,8);
|
||||
mw.visitVarInsn(ILOAD,7);
|
||||
if(i != 0)
|
||||
{
|
||||
mw.visitIntInsn(BIPUSH,i);
|
||||
mw.visitInsn(IADD);
|
||||
}
|
||||
mw.visitVarInsn(ALOAD,locals + i);
|
||||
mw.visitInsn(AASTORE);
|
||||
}
|
||||
|
||||
// increment the 'top' field.
|
||||
mw.visitVarInsn(ALOAD,6);
|
||||
mw.visitVarInsn(ILOAD,7);
|
||||
mw.visitIntInsn(BIPUSH,shuffleRlength);
|
||||
mw.visitInsn(IADD);
|
||||
mw.visitFieldInsn(PUTFIELD,
|
||||
"factor/FactorArrayStack", "top",
|
||||
"I");
|
||||
}
|
||||
else if(consumeR != 0)
|
||||
{
|
||||
mw.visitVarInsn(ALOAD,6);
|
||||
mw.visitVarInsn(ILOAD,7);
|
||||
mw.visitFieldInsn(PUTFIELD,
|
||||
"factor/FactorArrayStack", "top",
|
||||
"I");
|
||||
}
|
||||
|
||||
mw.visitInsn(RETURN);
|
||||
|
||||
// Max stack and locals
|
||||
mw.visitMaxs(4,9 + shuffleDlength + shuffleRlength);
|
||||
|
||||
return true;
|
||||
//{{{ compileCallTo() method
|
||||
/**
|
||||
* Compile a call to this word. Returns maximum JVM stack use.
|
||||
*/
|
||||
public int compileCallTo(CodeVisitor mw, LocalAllocator allocator,
|
||||
Set recursiveCheck) throws FactorStackException
|
||||
{
|
||||
eval(allocator.datastack,allocator.callstack);
|
||||
return 0;
|
||||
} //}}}
|
||||
|
||||
//{{{ eval() method
|
||||
public void eval(FactorWord word, FactorInterpreter interp)
|
||||
public void eval(FactorInterpreter interp)
|
||||
throws FactorStackException
|
||||
{
|
||||
FactorArrayStack datastack = interp.datastack;
|
||||
FactorArrayStack callstack = interp.callstack;
|
||||
eval(interp.datastack,interp.callstack);
|
||||
} //}}}
|
||||
|
||||
//{{{ eval() method
|
||||
public void eval(FactorArrayStack datastack, FactorArrayStack callstack)
|
||||
throws FactorStackException
|
||||
{
|
||||
if(datastack.top < consumeD)
|
||||
throw new FactorStackException(consumeD);
|
||||
|
||||
|
@ -398,10 +158,16 @@ public class FactorShuffleDefinition extends FactorWordDefinition
|
|||
throw new FactorStackException(consumeR);
|
||||
|
||||
if(shuffleD != null)
|
||||
shuffle(interp,datastack,consumeD,consumeR,shuffleD,temporaryD);
|
||||
{
|
||||
shuffle(datastack,callstack,datastack,consumeD,consumeR,
|
||||
shuffleD,temporaryD);
|
||||
}
|
||||
|
||||
if(shuffleR != null)
|
||||
shuffle(interp,callstack,consumeD,consumeR,shuffleR,temporaryR);
|
||||
{
|
||||
shuffle(datastack,callstack,callstack,consumeD,consumeR,
|
||||
shuffleR,temporaryR);
|
||||
}
|
||||
|
||||
datastack.top -= consumeD;
|
||||
if(temporaryD != null)
|
||||
|
@ -414,8 +180,14 @@ public class FactorShuffleDefinition extends FactorWordDefinition
|
|||
} //}}}
|
||||
|
||||
//{{{ shuffle() method
|
||||
private void shuffle(FactorInterpreter interp, FactorArrayStack stack,
|
||||
int consumeD, int consumeR, int[] shuffle, Object[] temporary)
|
||||
private void shuffle(
|
||||
FactorArrayStack datastack,
|
||||
FactorArrayStack callstack,
|
||||
FactorArrayStack stack,
|
||||
int consumeD,
|
||||
int consumeR,
|
||||
int[] shuffle,
|
||||
Object[] temporary)
|
||||
throws FactorStackException
|
||||
{
|
||||
for(int i = 0; i < temporary.length; i++)
|
||||
|
@ -426,15 +198,15 @@ public class FactorShuffleDefinition extends FactorWordDefinition
|
|||
int consume;
|
||||
if((index & FROM_R_MASK) == FROM_R_MASK)
|
||||
{
|
||||
array = interp.callstack.stack;
|
||||
top = interp.callstack.top;
|
||||
array = callstack.stack;
|
||||
top = callstack.top;
|
||||
index = (index & ~FROM_R_MASK);
|
||||
consume = consumeR;
|
||||
}
|
||||
else
|
||||
{
|
||||
array = interp.datastack.stack;
|
||||
top = interp.datastack.top;
|
||||
array = datastack.stack;
|
||||
top = datastack.top;
|
||||
consume = consumeD;
|
||||
}
|
||||
temporary[i] = array[top - consume + index];
|
||||
|
|
|
@ -29,8 +29,8 @@
|
|||
|
||||
package factor;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import factor.compiler.FactorCompilerException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* An internalized symbol.
|
||||
|
@ -44,10 +44,20 @@ public class FactorWord implements FactorExternalizable
|
|||
*/
|
||||
public FactorWordDefinition def;
|
||||
|
||||
/**
|
||||
* Definition before compiling.
|
||||
*/
|
||||
public FactorWordDefinition uncompiled;
|
||||
|
||||
/**
|
||||
* "define" pushes previous definitions onto this list, like a stack.
|
||||
*/
|
||||
public FactorList history;
|
||||
public Cons history;
|
||||
|
||||
/**
|
||||
* Is this word referenced from a compiled word?
|
||||
*/
|
||||
public boolean compileRef;
|
||||
|
||||
//{{{ FactorWord constructor
|
||||
/**
|
||||
|
@ -58,7 +68,64 @@ public class FactorWord implements FactorExternalizable
|
|||
public FactorWord(String name)
|
||||
{
|
||||
this.name = name;
|
||||
def = FactorMissingDefinition.INSTANCE;
|
||||
def = new FactorMissingDefinition(this);
|
||||
} //}}}
|
||||
|
||||
//{{{ define() method
|
||||
public void define(FactorWordDefinition def)
|
||||
{
|
||||
if(compileRef)
|
||||
{
|
||||
System.err.println("WARNING: " + this
|
||||
+ " is used in one or more compiled words; old definition will remain until full recompile");
|
||||
}
|
||||
else if(!(this.def instanceof FactorMissingDefinition))
|
||||
{
|
||||
System.err.println("WARNING: redefining " + this);
|
||||
history = new Cons(this.def,history);
|
||||
}
|
||||
|
||||
uncompiled = this.def = def;
|
||||
} //}}}
|
||||
|
||||
//{{{ compile() method
|
||||
public void compile(FactorInterpreter interp)
|
||||
{
|
||||
compile(interp,new HashSet());
|
||||
} //}}}
|
||||
|
||||
//{{{ compile() method
|
||||
public void compile(FactorInterpreter interp, Set recursiveCheck)
|
||||
{
|
||||
if(def.compileFailed)
|
||||
return;
|
||||
|
||||
System.err.println("Compiling " + this);
|
||||
if(recursiveCheck.contains(this))
|
||||
System.err.println("WARNING: cannot compile recursive calls: " + this);
|
||||
|
||||
try
|
||||
{
|
||||
recursiveCheck.add(this);
|
||||
|
||||
def = def.compile(interp,recursiveCheck);
|
||||
}
|
||||
catch(FactorCompilerException e)
|
||||
{
|
||||
def.compileFailed = true;
|
||||
System.err.println("WARNING: cannot compile " + this);
|
||||
System.err.println(e.getMessage());
|
||||
}
|
||||
catch(Throwable t)
|
||||
{
|
||||
def.compileFailed = true;
|
||||
System.err.println("WARNING: cannot compile " + this);
|
||||
t.printStackTrace();
|
||||
}
|
||||
finally
|
||||
{
|
||||
recursiveCheck.remove(this);
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ toString() method
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2003 Slava Pestov.
|
||||
* Copyright (C) 2003, 2004 Slava Pestov.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
|
@ -29,10 +29,10 @@
|
|||
|
||||
package factor;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.util.Iterator;
|
||||
import factor.compiler.*;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import org.objectweb.asm.*;
|
||||
import org.objectweb.asm.util.*;
|
||||
|
||||
/**
|
||||
* A word definition.
|
||||
|
@ -40,152 +40,89 @@ import org.objectweb.asm.util.*;
|
|||
public abstract class FactorWordDefinition implements FactorObject, Constants
|
||||
{
|
||||
private FactorNamespace namespace;
|
||||
protected FactorWord word;
|
||||
|
||||
/**
|
||||
* Number of times this word has been referenced from a
|
||||
* compound word (incremented by the precompiler).
|
||||
*/
|
||||
public int references;
|
||||
public boolean compileFailed;
|
||||
|
||||
public abstract void eval(FactorWord word, FactorInterpreter interp)
|
||||
public FactorWordDefinition(FactorWord word)
|
||||
{
|
||||
this.word = word;
|
||||
}
|
||||
|
||||
public abstract void eval(FactorInterpreter interp)
|
||||
throws Exception;
|
||||
|
||||
void precompile(FactorWord word, FactorInterpreter interp)
|
||||
throws Exception {}
|
||||
|
||||
//{{{ getNamespace() method
|
||||
public FactorNamespace getNamespace(FactorInterpreter interp) throws Exception
|
||||
{
|
||||
if(namespace == null)
|
||||
namespace = new FactorNamespace(interp.global,this);
|
||||
|
||||
return namespace;
|
||||
}
|
||||
|
||||
//{{{ canCompile() method
|
||||
boolean canCompile()
|
||||
{
|
||||
return false;
|
||||
} //}}}
|
||||
|
||||
private static int compileCount;
|
||||
|
||||
//{{{ compile() method
|
||||
/**
|
||||
* Compile the given word, returning a new word definition.
|
||||
*/
|
||||
FactorWordDefinition compile(FactorWord word, FactorInterpreter interp)
|
||||
throws Exception
|
||||
//{{{ getStackEffect() method
|
||||
public final StackEffect getStackEffect() throws Exception
|
||||
{
|
||||
if(!canCompile())
|
||||
return this;
|
||||
return getStackEffect(new HashSet(),new LocalAllocator());
|
||||
} //}}}
|
||||
|
||||
//System.out.println("Compiling " + word);
|
||||
|
||||
StringBuffer sanitizedName = new StringBuffer();
|
||||
for(int i = 0; i < word.name.length(); i++)
|
||||
{
|
||||
char ch = word.name.charAt(i);
|
||||
if(!Character.isJavaIdentifierStart(ch))
|
||||
sanitizedName.append("_");
|
||||
else
|
||||
sanitizedName.append(ch);
|
||||
}
|
||||
String className = "factor/__compiler__/" + sanitizedName
|
||||
+ "_" + (compileCount++);
|
||||
|
||||
ClassWriter cw = new ClassWriter(false);
|
||||
cw.visit(ACC_PUBLIC, className,
|
||||
"factor/FactorWordDefinition", null, null);
|
||||
|
||||
// creates a MethodWriter for the (implicit) constructor
|
||||
CodeVisitor mw = cw.visitMethod(ACC_PUBLIC,
|
||||
"<init>", "()V", null, null);
|
||||
// pushes the 'this' variable
|
||||
mw.visitVarInsn(ALOAD, 0);
|
||||
// invokes the super class constructor
|
||||
mw.visitMethodInsn(INVOKESPECIAL,
|
||||
"factor/FactorWordDefinition", "<init>", "()V");
|
||||
mw.visitInsn(RETURN);
|
||||
// this code uses a maximum of one stack element and one local
|
||||
// variable
|
||||
mw.visitMaxs(1, 1);
|
||||
|
||||
// creates a MethodWriter for the 'toString' method
|
||||
mw = cw.visitMethod(ACC_PUBLIC,
|
||||
"toString", "()Ljava/lang/String;", null, null);
|
||||
mw.visitLdcInsn("( compiled ) " + toString());
|
||||
mw.visitInsn(ARETURN);
|
||||
mw.visitMaxs(1, 1);
|
||||
|
||||
// pushes the 'this' variable
|
||||
mw.visitVarInsn(ALOAD, 0);
|
||||
// invokes the super class constructor
|
||||
mw.visitMethodInsn(INVOKESPECIAL,
|
||||
"factor/FactorWordDefinition", "<init>", "()V");
|
||||
mw.visitInsn(RETURN);
|
||||
// this code uses a maximum of one stack element and one local
|
||||
// variable
|
||||
mw.visitMaxs(1, 1);
|
||||
|
||||
// creates a MethodWriter for the 'eval' method
|
||||
mw = cw.visitMethod(ACC_PUBLIC,
|
||||
"eval", "(Lfactor/FactorWord;Lfactor/FactorInterpreter;)V",
|
||||
null, null);
|
||||
|
||||
// We store a string with disassembly for debugging
|
||||
// purposes.
|
||||
TraceCodeVisitor disasm = new TraceCodeVisitor(mw);
|
||||
if(!compile(word,interp,cw,disasm))
|
||||
return this;
|
||||
|
||||
// Save the disassembly
|
||||
StringBuffer buf = new StringBuffer();
|
||||
Iterator bytecodes = disasm.getText().iterator();
|
||||
while(bytecodes.hasNext())
|
||||
{
|
||||
buf.append(bytecodes.next());
|
||||
}
|
||||
|
||||
// gets the bytecode of the class, and loads it dynamically
|
||||
byte[] code = cw.toByteArray();
|
||||
|
||||
/* FileOutputStream fos = new FileOutputStream(className + ".class");
|
||||
fos.write(code);
|
||||
fos.close(); */
|
||||
|
||||
SimpleClassLoader loader = new SimpleClassLoader();
|
||||
Class compiledWordClass = loader._defineClass(className,
|
||||
code, 0, code.length);
|
||||
|
||||
FactorWordDefinition compiledWord = (FactorWordDefinition)
|
||||
compiledWordClass.newInstance();
|
||||
|
||||
compiledWord.getNamespace(interp).setVariable("asm",buf.toString());
|
||||
|
||||
return compiledWord;
|
||||
//{{{ getStackEffect() method
|
||||
public StackEffect getStackEffect(Set recursiveCheck,
|
||||
LocalAllocator state) throws Exception
|
||||
{
|
||||
return null;
|
||||
} //}}}
|
||||
|
||||
//{{{ compile() method
|
||||
/**
|
||||
* Write the definition of the eval() method in the compiled word.
|
||||
* Local 0 -- this
|
||||
* Local 1 -- word
|
||||
* Local 2 -- interpreter
|
||||
*/
|
||||
boolean compile(FactorWord word, FactorInterpreter interp,
|
||||
ClassWriter cw, CodeVisitor mw)
|
||||
throws Exception
|
||||
FactorWordDefinition compile(FactorInterpreter interp,
|
||||
Set recursiveCheck) throws Exception
|
||||
{
|
||||
throw new FactorRuntimeException("Don't know how to compile " + word);
|
||||
return this;
|
||||
} //}}}
|
||||
|
||||
//{{{ SimpleClassLoader class
|
||||
static class SimpleClassLoader extends ClassLoader
|
||||
//{{{ compileCallTo() method
|
||||
/**
|
||||
* Compile a call to this word. Returns maximum JVM stack use.
|
||||
*/
|
||||
public int compileCallTo(CodeVisitor mw, LocalAllocator allocator,
|
||||
Set recursiveCheck) throws Exception
|
||||
{
|
||||
public Class _defineClass(String name,
|
||||
byte[] code, int off, int len)
|
||||
StackEffect effect = getStackEffect();
|
||||
if(effect == null)
|
||||
{
|
||||
return defineClass(name,code,off,len);
|
||||
// combinator; inline
|
||||
return compileImmediate(mw,allocator,recursiveCheck);
|
||||
}
|
||||
else
|
||||
{
|
||||
// normal word
|
||||
mw.visitVarInsn(ALOAD,0);
|
||||
|
||||
allocator.generateArgs(mw,effect.inD,null);
|
||||
|
||||
String defclass = getClass().getName().replace('.','/');
|
||||
|
||||
String signature = effect.getCorePrototype();
|
||||
|
||||
mw.visitMethodInsn(INVOKESTATIC,defclass,"core",signature);
|
||||
|
||||
if(effect.outD > 1)
|
||||
throw new FactorCompilerException("Cannot compile word with non-0/1-out factors");
|
||||
if(effect.outD == 1)
|
||||
allocator.push(mw);
|
||||
|
||||
return effect.inD + 1;
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ compileImmediate() method
|
||||
/**
|
||||
* Compile a call to this word. Returns maximum JVM stack use.
|
||||
*/
|
||||
public int compileImmediate(CodeVisitor mw, LocalAllocator allocator,
|
||||
Set recursiveCheck) throws Exception
|
||||
{
|
||||
throw new FactorCompilerException("Cannot compile " + word + " in immediate mode");
|
||||
} //}}}
|
||||
}
|
||||
|
|
|
@ -28,28 +28,30 @@
|
|||
!!! The stack operators are defined using shuffle notation. This saves several
|
||||
!!! hundred lines of code!
|
||||
|
||||
~<< drop A -- >>~
|
||||
~<< 2drop A B -- >>~
|
||||
~<< dup A -- A A >>~
|
||||
~<< 2dup A B -- A B A B >>~
|
||||
~<< dupd A B -- A A B >>~
|
||||
~<< 2dupd A B C D -- A B A B C D >>~
|
||||
~<< nip A B -- B >>~
|
||||
~<< 2nip A B C D -- C D >>~
|
||||
~<< nop -- >>~ ! Does nothing!
|
||||
~<< over A B -- A B A >>~
|
||||
~<< 2over A B C D -- A B C D A B >>~
|
||||
~<< pick A B C -- A B C A >>~ ! Not the Forth pick!
|
||||
~<< rot A B C -- B C A >>~
|
||||
~<< 2rot A B C D E F -- C D E F A B >>~
|
||||
~<< -rot A B C -- C A B >>~
|
||||
~<< 2-rot A B C D E F -- E F A B C D >>~
|
||||
~<< swap A B -- B A >>~
|
||||
~<< 2swap A B C D -- C D A B >>~
|
||||
~<< swapd A B C -- B A C >>~
|
||||
~<< 2swapd A B C D E F -- C D A B E F >>~
|
||||
~<< tuck A B -- B A B >>~
|
||||
~<< 2tuck A B C D -- C D A B C D >>~
|
||||
~<< drop A -- >>~
|
||||
~<< 2drop A B -- >>~
|
||||
~<< dup A -- A A >>~
|
||||
~<< 2dup A B -- A B A B >>~
|
||||
~<< dupd A B -- A A B >>~
|
||||
~<< 2dupd A B C D -- A B A B C D >>~
|
||||
~<< nip A B -- B >>~
|
||||
~<< 2nip A B C D -- C D >>~
|
||||
~<< nop -- >>~ ! Does nothing!
|
||||
~<< over A B -- A B A >>~
|
||||
~<< 2over A B C D -- A B C D A B >>~
|
||||
~<< pick A B C -- A B C A >>~ ! Not the Forth pick!
|
||||
~<< rot A B C -- B C A >>~
|
||||
~<< 2rot A B C D E F -- C D E F A B >>~
|
||||
~<< -rot A B C -- C A B >>~
|
||||
~<< 2-rot A B C D E F -- E F A B C D >>~
|
||||
~<< swap A B -- B A >>~
|
||||
~<< 2swap A B C D -- C D A B >>~
|
||||
~<< swapd A B C -- B A C >>~
|
||||
~<< 2swapd A B C D E F -- C D A B E F >>~
|
||||
~<< transp A B C -- C B A >>~
|
||||
~<< 2transp A B C D E F -- E F C D A B >>~
|
||||
~<< tuck A B -- B A B >>~
|
||||
~<< 2tuck A B C D -- C D A B C D >>~
|
||||
|
||||
~<< rdrop r:A -- >>~
|
||||
~<< >r A -- r:A >>~
|
||||
|
@ -60,21 +62,21 @@
|
|||
!!! Minimum amount of I/O words needed to be able to read other resources.
|
||||
!!! Remaining I/O operations are defined in io.factor and parser.factor.
|
||||
: <breader> (reader -- breader)
|
||||
[ |java.io.Reader ] |java.io.BufferedReader jconstructor jnew ;
|
||||
[ |java.io.Reader ] |java.io.BufferedReader jnew ;
|
||||
|
||||
: <ireader> (inputstream -- breader)
|
||||
[ |java.io.InputStream ] |java.io.InputStreamReader jconstructor jnew ;
|
||||
[ |java.io.InputStream ] |java.io.InputStreamReader jnew ;
|
||||
|
||||
: <rreader> (path -- inputstream)
|
||||
|factor.FactorInterpreter
|
||||
[ |java.lang.String ] |java.lang.Class |getResourceAsStream jmethod jinvoke
|
||||
[ |java.lang.String ] |java.lang.Class |getResourceAsStream jinvoke
|
||||
<ireader> <breader> ;
|
||||
|
||||
: parse* (filename reader -- list)
|
||||
$dict
|
||||
[ |java.lang.String |java.io.Reader |factor.FactorDictionary ]
|
||||
|factor.FactorParser jconstructor jnew
|
||||
[ ] |factor.FactorParser |parse jmethod jinvoke ;
|
||||
|factor.FactorParser jnew
|
||||
[ ] |factor.FactorParser |parse jinvoke ;
|
||||
|
||||
: runResource (path --)
|
||||
dup <rreader> parse* call ;
|
||||
|
@ -98,5 +100,20 @@
|
|||
"/factor/stream.factor" runResource
|
||||
"/factor/strings.factor" runResource
|
||||
|
||||
: cli-param ( param -- )
|
||||
dup "no-" str-head? dup [
|
||||
f s@ drop
|
||||
] [
|
||||
drop t s@
|
||||
] ifte ;
|
||||
|
||||
: cli-arg ( argument -- boolean )
|
||||
"-" str-head? [ cli-param ] when* ;
|
||||
|
||||
$args [ cli-arg ] each
|
||||
|
||||
! Compile all words now
|
||||
$compile [ compileAll ] when
|
||||
|
||||
! If we're run stand-alone, start the interpreter in the current tty.
|
||||
$interactive [ initialInterpreterLoop ] when
|
||||
|
|
|
@ -90,18 +90,20 @@
|
|||
! [ [ condition 1 ] [ code 1 ]
|
||||
! [ condition 2 ] [ code 2 ]
|
||||
! ... ]
|
||||
! Each condition is evaluated in turn. If it returns true, the code
|
||||
! is evaluated. If it returns false, the next condition is checked.
|
||||
[
|
||||
uncons >r
|
||||
call
|
||||
r>
|
||||
swap [
|
||||
! Each condition is evaluated in turn. If it returns true,
|
||||
! the code is evaluated. If it returns false, the next
|
||||
! condition is checked. Before evaluating each condition,
|
||||
! the top of the stack is duplicated. After the last
|
||||
! condition is evaluated, the top of the stack is popped.
|
||||
dup [
|
||||
uncons [ over [ call ] dip ] dip rot [
|
||||
car call
|
||||
] [
|
||||
cdr cond
|
||||
] ifte
|
||||
] when* ;
|
||||
] [
|
||||
2drop
|
||||
] ifte ;
|
||||
|
||||
: dip (a [ b ] -- b a)
|
||||
! Calls b as if b was not even present on the stack -- b has no way of
|
||||
|
@ -122,14 +124,7 @@
|
|||
: each ([ list ] [ code ] --)
|
||||
! Applies the code to each element of the list.
|
||||
over [
|
||||
>r
|
||||
uncons
|
||||
r>
|
||||
tuck
|
||||
2>r
|
||||
call
|
||||
2r>
|
||||
each
|
||||
[ uncons ] dip tuck [ call ] 2dip each
|
||||
] [
|
||||
2drop
|
||||
] ifte ;
|
||||
|
@ -143,6 +138,9 @@
|
|||
call
|
||||
unstack ;
|
||||
|
||||
: ifte (cond [if true] [if false] --)
|
||||
? call ;
|
||||
|
||||
: interleave ( X list -- ... )
|
||||
! Evaluate each element of the list with X on top of the
|
||||
! stack.
|
||||
|
@ -152,9 +150,6 @@
|
|||
2drop
|
||||
] ifte ;
|
||||
|
||||
: ifte (cond [if true] [if false] --)
|
||||
? call ;
|
||||
|
||||
: linrec ( [ P ] [ T ] [ R1 ] [ R2 ] -- )
|
||||
! Evaluate P, if it pushes t, evaluate T. Otherwise, evaluate R1, recurse,
|
||||
! and evaluate R2. This combinator is similar to the linrec combinator in
|
||||
|
@ -168,13 +163,10 @@
|
|||
r> call
|
||||
] ifte ;
|
||||
|
||||
: map ([ items ] [ initial ] [ code ] -- [ mapping ])
|
||||
! Applies the code to each item, returns a list that begins with the initial
|
||||
! list and contains the result of each application.
|
||||
swapd 2list append
|
||||
restack
|
||||
each
|
||||
unstack ;
|
||||
: map ( [ items ] [ code ] -- [ mapping ] )
|
||||
! Applies the code to each item, returns a list that
|
||||
! contains the result of each application.
|
||||
2list restack each unstack ;
|
||||
|
||||
: push ([ a b c ... ] -- a b c ...)
|
||||
! Pushes values onto the stack literally (even if they are words).
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
/* :folding=explicit:collapseFolds=1: */
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2003, 2004 Slava Pestov.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package factor.compiler;
|
||||
|
||||
import factor.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.Set;
|
||||
import org.objectweb.asm.*;
|
||||
|
||||
/**
|
||||
* : name ... ;
|
||||
*/
|
||||
public abstract class CompiledDefinition
|
||||
extends FactorWordDefinition
|
||||
{
|
||||
private StackEffect effect;
|
||||
|
||||
//{{{ CompiledDefinition constructor
|
||||
public CompiledDefinition(FactorWord word, StackEffect effect)
|
||||
{
|
||||
super(word);
|
||||
this.effect = effect;
|
||||
} //}}}
|
||||
|
||||
//{{{ getStackEffect() method
|
||||
public StackEffect getStackEffect(Set recursiveCheck,
|
||||
LocalAllocator state)
|
||||
{
|
||||
return effect;
|
||||
} //}}}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/* :folding=explicit:collapseFolds=1: */
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2004 Slava Pestov.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package factor.compiler;
|
||||
|
||||
import factor.*;
|
||||
|
||||
public class FactorCompilerException extends FactorRuntimeException
|
||||
{
|
||||
public FactorCompilerException(String str)
|
||||
{
|
||||
super(str);
|
||||
}
|
||||
|
||||
public FactorCompilerException(String str, Throwable t)
|
||||
{
|
||||
super(str,t);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,677 @@
|
|||
/* :folding=explicit:collapseFolds=1: */
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2004 Slava Pestov.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package factor.compiler;
|
||||
|
||||
import factor.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.*;
|
||||
import org.objectweb.asm.*;
|
||||
|
||||
public class LocalAllocator implements Constants
|
||||
{
|
||||
private FactorInterpreter interp;
|
||||
|
||||
private String className;
|
||||
private int base;
|
||||
private int max;
|
||||
|
||||
public FactorDataStack datastack;
|
||||
public FactorCallStack callstack;
|
||||
|
||||
private int literalCount;
|
||||
private int wordCount;
|
||||
|
||||
private Map literals = new HashMap();
|
||||
private Map words = new HashMap();
|
||||
|
||||
//{{{ LocalAllocator constructor
|
||||
/**
|
||||
* For balancing.
|
||||
*/
|
||||
public LocalAllocator()
|
||||
{
|
||||
this(null,null,0,0);
|
||||
} //}}}
|
||||
|
||||
//{{{ LocalAllocator constructor
|
||||
/**
|
||||
* For compiling.
|
||||
*/
|
||||
public LocalAllocator(FactorInterpreter interp, String className,
|
||||
int base, int allot)
|
||||
{
|
||||
this.interp = interp;
|
||||
this.className = className;
|
||||
|
||||
this.base = base;
|
||||
datastack = new FactorDataStack();
|
||||
callstack = new FactorCallStack();
|
||||
|
||||
for(int i = 0; i < allot; i++)
|
||||
{
|
||||
datastack.push(new Result(base + i));
|
||||
}
|
||||
|
||||
max = base + allot;
|
||||
|
||||
} //}}}
|
||||
|
||||
//{{{ ensure() method
|
||||
/**
|
||||
* Ensure stack has at least 'count' elements.
|
||||
* Eg, if count is 4 and stack is A B,
|
||||
* stack will become RESULT RESULT A B.
|
||||
* Used when deducing stack effects.
|
||||
*/
|
||||
public void ensure(FactorArrayStack stack, int count)
|
||||
{
|
||||
int top = stack.top;
|
||||
if(top < count)
|
||||
{
|
||||
stack.ensurePush(count - top);
|
||||
System.arraycopy(stack.stack,0,stack.stack,
|
||||
count - top,top);
|
||||
for(int i = 0; i < count - top; i++)
|
||||
{
|
||||
stack.stack[i] = new Result(allocate());
|
||||
}
|
||||
stack.top = count;
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ compile() method
|
||||
/**
|
||||
* Compiles a quotation and returns the maximum JVM stack depth.
|
||||
*/
|
||||
public int compile(Cons definition, CodeVisitor mw,
|
||||
Set recursiveCheck) throws Exception
|
||||
{
|
||||
int maxJVMStack = 0;
|
||||
|
||||
while(definition != null)
|
||||
{
|
||||
Object obj = definition.car;
|
||||
if(obj instanceof FactorWord)
|
||||
{
|
||||
FactorWord w = (FactorWord)obj;
|
||||
|
||||
FactorWordDefinition d = w.def;
|
||||
if(d instanceof FactorCompoundDefinition
|
||||
&& d.getStackEffect(recursiveCheck,
|
||||
new LocalAllocator()) != null)
|
||||
{
|
||||
// compile first.
|
||||
w.compile(interp,recursiveCheck);
|
||||
if(w.def == d)
|
||||
{
|
||||
// didn't compile
|
||||
throw new FactorCompilerException(w + " cannot be compiled");
|
||||
}
|
||||
}
|
||||
|
||||
maxJVMStack = Math.max(maxJVMStack,
|
||||
w.def.compileCallTo(mw,this,recursiveCheck));
|
||||
}
|
||||
else if(obj == null)
|
||||
{
|
||||
pushNull();
|
||||
}
|
||||
else if(obj instanceof String)
|
||||
{
|
||||
pushString((String)obj);
|
||||
}
|
||||
else
|
||||
{
|
||||
pushLiteral(obj);
|
||||
}
|
||||
|
||||
definition = definition.next();
|
||||
}
|
||||
|
||||
return maxJVMStack;
|
||||
} //}}}
|
||||
|
||||
//{{{ push() method
|
||||
/**
|
||||
* Generates code for pushing the top of the JVM stack onto the
|
||||
* data stack.
|
||||
*/
|
||||
public void push(CodeVisitor mw)
|
||||
{
|
||||
int local = allocate();
|
||||
datastack.push(new Result(local));
|
||||
if(mw != null)
|
||||
mw.visitVarInsn(ASTORE,local);
|
||||
} //}}}
|
||||
|
||||
//{{{ pushR() method
|
||||
/**
|
||||
* Generates code for pushing the top of the JVM stack onto the
|
||||
* call stack.
|
||||
*/
|
||||
public void pushR(CodeVisitor mw)
|
||||
{
|
||||
int local = allocate();
|
||||
callstack.push(new Result(local));
|
||||
if(mw != null)
|
||||
mw.visitVarInsn(ASTORE,local);
|
||||
} //}}}
|
||||
|
||||
//{{{ pushLiteral() method
|
||||
public void pushLiteral(Object literal)
|
||||
{
|
||||
datastack.push(new Literal(literal));
|
||||
} //}}}
|
||||
|
||||
//{{{ pushString() method
|
||||
public void pushString(String literal)
|
||||
{
|
||||
datastack.push(new ConstantPoolString(literal));
|
||||
} //}}}
|
||||
|
||||
//{{{ pushNull() method
|
||||
public void pushNull()
|
||||
{
|
||||
datastack.push(new Null());
|
||||
} //}}}
|
||||
|
||||
//{{{ pushChoice() method
|
||||
public void pushChoice() throws FactorStackException
|
||||
{
|
||||
FlowObject f = (FlowObject)datastack.pop();
|
||||
FlowObject t = (FlowObject)datastack.pop();
|
||||
FlowObject cond = (FlowObject)datastack.pop();
|
||||
datastack.push(new Choice(cond,t,f));
|
||||
} //}}}
|
||||
|
||||
//{{{ pop() method
|
||||
/**
|
||||
* Generates code for popping the top of the data stack onto
|
||||
* the JVM stack.
|
||||
*/
|
||||
public void pop(CodeVisitor mw) throws FactorStackException
|
||||
{
|
||||
FlowObject obj = (FlowObject)datastack.pop();
|
||||
if(mw != null)
|
||||
obj.generate(mw);
|
||||
} //}}}
|
||||
|
||||
//{{{ popR() method
|
||||
/**
|
||||
* Generates code for popping the top of the call stack onto
|
||||
* the JVM stack.
|
||||
*/
|
||||
public void popR(CodeVisitor mw) throws FactorStackException
|
||||
{
|
||||
FlowObject obj = (FlowObject)callstack.pop();
|
||||
if(mw != null)
|
||||
obj.generate(mw);
|
||||
} //}}}
|
||||
|
||||
//{{{ popLiteral() method
|
||||
/**
|
||||
* Pops a literal off the datastack or throws an exception.
|
||||
*/
|
||||
public Object popLiteral() throws FactorException
|
||||
{
|
||||
FlowObject obj = (FlowObject)datastack.pop();
|
||||
return obj.getLiteral();
|
||||
} //}}}
|
||||
|
||||
//{{{ allocate() method
|
||||
/**
|
||||
* Allocate a local variable.
|
||||
*/
|
||||
private int allocate()
|
||||
{
|
||||
// inefficient!
|
||||
int limit = base + datastack.top + callstack.top;
|
||||
for(int i = base; i <= limit; i++)
|
||||
{
|
||||
if(allocate(i,datastack) && allocate(i,callstack))
|
||||
{
|
||||
max = Math.max(max,i + 1);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
// this is impossible
|
||||
throw new RuntimeException("allocator failed");
|
||||
} //}}}
|
||||
|
||||
//{{{ allocate() method
|
||||
/**
|
||||
* Return true if not in use, false if in use.
|
||||
*/
|
||||
private boolean allocate(int local, FactorArrayStack stack)
|
||||
{
|
||||
for(int i = 0; i < stack.top; i++)
|
||||
{
|
||||
FlowObject obj = (FlowObject)stack.stack[i];
|
||||
if(obj.usingLocal(local))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} //}}}
|
||||
|
||||
//{{{ maxLocals() method
|
||||
public int maxLocals()
|
||||
{
|
||||
return max;
|
||||
} //}}}
|
||||
|
||||
//{{{ literal() method
|
||||
private String literal(Object obj)
|
||||
{
|
||||
Integer i = (Integer)literals.get(obj);
|
||||
int literal;
|
||||
if(i == null)
|
||||
{
|
||||
literal = literalCount++;
|
||||
literals.put(obj,new Integer(literal));
|
||||
}
|
||||
else
|
||||
literal = i.intValue();
|
||||
|
||||
return "literal_" + literal;
|
||||
} //}}}
|
||||
|
||||
//{{{ generateArgs() method
|
||||
/**
|
||||
* Generate instructions for copying arguments from the allocated
|
||||
* local variables to the JVM stack, doing type conversion in the
|
||||
* process.
|
||||
*/
|
||||
public void generateArgs(CodeVisitor mw, int num, Class[] args)
|
||||
throws Exception
|
||||
{
|
||||
for(int i = 0; i < num; i++)
|
||||
{
|
||||
FlowObject obj = (FlowObject)datastack.stack[
|
||||
datastack.top - num + i];
|
||||
obj.generate(mw);
|
||||
if(args != null)
|
||||
FactorJava.generateFromConversion(mw,args[i]);
|
||||
}
|
||||
|
||||
datastack.top -= num;
|
||||
} //}}}
|
||||
|
||||
//{{{ generateFields() method
|
||||
public void generateFields(ClassWriter cw)
|
||||
throws Exception
|
||||
{
|
||||
for(int i = 0; i < literalCount; i++)
|
||||
{
|
||||
cw.visitField(ACC_PUBLIC | ACC_STATIC,"literal_" + i,
|
||||
"Ljava/lang/Object;",null,null);
|
||||
}
|
||||
|
||||
Iterator entries = words.entrySet().iterator();
|
||||
while(entries.hasNext())
|
||||
{
|
||||
Map.Entry entry = (Map.Entry)entries.next();
|
||||
FactorWord word = (FactorWord)entry.getKey();
|
||||
int index = ((Integer)entry.getValue()).intValue();
|
||||
|
||||
cw.visitField(ACC_PUBLIC | ACC_STATIC,"word_" + index,
|
||||
FactorJava.javaClassToVMClass(word.def.getClass()),
|
||||
null,null);
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ setFields() method
|
||||
public void setFields(Class def)
|
||||
throws Exception
|
||||
{
|
||||
Iterator entries = literals.entrySet().iterator();
|
||||
while(entries.hasNext())
|
||||
{
|
||||
Map.Entry entry = (Map.Entry)entries.next();
|
||||
Object literal = entry.getKey();
|
||||
int index = ((Integer)entry.getValue()).intValue();
|
||||
|
||||
Field f = def.getField("literal_" + index);
|
||||
f.set(null,literal);
|
||||
}
|
||||
|
||||
entries = words.entrySet().iterator();
|
||||
while(entries.hasNext())
|
||||
{
|
||||
Map.Entry entry = (Map.Entry)entries.next();
|
||||
FactorWord word = (FactorWord)entry.getKey();
|
||||
int index = ((Integer)entry.getValue()).intValue();
|
||||
|
||||
Field f = def.getField("word_" + index);
|
||||
System.err.println(word.def.getClass() + " ==> " + "word_" + index);
|
||||
f.set(null,word.def);
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ FlowObject
|
||||
public abstract class FlowObject
|
||||
{
|
||||
abstract void generate(CodeVisitor mw);
|
||||
|
||||
boolean usingLocal(int local)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Object getLiteral()
|
||||
throws FactorCompilerException
|
||||
{
|
||||
throw new FactorCompilerException("Cannot compile unless literal on stack");
|
||||
}
|
||||
|
||||
/**
|
||||
* Stack effect of evaluating this -- only used for lists
|
||||
* and conditionals!
|
||||
*/
|
||||
public StackEffect getStackEffect(Set recursiveCheck)
|
||||
throws Exception
|
||||
{
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write code for evaluating this. Returns maximum JVM stack
|
||||
* usage.
|
||||
*/
|
||||
public int compileCallTo(CodeVisitor mw, Set recursiveCheck)
|
||||
throws Exception
|
||||
{
|
||||
throw new FactorCompilerException("Cannot compile call to non-literal quotation");
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ Result
|
||||
class Result extends FlowObject
|
||||
{
|
||||
private int local;
|
||||
|
||||
Result(int local)
|
||||
{
|
||||
this.local = local;
|
||||
}
|
||||
|
||||
void generate(CodeVisitor mw)
|
||||
{
|
||||
mw.visitVarInsn(ALOAD,local);
|
||||
}
|
||||
|
||||
boolean usingLocal(int local)
|
||||
{
|
||||
return (this.local == local);
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ Literal
|
||||
class Literal extends FlowObject
|
||||
{
|
||||
private Object literal;
|
||||
|
||||
Literal(Object literal)
|
||||
{
|
||||
this.literal = literal;
|
||||
}
|
||||
|
||||
void generate(CodeVisitor mw)
|
||||
{
|
||||
mw.visitFieldInsn(GETSTATIC,className,
|
||||
literal(literal),"Ljava/lang/Object;");
|
||||
}
|
||||
|
||||
Object getLiteral()
|
||||
{
|
||||
return literal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stack effect of executing this -- only used for lists
|
||||
* and conditionals!
|
||||
*/
|
||||
public StackEffect getStackEffect(Set recursiveCheck)
|
||||
throws Exception
|
||||
{
|
||||
if(literal instanceof Cons
|
||||
|| literal == null)
|
||||
{
|
||||
return StackEffect.getStackEffect(
|
||||
(Cons)literal,recursiveCheck,
|
||||
LocalAllocator.this);
|
||||
}
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write code for evaluating this. Returns maximum JVM stack
|
||||
* usage.
|
||||
*/
|
||||
public int compileCallTo(CodeVisitor mw, Set recursiveCheck)
|
||||
throws Exception
|
||||
{
|
||||
if(literal instanceof Cons || literal == null)
|
||||
return compile((Cons)literal,mw,recursiveCheck);
|
||||
else
|
||||
throw new FactorCompilerException("Not a quotation: " + literal);
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ ConstantPoolString
|
||||
class ConstantPoolString extends FlowObject
|
||||
{
|
||||
private String str;
|
||||
|
||||
ConstantPoolString(String str)
|
||||
{
|
||||
this.str = str;
|
||||
}
|
||||
|
||||
void generate(CodeVisitor mw)
|
||||
{
|
||||
mw.visitLdcInsn(str);
|
||||
}
|
||||
|
||||
Object getLiteral()
|
||||
{
|
||||
return str;
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ Null
|
||||
class Null extends FlowObject
|
||||
{
|
||||
void generate(CodeVisitor mw)
|
||||
{
|
||||
mw.visitInsn(ACONST_NULL);
|
||||
}
|
||||
|
||||
Object getLiteral()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stack effect of executing this -- only used for lists
|
||||
* and conditionals!
|
||||
*/
|
||||
public StackEffect getStackEffect(Set recursiveCheck)
|
||||
{
|
||||
return new StackEffect(0,0,0,0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write code for evaluating this. Returns maximum JVM stack
|
||||
* usage.
|
||||
*/
|
||||
public int compileCallTo(CodeVisitor mw, Set recursiveCheck)
|
||||
throws Exception
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
} //}}}
|
||||
|
||||
//{{{ Choice
|
||||
class Choice extends FlowObject
|
||||
{
|
||||
FlowObject cond, t, f;
|
||||
|
||||
Choice(FlowObject cond, FlowObject t, FlowObject f)
|
||||
{
|
||||
this.cond = cond;
|
||||
this.t = t;
|
||||
this.f = f;
|
||||
}
|
||||
|
||||
void generate(CodeVisitor mw)
|
||||
{
|
||||
// if null jump to F
|
||||
// T
|
||||
// jump END
|
||||
// F: F
|
||||
// END: ...
|
||||
Label fl = new Label();
|
||||
Label endl = new Label();
|
||||
|
||||
cond.generate(mw);
|
||||
mw.visitJumpInsn(IFNULL,fl);
|
||||
t.generate(mw);
|
||||
mw.visitJumpInsn(GOTO,endl);
|
||||
mw.visitLabel(fl);
|
||||
f.generate(mw);
|
||||
mw.visitLabel(endl);
|
||||
}
|
||||
|
||||
boolean usingLocal(int local)
|
||||
{
|
||||
return cond.usingLocal(local)
|
||||
|| t.usingLocal(local)
|
||||
|| f.usingLocal(local);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stack effect of executing this -- only used for lists
|
||||
* and conditionals!
|
||||
*/
|
||||
public StackEffect getStackEffect(Set recursiveCheck)
|
||||
throws Exception
|
||||
{
|
||||
FactorDataStack datastackCopy = (FactorDataStack)
|
||||
datastack.clone();
|
||||
FactorCallStack callstackCopy = (FactorCallStack)
|
||||
callstack.clone();
|
||||
|
||||
StackEffect te = t.getStackEffect(recursiveCheck);
|
||||
|
||||
datastack = datastackCopy;
|
||||
callstack = callstackCopy;
|
||||
|
||||
StackEffect fe = f.getStackEffect(recursiveCheck);
|
||||
|
||||
if(te == null || fe == null)
|
||||
return null;
|
||||
|
||||
// we can only balance out a conditional if
|
||||
// both sides leave the same amount of elements
|
||||
// on the stack.
|
||||
// eg, 1/1 -vs- 2/2 is ok, 3/1 -vs- 4/2 is ok,
|
||||
// but 1/2 -vs- 2/1 is not.
|
||||
int balanceTD = te.outD - te.inD;
|
||||
int balanceTR = te.outR - te.inR;
|
||||
int balanceFD = fe.outD - fe.inD;
|
||||
int balanceFR = fe.outR - fe.inR;
|
||||
if(balanceTD == balanceFD
|
||||
&& balanceTR == balanceFR)
|
||||
{
|
||||
// replace results from the f branch with
|
||||
// dummy values so that subsequent code
|
||||
// doesn't assume these values always
|
||||
// result from this
|
||||
datastack.top -= te.outD;
|
||||
for(int i = 0; i < te.outD; i++)
|
||||
{
|
||||
push(null);
|
||||
}
|
||||
callstack.top -= te.outR;
|
||||
for(int i = 0; i < te.outR; i++)
|
||||
{
|
||||
pushR(null);
|
||||
}
|
||||
return new StackEffect(
|
||||
Math.max(te.inD,fe.inD),
|
||||
Math.max(te.outD,fe.outD),
|
||||
Math.max(te.inR,fe.inR),
|
||||
Math.max(te.outR,fe.outR)
|
||||
);
|
||||
}
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write code for evaluating this. Returns maximum JVM stack
|
||||
* usage.
|
||||
*/
|
||||
public int compileCallTo(CodeVisitor mw, Set recursiveCheck)
|
||||
throws Exception
|
||||
{
|
||||
// if null jump to F
|
||||
// T
|
||||
// jump END
|
||||
// F: F
|
||||
// END: ...
|
||||
Label fl = new Label();
|
||||
Label endl = new Label();
|
||||
|
||||
cond.generate(mw);
|
||||
mw.visitJumpInsn(IFNULL,fl);
|
||||
|
||||
FactorDataStack datastackCopy = (FactorDataStack)
|
||||
datastack.clone();
|
||||
FactorCallStack callstackCopy = (FactorCallStack)
|
||||
callstack.clone();
|
||||
|
||||
int maxJVMStack = t.compileCallTo(mw,recursiveCheck);
|
||||
mw.visitJumpInsn(GOTO,endl);
|
||||
mw.visitLabel(fl);
|
||||
|
||||
datastack = datastackCopy;
|
||||
callstack = callstackCopy;
|
||||
|
||||
maxJVMStack = Math.max(f.compileCallTo(
|
||||
mw,recursiveCheck),maxJVMStack);
|
||||
mw.visitLabel(endl);
|
||||
|
||||
return Math.max(maxJVMStack,1);
|
||||
}
|
||||
} //}}}
|
||||
}
|
|
@ -0,0 +1,168 @@
|
|||
/* :folding=explicit:collapseFolds=1: */
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2004 Slava Pestov.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package factor.compiler;
|
||||
|
||||
import factor.*;
|
||||
import java.util.*;
|
||||
|
||||
public class StackEffect
|
||||
{
|
||||
public final int inD;
|
||||
public final int outD;
|
||||
public final int inR;
|
||||
public final int outR;
|
||||
|
||||
//{{{ StackEffect constructor
|
||||
public StackEffect(int inD, int outD, int inR, int outR)
|
||||
{
|
||||
this.inD = inD;
|
||||
this.outD = outD;
|
||||
this.inR = inR;
|
||||
this.outR = outR;
|
||||
} //}}}
|
||||
|
||||
//{{{ getStackEffect() method
|
||||
public static StackEffect getStackEffect(Cons definition)
|
||||
throws Exception
|
||||
{
|
||||
return getStackEffect(definition,new HashSet(),
|
||||
new LocalAllocator());
|
||||
} //}}}
|
||||
|
||||
//{{{ getStackEffect() method
|
||||
public static StackEffect getStackEffect(Cons definition,
|
||||
Set recursiveCheck, LocalAllocator state)
|
||||
throws Exception
|
||||
{
|
||||
int inD = 0;
|
||||
int outD = 0;
|
||||
int inR = 0;
|
||||
int outR = 0;
|
||||
|
||||
Cons iter = definition;
|
||||
while(iter != null)
|
||||
{
|
||||
Object obj = iter.car;
|
||||
if(obj instanceof FactorWord)
|
||||
{
|
||||
StackEffect se = ((FactorWord)obj).def
|
||||
.getStackEffect(
|
||||
recursiveCheck,
|
||||
state);
|
||||
|
||||
if(se == null)
|
||||
return null;
|
||||
|
||||
if(se.inD <= outD)
|
||||
outD -= se.inD;
|
||||
else
|
||||
{
|
||||
inD += (se.inD - outD);
|
||||
outD = 0;
|
||||
}
|
||||
|
||||
if(se.inR <= outR)
|
||||
outR -= se.inR;
|
||||
else
|
||||
{
|
||||
inR += (se.inR - outR);
|
||||
outR = 0;
|
||||
}
|
||||
|
||||
outD += se.outD;
|
||||
outR += se.outR;
|
||||
}
|
||||
else
|
||||
{
|
||||
outD++;
|
||||
state.pushLiteral(obj);
|
||||
}
|
||||
|
||||
iter = iter.next();
|
||||
}
|
||||
|
||||
return new StackEffect(inD,outD,inR,outR);
|
||||
} //}}}
|
||||
|
||||
//{{{ getCorePrototype() method
|
||||
public String getCorePrototype()
|
||||
{
|
||||
StringBuffer signatureBuf = new StringBuffer(
|
||||
"(Lfactor/FactorInterpreter;");
|
||||
|
||||
for(int i = 0; i < inD; i++)
|
||||
{
|
||||
signatureBuf.append("Ljava/lang/Object;");
|
||||
}
|
||||
|
||||
if(outD == 0)
|
||||
signatureBuf.append(")V");
|
||||
else
|
||||
signatureBuf.append(")Ljava/lang/Object;");
|
||||
|
||||
return signatureBuf.toString();
|
||||
} //}}}
|
||||
|
||||
//{{{ equals() method
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
if(!(o instanceof StackEffect))
|
||||
return false;
|
||||
StackEffect effect = (StackEffect)o;
|
||||
return effect.inD == inD
|
||||
&& effect.outD == outD
|
||||
&& effect.inR == inR
|
||||
&& effect.outR == outR;
|
||||
} //}}}
|
||||
|
||||
//{{{ toString() method
|
||||
public String toString()
|
||||
{
|
||||
StringBuffer buf = new StringBuffer();
|
||||
for(int i = 0; i < inD; i++)
|
||||
{
|
||||
buf.append("I ");
|
||||
}
|
||||
for(int i = 0; i < inR; i++)
|
||||
{
|
||||
buf.append("r:I ");
|
||||
}
|
||||
buf.append("--");
|
||||
for(int i = 0; i < outD; i++)
|
||||
{
|
||||
buf.append(" O");
|
||||
}
|
||||
for(int i = 0; i < outR; i++)
|
||||
{
|
||||
buf.append(" r:O");
|
||||
}
|
||||
return buf.toString();
|
||||
} //}}}
|
||||
}
|
|
@ -25,43 +25,75 @@
|
|||
! OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
! Undefined words's def field is equal to this.
|
||||
"factor.FactorMissingDefinition" "INSTANCE" jfield jvarStatic$ @undefinedWord
|
||||
|
||||
: asm. (word -- assembly)
|
||||
: asm ( word -- assembly )
|
||||
! Prints JVM bytecode disassembly of the given word.
|
||||
worddef [ $asm ] bind dup [
|
||||
worddef compiled? dup [
|
||||
print
|
||||
] [
|
||||
drop "Not a compiled word." print
|
||||
] ifte ;
|
||||
|
||||
: word? (obj -- boolean)
|
||||
"factor.FactorWord" is ;
|
||||
: compile* ( word -- )
|
||||
$interpreter swap
|
||||
[ "factor.FactorInterpreter" ] "factor.FactorWord" "compile"
|
||||
jinvoke ;
|
||||
|
||||
: str>word ("word" -- word)
|
||||
! Returns the top of the stack if it already been interned.
|
||||
dup word? [
|
||||
$dict [ "java.lang.String" ] "factor.FactorDictionary" "intern"
|
||||
jmethod jinvoke
|
||||
] unless ;
|
||||
: compile ( word -- )
|
||||
dup worddef compiled? [
|
||||
drop
|
||||
] [
|
||||
intern compile*
|
||||
] ifte ;
|
||||
|
||||
: worddef? (obj -- boolean)
|
||||
"factor.FactorWordDefinition" is ;
|
||||
: compileAll ( -- )
|
||||
"Compiling..." write
|
||||
words [ compile ] each
|
||||
" done" print ;
|
||||
|
||||
: compiled? ( obj -- boolean )
|
||||
[ $asm ] bind ;
|
||||
|
||||
: compound? (obj -- boolean)
|
||||
"factor.FactorCompoundDefinition" is ;
|
||||
|
||||
: missing>f ( word -- word/f )
|
||||
! Is it the missing word placeholder? Then push f.
|
||||
dup undefined? [ drop f ] when ;
|
||||
|
||||
: shuffle? (obj -- boolean)
|
||||
"factor.FactorShuffleDefinition" is ;
|
||||
|
||||
: worddef (word -- worddef)
|
||||
str>word
|
||||
! Get the 'def' field
|
||||
"factor.FactorWord" "def" jfield jvar$
|
||||
! Is it equal to the missing word placeholder? Then push f.
|
||||
dup $undefinedWord = [ drop f ] when ;
|
||||
: intern ("word" -- word)
|
||||
! Returns the top of the stack if it already been interned.
|
||||
dup word? [
|
||||
$dict [ "java.lang.String" ]
|
||||
"factor.FactorDictionary" "intern"
|
||||
jinvoke
|
||||
] unless ;
|
||||
|
||||
: undefined? ( obj -- boolean )
|
||||
"factor.FactorMissingDefinition" is ;
|
||||
|
||||
: word? (obj -- boolean)
|
||||
"factor.FactorWord" is ;
|
||||
|
||||
: word ( -- word )
|
||||
! Pushes most recently defined word.
|
||||
$dict "factor.FactorDictionary" "last" jvar$ ;
|
||||
|
||||
: worddef? (obj -- boolean)
|
||||
"factor.FactorWordDefinition" is ;
|
||||
|
||||
: worddef ( word -- worddef )
|
||||
intern
|
||||
"factor.FactorWord" "def" jvar$
|
||||
missing>f ;
|
||||
|
||||
: worddefUncompiled ( word -- worddef )
|
||||
intern
|
||||
"factor.FactorWord" "uncompiled" jvar$
|
||||
missing>f ;
|
||||
|
||||
: words (-- list)
|
||||
! Pushes a list of all defined words.
|
||||
$dict [ ] "factor.FactorDictionary" "toWordList" jmethod jinvoke ;
|
||||
$dict [ ] "factor.FactorDictionary" "toWordList" jinvoke ;
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
! - implement an LSP that does an "apropos" search
|
||||
|
||||
: httpdGetPath ( request -- file )
|
||||
dup ".*\\.\\.*" matches [
|
||||
dup ".*\\.\\.*" re-matches [
|
||||
f
|
||||
] [
|
||||
dup [ "GET (.*?)( HTTP.*|)" groups dup [ car ] when ] when
|
||||
|
@ -58,12 +58,12 @@
|
|||
|
||||
: httpdFiletype (filename -- mime-type)
|
||||
[
|
||||
[ dup ".*\.gif" matches ] [ drop "image/gif" ]
|
||||
[ dup ".*\.png" matches ] [ drop "image/png" ]
|
||||
[ dup ".*\.html" matches ] [ drop "text/html" ]
|
||||
[ dup ".*\.txt" matches ] [ drop "text/plain" ]
|
||||
[ dup ".*\.lsd" matches ] [ drop "text/plain" ]
|
||||
[ t ] [ drop "application/octet-stream" ]
|
||||
[ ".*\.gif" re-matches ] [ drop "image/gif" ]
|
||||
[ ".*\.png" re-matches ] [ drop "image/png" ]
|
||||
[ ".*\.html" re-matches ] [ drop "text/html" ]
|
||||
[ ".*\.txt" re-matches ] [ drop "text/plain" ]
|
||||
[ ".*\.lsd" re-matches ] [ drop "text/plain" ]
|
||||
[ t ] [ drop "application/octet-stream" ]
|
||||
] cond ;
|
||||
|
||||
: httpdUriToPath (uri -- path)
|
||||
|
@ -123,7 +123,7 @@
|
|||
dup directory? [
|
||||
httpdServeDirectory
|
||||
] [
|
||||
dup ".*\.lhtml" matches [
|
||||
dup ".*\.lhtml" re-matches [
|
||||
httpdServeScript
|
||||
] [
|
||||
httpdServeFile
|
||||
|
|
|
@ -29,13 +29,13 @@
|
|||
"java.lang.Throwable" is ;
|
||||
|
||||
: printStackTrace (exception --)
|
||||
[ ] "java.lang.Throwable" "printStackTrace" jmethod jinvoke ;
|
||||
[ ] "java.lang.Throwable" "printStackTrace" jinvoke ;
|
||||
|
||||
: exception. (exception --)
|
||||
! If this is an Factor exception, just print the message, otherwise print
|
||||
! the entire exception as a string.
|
||||
dup "factor.FactorException" is [
|
||||
[ ] "java.lang.Throwable" "getMessage" jmethod jinvoke
|
||||
[ ] "java.lang.Throwable" "getMessage" jinvoke
|
||||
] [
|
||||
>str
|
||||
] ifte print ;
|
||||
|
@ -53,6 +53,7 @@
|
|||
":g continues execution (but expect another error)." print
|
||||
"" print
|
||||
"ERROR: " write exception.
|
||||
:w
|
||||
callstack$ @errorCallStack
|
||||
[
|
||||
@errorContinuation
|
||||
|
@ -131,9 +132,11 @@
|
|||
words [ . ] each ;
|
||||
|
||||
: see (word --)
|
||||
dup worddef [
|
||||
dup worddefUncompiled [
|
||||
(word -- worddef word)
|
||||
dup [ worddef dup shuffle? "~<< " ": " ? write ] dip
|
||||
dup [
|
||||
worddefUncompiled dup shuffle? "~<< " ": " ? write
|
||||
] dip
|
||||
|
||||
(worddef word -- worddef)
|
||||
write "\n " write
|
||||
|
@ -153,6 +156,22 @@
|
|||
! Prints the contents of the data stack
|
||||
datastack$ . ;
|
||||
|
||||
: stats ( -- )
|
||||
"Cons: " write
|
||||
"factor.Cons" "COUNT" jvar-static$ .
|
||||
"Words: " write
|
||||
words length .
|
||||
"Compiled: " write
|
||||
words [ worddef compiled? ] subset length . ;
|
||||
|
||||
: gc ( -- )
|
||||
[ ] "java.lang.System" "gc" jinvoke-static ;
|
||||
|
||||
: balance ( code -- effect )
|
||||
! Push stack effect of the given code quotation.
|
||||
[ "factor.Cons" ] "factor.compiler.StackEffect"
|
||||
"getStackEffect" jinvoke-static ;
|
||||
|
||||
: help
|
||||
"" print
|
||||
"= Dynamic, interpreted, stack-based scripting language" print
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
! $Id$
|
||||
!
|
||||
! Copyright (C) 2003 Slava Pestov.
|
||||
! Copyright (C) 2003, 2004 Slava Pestov.
|
||||
!
|
||||
! Redistribution and use in source and binary forms, with or without
|
||||
! modification, are permitted provided that the following conditions are met:
|
||||
|
@ -31,8 +31,8 @@
|
|||
: 2rlist (a b -- [ b a ])
|
||||
swap unit cons ;
|
||||
|
||||
: append ([ list1 ] [ list2 ] -- [ list1 list2 ])
|
||||
swap rappend ;
|
||||
: append ( [ list1 ] [ list2 ] -- [ list1 list2 ] )
|
||||
over [ [ uncons ] dip append cons ] [ nip ] ifte ;
|
||||
|
||||
: add ([ list1 ] elem -- [ list1 elem ])
|
||||
unit append ;
|
||||
|
@ -42,7 +42,8 @@
|
|||
dup [ $ swap append ] dip @ ;
|
||||
|
||||
: array>list ( array -- list )
|
||||
[ "[Ljava.lang.Object;" ] "factor.FactorList" "fromArray" jmethod jinvokeStatic ;
|
||||
[ [ "java.lang.Object" ] ] "factor.Cons" "fromArray"
|
||||
jinvoke-static ;
|
||||
|
||||
: add@ (elem variable --)
|
||||
! Adds the element to the end of the list stored in the given variable.
|
||||
|
@ -63,10 +64,10 @@
|
|||
] ifte ;
|
||||
|
||||
: car ([ car , cdr ] -- car)
|
||||
|factor.FactorList |car jfield jvar$ ;
|
||||
|factor.Cons |car jvar$ ;
|
||||
|
||||
: cdr ([ car , cdr ] -- cdr)
|
||||
|factor.FactorList |cdr jfield jvar$ ;
|
||||
|factor.Cons |cdr jvar$ ;
|
||||
|
||||
: caar (list -- caar)
|
||||
car car ;
|
||||
|
@ -83,10 +84,10 @@
|
|||
: cloneList (list -- list)
|
||||
! Returns a new list where each element is a clone of the elements of
|
||||
! the given list.
|
||||
dup [ [ ] "factor.FactorList" "deepClone" jmethod jinvoke ] when ;
|
||||
dup [ [ ] "factor.Cons" "deepClone" jinvoke ] when ;
|
||||
|
||||
: cons (car cdr -- [ car , cdr ])
|
||||
[ |java.lang.Object |java.lang.Object ] |factor.FactorList jconstructor jnew ;
|
||||
[ |java.lang.Object |java.lang.Object ] |factor.Cons jnew ;
|
||||
|
||||
: contains (elem list -- boolean)
|
||||
dup [
|
||||
|
@ -113,9 +114,13 @@
|
|||
: get (list n -- list[n])
|
||||
[ cdr ] times car ;
|
||||
|
||||
: last (list -- last)
|
||||
: last* ( list -- last )
|
||||
! Pushes last cons of the list.
|
||||
[ dup cdr ] [ cdr ] while ;
|
||||
|
||||
: last ( list -- last )
|
||||
! Pushes last element of the list.
|
||||
[ dup cdr ] [ cdr ] while car ;
|
||||
last* car ;
|
||||
|
||||
: length (list -- length)
|
||||
0 swap [ drop succ ] each ;
|
||||
|
@ -126,18 +131,27 @@
|
|||
: list? (list -- boolean)
|
||||
dup pair? [ cdr list? ] [ f ] ifte ;
|
||||
|
||||
: pair? (list -- boolean)
|
||||
|factor.FactorList is ;
|
||||
: nappend ( [ list1 ] [ list2 ] -- [ list1 list2 ] )
|
||||
! Destructive on list1!
|
||||
over [ last* rplacd ] when* ;
|
||||
|
||||
: rappend ([ list2 ] [ list1 ] -- [ list1 list2 ])
|
||||
[ [ |factor.FactorList ] |factor.FactorList |append jmethod jinvoke ] when* ;
|
||||
: pair? (list -- boolean)
|
||||
|factor.Cons is ;
|
||||
|
||||
: reverse (list -- list)
|
||||
[ ] swap [ swons ] each ;
|
||||
|
||||
: rplaca ( A [ B , C ] -- [ A , C ] )
|
||||
! Destructive!
|
||||
"factor.Cons" "car" jvar@ ;
|
||||
|
||||
: rplacd ( A [ B , C ] -- [ B , A ] )
|
||||
! Destructive!
|
||||
"factor.Cons" "cdr" jvar@ ;
|
||||
|
||||
: swons (cdr car -- [ car , cdr ])
|
||||
swap [ |java.lang.Object |java.lang.Object ]
|
||||
|factor.FactorList jconstructor jnew ;
|
||||
|factor.Cons jnew ;
|
||||
|
||||
: uncons ([ car , cdr ] -- car cdr)
|
||||
dup car swap cdr ;
|
||||
|
|
|
@ -35,76 +35,64 @@
|
|||
"java.lang.Integer" is ;
|
||||
|
||||
: >fixnum (num -- fixnum)
|
||||
[ ] "java.lang.Number" "intValue" jmethod jinvoke ;
|
||||
[ ] "java.lang.Number" "intValue" jinvoke ;
|
||||
|
||||
: bignum? (obj -- boolean)
|
||||
"java.math.BigInteger" is ;
|
||||
|
||||
: >bignum (num -- bignum)
|
||||
[ ] "java.lang.Number" "longValue" jmethod jinvoke
|
||||
[ "long" ] "java.math.BigInteger" "valueOf" jmethod jinvokeStatic ;
|
||||
[ ] "java.lang.Number" "longValue" jinvoke
|
||||
[ "long" ] "java.math.BigInteger" "valueOf" jinvoke-static ;
|
||||
|
||||
: realnum? (obj -- boolean)
|
||||
dup "java.lang.Float" is
|
||||
swap "java.lang.Double" is or ;
|
||||
|
||||
: >realnum (num -- realnum)
|
||||
[ ] "java.lang.Number" "doubleValue" jmethod jinvoke ;
|
||||
[ ] "java.lang.Number" "doubleValue" jinvoke ;
|
||||
|
||||
: ratio? (obj -- boolean)
|
||||
"factor.FactorRatio" is ;
|
||||
|
||||
: + (a b -- a+b)
|
||||
[ "java.lang.Number" "java.lang.Number" ] "factor.FactorMath" "add"
|
||||
jmethod jinvokeStatic ;
|
||||
jinvoke-static ;
|
||||
|
||||
: +@ (num var --)
|
||||
dup [ $ + ] dip @ ;
|
||||
|
||||
: - (a b -- a-b)
|
||||
[ "java.lang.Number" "java.lang.Number" ] "factor.FactorMath" "subtract"
|
||||
jmethod jinvokeStatic ;
|
||||
jinvoke-static ;
|
||||
|
||||
: -@ (num var --)
|
||||
dup [ $ -- ] dip @ ;
|
||||
|
||||
: -- (a b -- b-a)
|
||||
swap - ;
|
||||
|
||||
: --@ (var num --)
|
||||
[ dup $ - ] dip s@ ;
|
||||
dup [ $ swap - ] dip @ ;
|
||||
|
||||
: * (a b -- a*b)
|
||||
[ "java.lang.Number" "java.lang.Number" ] "factor.FactorMath" "multiply"
|
||||
jmethod jinvokeStatic ;
|
||||
jinvoke-static ;
|
||||
|
||||
: *@ (num var --)
|
||||
dup [ $ * ] dip @ ;
|
||||
|
||||
: / (a b -- a/b)
|
||||
[ "java.lang.Number" "java.lang.Number" ] "factor.FactorMath" "divide"
|
||||
jmethod jinvokeStatic ;
|
||||
jinvoke-static ;
|
||||
|
||||
: /@ (num var --)
|
||||
dup [ $ / ] dip @ ;
|
||||
|
||||
: // (a b -- b/a)
|
||||
swap / ;
|
||||
|
||||
: //@ (num var --)
|
||||
[ dup $ / ] dip s@ ;
|
||||
|
||||
: > (a b -- boolean)
|
||||
[ "float" "float" ] "factor.FactorMath" "greater" jmethod jinvokeStatic ;
|
||||
[ "float" "float" ] "factor.FactorMath" "greater" jinvoke-static ;
|
||||
|
||||
: >= (a b -- boolean)
|
||||
[ "float" "float" ] "factor.FactorMath" "greaterEqual" jmethod jinvokeStatic ;
|
||||
[ "float" "float" ] "factor.FactorMath" "greaterEqual" jinvoke-static ;
|
||||
|
||||
: < (a b -- boolean)
|
||||
[ "float" "float" ] "factor.FactorMath" "less" jmethod jinvokeStatic ;
|
||||
[ "float" "float" ] "factor.FactorMath" "less" jinvoke-static ;
|
||||
|
||||
: <= (a b -- boolean)
|
||||
[ "float" "float" ] "factor.FactorMath" "lessEqual" jmethod jinvokeStatic ;
|
||||
[ "float" "float" ] "factor.FactorMath" "lessEqual" jinvoke-static ;
|
||||
|
||||
: and (a b -- a&b)
|
||||
f ? ;
|
||||
|
@ -126,9 +114,15 @@
|
|||
: not@ (boolean -- boolean)
|
||||
dup $ not s@ ;
|
||||
|
||||
: pow ( x y -- x^y )
|
||||
[ "double" "double" ] "java.lang.Math" "pow" jinvoke-static ;
|
||||
|
||||
: pred (n -- n-1)
|
||||
1 - ;
|
||||
|
||||
: round ( x y -- x^y )
|
||||
[ "double" "double" ] "java.lang.Math" "pow" jinvoke-static ;
|
||||
|
||||
: succ (n -- nsucc)
|
||||
1 + ;
|
||||
|
||||
|
@ -139,13 +133,13 @@
|
|||
t swap ? ;
|
||||
|
||||
: recip (x -- 1/x)
|
||||
1 // ;
|
||||
1 swap / ;
|
||||
|
||||
: sq (x -- x^2)
|
||||
dup * ;
|
||||
|
||||
: sqrt (x -- sqrt x)
|
||||
[ "double" ] "java.lang.Math" "sqrt" jmethod jinvokeStatic ;
|
||||
[ "double" ] "java.lang.Math" "sqrt" jinvoke-static ;
|
||||
|
||||
: succ@ (var --)
|
||||
dup $ 1 + s@ ;
|
||||
|
|
|
@ -25,30 +25,28 @@
|
|||
! OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
: >str (obj -- string)
|
||||
! Returns the Java string representation of this object.
|
||||
[ ] "java.lang.Object" "toString" jmethod jinvoke ;
|
||||
|
||||
: = (a b -- boolean)
|
||||
! Returns true if a = b.
|
||||
[ "java.lang.Object" "java.lang.Object" ]
|
||||
"factor.FactorLib" "equal" jmethod jinvokeStatic ;
|
||||
"factor.FactorLib" "equal" jinvoke-static ;
|
||||
|
||||
: clone (obj -- obj)
|
||||
[ ] "factor.PublicCloneable" "clone" jmethod jinvoke ;
|
||||
[ ] "factor.PublicCloneable" "clone" jinvoke ;
|
||||
|
||||
: cloneArray (obj -- obj)
|
||||
[ "[Ljava.lang.Object;" ] "factor.FactorLib" "cloneArray"
|
||||
jmethod jinvokeStatic ;
|
||||
[ [ "java.lang.Object" ] ]
|
||||
"factor.FactorLib" "cloneArray"
|
||||
jinvoke-static ;
|
||||
|
||||
: deepCloneArray (obj -- obj)
|
||||
[ "[Ljava.lang.Object;" ] "factor.FactorLib" "deepCloneArray"
|
||||
jmethod jinvokeStatic ;
|
||||
[ [ "java.lang.Object" ] ]
|
||||
"factor.FactorLib" "deepCloneArray"
|
||||
jinvoke-static ;
|
||||
|
||||
: is (obj class -- boolean)
|
||||
! Like "instanceof" in Java.
|
||||
[ "java.lang.Object" ] "java.lang.Class" "isInstance"
|
||||
jmethod jinvoke ;
|
||||
jinvoke ;
|
||||
|
||||
: not= (a b -- boolean)
|
||||
= not ;
|
||||
|
@ -57,36 +55,31 @@
|
|||
! Returns true if a = c, b = d.
|
||||
swapd = [ = ] dip and ;
|
||||
|
||||
: ? (cond obj1 obj2 -- obj)
|
||||
! Pushes obj1 if cond is true, obj2 if cond is false.
|
||||
[ "boolean" "java.lang.Object" "java.lang.Object" ]
|
||||
"factor.FactorLib" "branch2" jmethod jinvokeStatic ;
|
||||
|
||||
: >=< (x y obj1 obj2 obj3 -- obj)
|
||||
! If x > y, pushes obj1, if x = y, pushes obj2, else obj3.
|
||||
[
|
||||
"float" "float"
|
||||
"java.lang.Object" "java.lang.Object" "java.lang.Object"
|
||||
]
|
||||
"factor.FactorLib" "branch3" jmethod jinvokeStatic ;
|
||||
"factor.FactorLib" "branch3" jinvoke-static ;
|
||||
|
||||
: error (msg --)
|
||||
[ "java.lang.String" ] "factor.FactorLib" "error" jmethod jinvokeStatic ;
|
||||
[ "java.lang.String" ] "factor.FactorLib" "error" jinvoke-static ;
|
||||
|
||||
: exit* (code --)
|
||||
[ |int ] |java.lang.System |exit jmethod jinvokeStatic ;
|
||||
[ |int ] |java.lang.System |exit jinvoke-static ;
|
||||
|
||||
: exit (--)
|
||||
0 exit* ;
|
||||
|
||||
: millis (-- millis)
|
||||
! Pushes the current time, in milliseconds.
|
||||
[ ] |java.lang.System |currentTimeMillis jmethod jinvokeStatic
|
||||
[ ] |java.lang.System |currentTimeMillis jinvoke-static
|
||||
>bignum ;
|
||||
|
||||
: stack>list (stack -- list)
|
||||
! Turns a callstack or datastack object into a list.
|
||||
[ ] "factor.FactorArrayStack" "toList" jmethod jinvoke ;
|
||||
[ ] "factor.FactorArrayStack" "toList" jinvoke ;
|
||||
|
||||
: time (code --)
|
||||
! Evaluates the given code and prints the time taken to execute it.
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
! OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
: s@ ( variable value -- )
|
||||
swap @ ;
|
||||
|
||||
: lazy (var [ a ] -- value)
|
||||
! If the value of the variable is f, set the value to the result of
|
||||
! evaluating [ a ].
|
||||
|
@ -35,12 +38,12 @@
|
|||
|
||||
: <namespace> (-- namespace)
|
||||
$namespace [ |factor.FactorNamespace ] |factor.FactorNamespace
|
||||
jconstructor jnew ;
|
||||
jnew ;
|
||||
|
||||
: <objnamespace> ( object -- namespace )
|
||||
$namespace swap
|
||||
[ "factor.FactorNamespace" "java.lang.Object" ]
|
||||
"factor.FactorNamespace" jconstructor jnew ;
|
||||
"factor.FactorNamespace" jnew ;
|
||||
|
||||
: extend (object code -- object)
|
||||
! Used in code like this:
|
||||
|
@ -52,12 +55,12 @@
|
|||
|
||||
: import (class pairs --)
|
||||
! Import some static variables from a Java class into the current namespace.
|
||||
$namespace [ |java.lang.String |factor.FactorList ]
|
||||
$namespace [ |java.lang.String |factor.Cons ]
|
||||
|factor.FactorNamespace |importVars
|
||||
jmethod jinvoke ;
|
||||
jinvoke ;
|
||||
|
||||
: vars (-- list)
|
||||
$namespace [ ] |factor.FactorNamespace |toVarList jmethod jinvoke ;
|
||||
$namespace [ ] |factor.FactorNamespace |toVarList jinvoke ;
|
||||
|
||||
: uvar? (name --)
|
||||
[ "namespace" "parent" ] contains not ;
|
||||
|
|
|
@ -28,21 +28,21 @@
|
|||
: <server> ( port -- stream )
|
||||
! Starts listening on localhost:port. Returns a stream that you can close
|
||||
! with fclose. No other stream operations are supported.
|
||||
[ "int" ] "java.net.ServerSocket" jconstructor jnew
|
||||
[ "int" ] "java.net.ServerSocket" jnew
|
||||
<stream> [
|
||||
@socket
|
||||
|
||||
( -- )
|
||||
[
|
||||
$socket [ ] "java.net.ServerSocket" "close" jmethod jinvoke
|
||||
$socket [ ] "java.net.ServerSocket" "close" jinvoke
|
||||
] @fclose
|
||||
] extend ;
|
||||
|
||||
: <socketstream> ( socket -- stream )
|
||||
! Wraps a socket inside a bytestream.
|
||||
dup
|
||||
[ [ ] "java.net.Socket" "getInputStream" jmethod jinvoke ]
|
||||
[ [ ] "java.net.Socket" "getOutputStream" jmethod jinvoke ]
|
||||
[ [ ] "java.net.Socket" "getInputStream" jinvoke ]
|
||||
[ [ ] "java.net.Socket" "getOutputStream" jinvoke ]
|
||||
cleave
|
||||
<bytestream> [
|
||||
@socket
|
||||
|
@ -50,11 +50,11 @@
|
|||
! We "extend" bytestream's fclose.
|
||||
( -- )
|
||||
$fclose [
|
||||
$socket [ ] "java.net.Socket" "close" jmethod jinvoke
|
||||
$socket [ ] "java.net.Socket" "close" jinvoke
|
||||
] append @fclose
|
||||
] extend ;
|
||||
|
||||
: accept ( server -- client )
|
||||
! Accept a connection from a server socket.
|
||||
[ $socket ] bind
|
||||
[ ] "java.net.ServerSocket" "accept" jmethod jinvoke <socketstream> ;
|
||||
[ ] "java.net.ServerSocket" "accept" jinvoke <socketstream> ;
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
: unparse (X -- "X")
|
||||
[ |java.lang.Object ] |factor.FactorJava |factorTypeToString
|
||||
jmethod jinvokeStatic ;
|
||||
jinvoke-static ;
|
||||
|
||||
: . (expr --)
|
||||
unparse print ;
|
||||
|
|
|
@ -0,0 +1,126 @@
|
|||
/* :folding=explicit:collapseFolds=1: */
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2003, 2004 Slava Pestov.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package factor.primitives;
|
||||
|
||||
import factor.compiler.*;
|
||||
import factor.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.Set;
|
||||
import org.objectweb.asm.*;
|
||||
|
||||
public class Bind extends FactorWordDefinition
|
||||
{
|
||||
//{{{ Bind constructor
|
||||
public Bind(FactorWord word)
|
||||
{
|
||||
super(word);
|
||||
} //}}}
|
||||
|
||||
//{{{ eval() method
|
||||
public void eval(FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
FactorDataStack datastack = interp.datastack;
|
||||
Cons code = (Cons)datastack.pop(Cons.class);
|
||||
Object obj = datastack.pop();
|
||||
FactorNamespace ns = FactorJava.toNamespace(obj,interp);
|
||||
interp.call(word,ns,code);
|
||||
} //}}}
|
||||
|
||||
//{{{ getStackEffect() method
|
||||
public StackEffect getStackEffect(Set recursiveCheck,
|
||||
LocalAllocator state) throws Exception
|
||||
{
|
||||
state.ensure(state.datastack,2);
|
||||
LocalAllocator.FlowObject quot
|
||||
= (LocalAllocator.FlowObject)
|
||||
state.datastack.pop();
|
||||
state.pop(null);
|
||||
StackEffect effect = quot.getStackEffect(recursiveCheck);
|
||||
if(effect != null)
|
||||
{
|
||||
// add 2 to inD since we consume the
|
||||
// quotation and the object
|
||||
return new StackEffect(effect.inD + 2,
|
||||
effect.outD,
|
||||
effect.inR,
|
||||
effect.outR);
|
||||
}
|
||||
else
|
||||
return null;
|
||||
} //}}}
|
||||
|
||||
//{{{ compileCallTo() method
|
||||
/**
|
||||
* Compile a call to this word. Returns maximum JVM stack use.
|
||||
*/
|
||||
public int compileCallTo(
|
||||
CodeVisitor mw,
|
||||
LocalAllocator allocator,
|
||||
Set recursiveCheck)
|
||||
throws Exception
|
||||
{
|
||||
LocalAllocator.FlowObject quot = (LocalAllocator.FlowObject)
|
||||
allocator.datastack.pop();
|
||||
|
||||
// store namespace on callstack
|
||||
mw.visitVarInsn(ALOAD,0);
|
||||
mw.visitFieldInsn(GETFIELD,
|
||||
"factor/FactorInterpreter",
|
||||
"callframe",
|
||||
"Lfactor/FactorCallFrame;");
|
||||
mw.visitInsn(DUP);
|
||||
mw.visitFieldInsn(GETFIELD,
|
||||
"factor/FactorCallFrame",
|
||||
"namespace",
|
||||
"Lfactor/FactorNamespace;");
|
||||
allocator.pushR(mw);
|
||||
|
||||
// set new namespace
|
||||
mw.visitInsn(DUP);
|
||||
allocator.pop(mw);
|
||||
FactorJava.generateFromConversion(mw,FactorNamespace.class);
|
||||
mw.visitFieldInsn(PUTFIELD,
|
||||
"factor/FactorCallFrame",
|
||||
"namespace",
|
||||
"Lfactor/FactorNamespace;");
|
||||
|
||||
int maxJVMStack = quot.compileCallTo(mw,recursiveCheck);
|
||||
|
||||
// restore namespace from callstack
|
||||
allocator.popR(mw);
|
||||
mw.visitFieldInsn(PUTFIELD,
|
||||
"factor/FactorCallFrame",
|
||||
"namespace",
|
||||
"Lfactor/FactorNamespace;");
|
||||
|
||||
return maxJVMStack + 3;
|
||||
} //}}}
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
/* :folding=explicit:collapseFolds=1: */
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2003, 2004 Slava Pestov.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package factor.primitives;
|
||||
|
||||
import factor.compiler.*;
|
||||
import factor.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.Set;
|
||||
import org.objectweb.asm.*;
|
||||
|
||||
public class Call extends FactorWordDefinition
|
||||
{
|
||||
//{{{ Call constructor
|
||||
public Call(FactorWord word)
|
||||
{
|
||||
super(word);
|
||||
} //}}}
|
||||
|
||||
//{{{ eval() method
|
||||
public void eval(FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
interp.call(word,(Cons)interp.datastack.pop(
|
||||
Cons.class));
|
||||
} //}}}
|
||||
|
||||
//{{{ getStackEffect() method
|
||||
public StackEffect getStackEffect(Set recursiveCheck,
|
||||
LocalAllocator state) throws Exception
|
||||
{
|
||||
state.ensure(state.datastack,1);
|
||||
LocalAllocator.FlowObject quot
|
||||
= (LocalAllocator.FlowObject)
|
||||
state.datastack.pop();
|
||||
StackEffect effect = quot.getStackEffect(recursiveCheck);
|
||||
if(effect != null)
|
||||
{
|
||||
// add 1 to inD since we consume the
|
||||
// quotation
|
||||
return new StackEffect(effect.inD + 1,
|
||||
effect.outD,
|
||||
effect.inR,
|
||||
effect.outR);
|
||||
}
|
||||
else
|
||||
return null;
|
||||
} //}}}
|
||||
|
||||
//{{{ compileCallTo() method
|
||||
/**
|
||||
* Compile a call to this word. Returns maximum JVM stack use.
|
||||
*/
|
||||
public int compileCallTo(
|
||||
CodeVisitor mw,
|
||||
LocalAllocator allocator,
|
||||
Set recursiveCheck)
|
||||
throws Exception
|
||||
{
|
||||
LocalAllocator.FlowObject quot = (LocalAllocator.FlowObject)
|
||||
allocator.datastack.pop();
|
||||
return quot.compileCallTo(mw,recursiveCheck);
|
||||
} //}}}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/* :folding=explicit:collapseFolds=1: */
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2003, 2004 Slava Pestov.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package factor.primitives;
|
||||
|
||||
import factor.compiler.*;
|
||||
import factor.*;
|
||||
import java.util.Set;
|
||||
import org.objectweb.asm.*;
|
||||
|
||||
public class CallstackGet extends FactorWordDefinition
|
||||
{
|
||||
//{{{ CallstackGet constructor
|
||||
public CallstackGet(FactorWord word)
|
||||
{
|
||||
super(word);
|
||||
} //}}}
|
||||
|
||||
//{{{ eval() method
|
||||
public void eval(FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
interp.datastack.push(interp.callstack.clone());
|
||||
} //}}}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/* :folding=explicit:collapseFolds=1: */
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2003, 2004 Slava Pestov.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package factor.primitives;
|
||||
|
||||
import factor.compiler.*;
|
||||
import factor.*;
|
||||
import java.util.Set;
|
||||
|
||||
public class CallstackSet extends FactorWordDefinition
|
||||
{
|
||||
//{{{ CallstackSet constructor
|
||||
public CallstackSet(FactorWord word)
|
||||
{
|
||||
super(word);
|
||||
} //}}}
|
||||
|
||||
//{{{ eval() method
|
||||
public void eval(FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
interp.callstack = (FactorCallStack)((FactorCallStack)
|
||||
interp.datastack.pop(FactorCallStack.class))
|
||||
.clone();
|
||||
} //}}}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
/* :folding=explicit:collapseFolds=1: */
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2003, 2004 Slava Pestov.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package factor.primitives;
|
||||
|
||||
import factor.compiler.*;
|
||||
import factor.*;
|
||||
import org.objectweb.asm.*;
|
||||
|
||||
public class Choice extends FactorWordDefinition
|
||||
{
|
||||
//{{{ Choice constructor
|
||||
public Choice(FactorWord word)
|
||||
{
|
||||
super(word);
|
||||
} //}}}
|
||||
|
||||
//{{{ eval() method
|
||||
public void eval(FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
FactorDataStack datastack = interp.datastack;
|
||||
Object f = datastack.pop();
|
||||
Object t = datastack.pop();
|
||||
Object cond = datastack.pop();
|
||||
datastack.push(core(interp,cond,t,f));
|
||||
} //}}}
|
||||
|
||||
//{{{ core() method
|
||||
public static Object core(FactorInterpreter interp,
|
||||
Object cond, Object t, Object f) throws Exception
|
||||
{
|
||||
return FactorJava.toBoolean(cond) ? t : f;
|
||||
} //}}}
|
||||
|
||||
//{{{ getStackEffect() method
|
||||
public StackEffect getStackEffect(java.util.Set recursiveCheck,
|
||||
LocalAllocator state) throws FactorStackException
|
||||
{
|
||||
state.ensure(state.datastack,3);
|
||||
state.pushChoice();
|
||||
return new StackEffect(3,1,0,0);
|
||||
} //}}}
|
||||
|
||||
//{{{ compileCallTo() method
|
||||
/**
|
||||
* Compile a call to this word. Returns maximum JVM stack use.
|
||||
*/
|
||||
/* public int compileCallTo(
|
||||
CodeVisitor mw,
|
||||
LocalAllocator allocator,
|
||||
java.util.Set recursiveCheck)
|
||||
throws Exception
|
||||
{
|
||||
allocator.pushChoice();
|
||||
|
||||
return 0;
|
||||
} */ //}}}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/* :folding=explicit:collapseFolds=1: */
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2003, 2004 Slava Pestov.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package factor.primitives;
|
||||
|
||||
import factor.compiler.*;
|
||||
import factor.*;
|
||||
import java.util.Set;
|
||||
|
||||
public class Clear extends FactorWordDefinition
|
||||
{
|
||||
//{{{ Clear constructor
|
||||
public Clear(FactorWord word)
|
||||
{
|
||||
super(word);
|
||||
} //}}}
|
||||
|
||||
//{{{ eval() method
|
||||
public void eval(FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
interp.datastack.top = 0;
|
||||
} //}}}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/* :folding=explicit:collapseFolds=1: */
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2003, 2004 Slava Pestov.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package factor.primitives;
|
||||
|
||||
import factor.compiler.*;
|
||||
import factor.*;
|
||||
import java.util.Set;
|
||||
|
||||
public class DatastackGet extends FactorWordDefinition
|
||||
{
|
||||
//{{{ DatastackGet constructor
|
||||
public DatastackGet(FactorWord word)
|
||||
{
|
||||
super(word);
|
||||
} //}}}
|
||||
|
||||
//{{{ eval() method
|
||||
public void eval(FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
interp.datastack.push(interp.datastack.clone());
|
||||
} //}}}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/* :folding=explicit:collapseFolds=1: */
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2003, 2004 Slava Pestov.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package factor.primitives;
|
||||
|
||||
import factor.compiler.*;
|
||||
import factor.*;
|
||||
import java.util.Set;
|
||||
|
||||
public class DatastackSet extends FactorWordDefinition
|
||||
{
|
||||
//{{{ DatastackSet constructor
|
||||
public DatastackSet(FactorWord word)
|
||||
{
|
||||
super(word);
|
||||
} //}}}
|
||||
|
||||
//{{{ eval() method
|
||||
public void eval(FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
interp.datastack = (FactorDataStack)((FactorDataStack)
|
||||
interp.datastack.pop(FactorDataStack.class))
|
||||
.clone();
|
||||
} //}}}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
/* :folding=explicit:collapseFolds=1: */
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2003, 2004 Slava Pestov.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package factor.primitives;
|
||||
|
||||
import factor.compiler.*;
|
||||
import factor.*;
|
||||
import java.util.Set;
|
||||
|
||||
public class Define extends FactorWordDefinition
|
||||
{
|
||||
//{{{ Define constructor
|
||||
public Define(FactorWord word)
|
||||
{
|
||||
super(word);
|
||||
} //}}}
|
||||
|
||||
//{{{ eval() method
|
||||
public void eval(FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
FactorDataStack datastack = interp.datastack;
|
||||
FactorDictionary dict = interp.dict;
|
||||
// handle old define syntax
|
||||
Object obj = datastack.pop();
|
||||
|
||||
FactorWord newWord = interp.dict.intern(
|
||||
(String)datastack.pop(String.class));
|
||||
|
||||
if(obj instanceof Cons)
|
||||
{
|
||||
obj = new FactorCompoundDefinition(
|
||||
newWord,(Cons)obj);
|
||||
}
|
||||
|
||||
FactorWordDefinition def = (FactorWordDefinition)obj;
|
||||
|
||||
newWord.define(def);
|
||||
dict.last = newWord;
|
||||
} //}}}
|
||||
|
||||
//{{{ getStackEffect() method
|
||||
public StackEffect getStackEffect(Set recursiveCheck,
|
||||
LocalAllocator state) throws FactorStackException
|
||||
{
|
||||
state.ensure(state.datastack,2);
|
||||
state.pop(null);
|
||||
state.pop(null);
|
||||
return new StackEffect(2,0,0,0);
|
||||
} //}}}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/* :folding=explicit:collapseFolds=1: */
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2003, 2004 Slava Pestov.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package factor.primitives;
|
||||
|
||||
import factor.compiler.*;
|
||||
import factor.*;
|
||||
import java.util.Set;
|
||||
|
||||
public class Get extends FactorWordDefinition
|
||||
{
|
||||
//{{{ Get constructor
|
||||
public Get(FactorWord word)
|
||||
{
|
||||
super(word);
|
||||
} //}}}
|
||||
|
||||
//{{{ eval() method
|
||||
public void eval(FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
FactorDataStack datastack = interp.datastack;
|
||||
datastack.push(core(interp,datastack.pop()));
|
||||
} //}}}
|
||||
|
||||
//{{{ core() method
|
||||
public static Object core(FactorInterpreter interp,
|
||||
Object name) throws Exception
|
||||
{
|
||||
return interp.callframe.namespace.getVariable(
|
||||
FactorJava.toString(name));
|
||||
} //}}}
|
||||
|
||||
//{{{ getStackEffect() method
|
||||
public StackEffect getStackEffect(Set recursiveCheck,
|
||||
LocalAllocator state) throws FactorStackException
|
||||
{
|
||||
state.ensure(state.datastack,1);
|
||||
state.pop(null);
|
||||
state.push(null);
|
||||
return new StackEffect(1,1,0,0);
|
||||
} //}}}
|
||||
}
|
|
@ -0,0 +1,146 @@
|
|||
/* :folding=explicit:collapseFolds=1: */
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2003, 2004 Slava Pestov.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package factor.primitives;
|
||||
|
||||
import factor.compiler.*;
|
||||
import factor.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.Set;
|
||||
import org.objectweb.asm.*;
|
||||
|
||||
public class JInvoke extends FactorWordDefinition
|
||||
{
|
||||
//{{{ JInvoke constructor
|
||||
public JInvoke(FactorWord word)
|
||||
{
|
||||
super(word);
|
||||
} //}}}
|
||||
|
||||
//{{{ eval() method
|
||||
public void eval(FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
FactorDataStack datastack = interp.datastack;
|
||||
Method method = FactorJava.jmethod(
|
||||
(String)datastack.pop(String.class),
|
||||
(String)datastack.pop(String.class),
|
||||
(Cons)datastack.pop(Cons.class));
|
||||
FactorJava.jinvoke(datastack,
|
||||
method,datastack.pop());
|
||||
} //}}}
|
||||
|
||||
//{{{ getStackEffect() method
|
||||
public StackEffect getStackEffect(Set recursiveCheck,
|
||||
LocalAllocator state) throws Exception
|
||||
{
|
||||
state.ensure(state.datastack,4);
|
||||
Object clazz = state.popLiteral();
|
||||
Object name = state.popLiteral();
|
||||
Object args = state.popLiteral();
|
||||
state.pop(null);
|
||||
|
||||
if(clazz instanceof String &&
|
||||
name instanceof String &&
|
||||
(args == null || args instanceof Cons))
|
||||
{
|
||||
Method method = FactorJava.jmethod(
|
||||
(String)clazz,
|
||||
(String)name,
|
||||
(Cons)args);
|
||||
|
||||
boolean returnValue = method.getReturnType() == Void.TYPE;
|
||||
if(returnValue)
|
||||
state.push(null);
|
||||
return new StackEffect(
|
||||
4 + method.getParameterTypes().length,
|
||||
returnValue ? 0 : 1,0,0);
|
||||
}
|
||||
else
|
||||
return null;
|
||||
} //}}}
|
||||
|
||||
//{{{ compileCallTo() method
|
||||
/**
|
||||
* Compile a call to this word. Returns maximum JVM stack use.
|
||||
* XXX: does not use factor type system conversions.
|
||||
*/
|
||||
public int compileCallTo(
|
||||
CodeVisitor mw,
|
||||
LocalAllocator allocator,
|
||||
Set recursiveCheck)
|
||||
throws Exception
|
||||
{
|
||||
Object _method = allocator.popLiteral();
|
||||
Object _clazz = allocator.popLiteral();
|
||||
Object _args = allocator.popLiteral();
|
||||
if(_method instanceof String &&
|
||||
_clazz instanceof String &&
|
||||
(_args == null || _args instanceof Cons))
|
||||
{
|
||||
String method = (String)_method;
|
||||
String clazz = (String)_clazz;
|
||||
Class[] args = FactorJava.classNameToClassList(
|
||||
(Cons)_args);
|
||||
Class cls = FactorJava.getClass(clazz);
|
||||
Method mth = cls.getMethod(method,args);
|
||||
Class returnType = mth.getReturnType();
|
||||
|
||||
clazz = clazz.replace('.','/');
|
||||
|
||||
FactorJava.generateToConversionPre(mw,returnType);
|
||||
|
||||
allocator.pop(mw);
|
||||
FactorJava.generateFromConversion(mw,cls);
|
||||
|
||||
allocator.generateArgs(mw,args.length,args);
|
||||
|
||||
int opcode;
|
||||
if(cls.isInterface())
|
||||
opcode = INVOKEINTERFACE;
|
||||
else
|
||||
opcode = INVOKEVIRTUAL;
|
||||
mw.visitMethodInsn(opcode,
|
||||
clazz,
|
||||
method,
|
||||
FactorJava.javaSignatureToVMSignature(
|
||||
args,returnType));
|
||||
|
||||
if(returnType != Void.TYPE)
|
||||
{
|
||||
FactorJava.generateToConversion(mw,returnType);
|
||||
allocator.push(mw);
|
||||
}
|
||||
|
||||
return 4 + args.length;
|
||||
}
|
||||
else
|
||||
throw new FactorCompilerException("Cannot compile jinvoke with non-literal parameters");
|
||||
} //}}}
|
||||
}
|
|
@ -0,0 +1,136 @@
|
|||
/* :folding=explicit:collapseFolds=1: */
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2003, 2004 Slava Pestov.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package factor.primitives;
|
||||
|
||||
import factor.compiler.*;
|
||||
import factor.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.Set;
|
||||
import org.objectweb.asm.*;
|
||||
|
||||
public class JInvokeStatic extends FactorWordDefinition
|
||||
{
|
||||
//{{{ JInvokeStatic constructor
|
||||
public JInvokeStatic(FactorWord word)
|
||||
{
|
||||
super(word);
|
||||
} //}}}
|
||||
|
||||
//{{{ eval() method
|
||||
public void eval(FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
FactorDataStack datastack = interp.datastack;
|
||||
Method method = FactorJava.jmethod(
|
||||
(String)datastack.pop(String.class),
|
||||
(String)datastack.pop(String.class),
|
||||
(Cons)datastack.pop(Cons.class));
|
||||
FactorJava.jinvokeStatic(datastack,method);
|
||||
} //}}}
|
||||
|
||||
//{{{ getStackEffect() method
|
||||
public StackEffect getStackEffect(Set recursiveCheck,
|
||||
LocalAllocator state) throws Exception
|
||||
{
|
||||
state.ensure(state.datastack,3);
|
||||
Object clazz = state.popLiteral();
|
||||
Object name = state.popLiteral();
|
||||
Object args = state.popLiteral();
|
||||
|
||||
if(clazz instanceof String &&
|
||||
name instanceof String &&
|
||||
(args == null || args instanceof Cons))
|
||||
{
|
||||
Method method = FactorJava.jmethod(
|
||||
(String)clazz,
|
||||
(String)name,
|
||||
(Cons)args);
|
||||
|
||||
boolean returnValue = method.getReturnType() == Void.TYPE;
|
||||
if(returnValue)
|
||||
state.push(null);
|
||||
return new StackEffect(
|
||||
3 + method.getParameterTypes().length,
|
||||
returnValue ? 0 : 1,0,0);
|
||||
}
|
||||
else
|
||||
return null;
|
||||
} //}}}
|
||||
|
||||
//{{{ compileCallTo() method
|
||||
/**
|
||||
* Compile a call to this word. Returns maximum JVM stack use.
|
||||
* XXX: does not use factor type system conversions.
|
||||
*/
|
||||
public int compileCallTo(
|
||||
CodeVisitor mw,
|
||||
LocalAllocator allocator,
|
||||
Set recursiveCheck)
|
||||
throws Exception
|
||||
{
|
||||
Object _method = allocator.popLiteral();
|
||||
Object _clazz = allocator.popLiteral();
|
||||
Object _args = allocator.popLiteral();
|
||||
if(_method instanceof String &&
|
||||
_clazz instanceof String &&
|
||||
(_args == null || _args instanceof Cons))
|
||||
{
|
||||
String method = (String)_method;
|
||||
String clazz = (String)_clazz;
|
||||
Class[] args = FactorJava.classNameToClassList(
|
||||
(Cons)_args);
|
||||
Class cls = FactorJava.getClass(clazz);
|
||||
Method mth = cls.getMethod(method,args);
|
||||
Class returnType = mth.getReturnType();
|
||||
|
||||
clazz = clazz.replace('.','/');
|
||||
|
||||
FactorJava.generateToConversionPre(mw,returnType);
|
||||
|
||||
allocator.generateArgs(mw,args.length,args);
|
||||
|
||||
mw.visitMethodInsn(INVOKESTATIC,
|
||||
clazz,
|
||||
method,
|
||||
FactorJava.javaSignatureToVMSignature(
|
||||
args,returnType));
|
||||
|
||||
if(returnType != Void.TYPE)
|
||||
{
|
||||
FactorJava.generateToConversion(mw,returnType);
|
||||
allocator.push(mw);
|
||||
}
|
||||
|
||||
return 4 + args.length;
|
||||
}
|
||||
else
|
||||
throw new FactorCompilerException("Cannot compile jinvoke with non-literal parameters");
|
||||
} //}}}
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
/* :folding=explicit:collapseFolds=1: */
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2003, 2004 Slava Pestov.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package factor.primitives;
|
||||
|
||||
import factor.compiler.*;
|
||||
import factor.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.Set;
|
||||
import org.objectweb.asm.*;
|
||||
|
||||
public class JNew extends FactorWordDefinition
|
||||
{
|
||||
//{{{ JNew constructor
|
||||
public JNew(FactorWord word)
|
||||
{
|
||||
super(word);
|
||||
} //}}}
|
||||
|
||||
//{{{ eval() method
|
||||
public void eval(FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
FactorDataStack datastack = interp.datastack;
|
||||
String name = (String)datastack.pop(String.class);
|
||||
Cons args = (Cons)datastack.pop(Cons.class);
|
||||
Constructor constructor = FactorJava.jconstructor(
|
||||
name,args);
|
||||
FactorJava.jnew(datastack,constructor);
|
||||
} //}}}
|
||||
|
||||
//{{{ getStackEffect() method
|
||||
/**
|
||||
* XXX: does not use factor type system conversions.
|
||||
*/
|
||||
public StackEffect getStackEffect(Set recursiveCheck,
|
||||
LocalAllocator state) throws Exception
|
||||
{
|
||||
state.ensure(state.datastack,2);
|
||||
|
||||
Object clazz = state.popLiteral();
|
||||
Object args = state.popLiteral();
|
||||
if(clazz instanceof String &&
|
||||
(args == null || args instanceof Cons))
|
||||
{
|
||||
Constructor constructor
|
||||
= FactorJava.jconstructor(
|
||||
(String)clazz,
|
||||
(Cons)args);
|
||||
|
||||
state.push(null);
|
||||
return new StackEffect(
|
||||
2 + constructor.getParameterTypes()
|
||||
.length,1,0,0);
|
||||
}
|
||||
else
|
||||
return null;
|
||||
} //}}}
|
||||
|
||||
//{{{ compileCallTo() method
|
||||
/**
|
||||
* Compile a call to this word. Returns maximum JVM stack use.
|
||||
* XXX: does not use factor type system conversions.
|
||||
*/
|
||||
public int compileCallTo(
|
||||
CodeVisitor mw,
|
||||
LocalAllocator allocator,
|
||||
Set recursiveCheck)
|
||||
throws Exception
|
||||
{
|
||||
Object _clazz = allocator.popLiteral();
|
||||
Object _args = allocator.popLiteral();
|
||||
if(_clazz instanceof String &&
|
||||
(_args == null || _args instanceof Cons))
|
||||
{
|
||||
String clazz = ((String)_clazz)
|
||||
.replace('.','/');
|
||||
Class[] args = FactorJava.classNameToClassList(
|
||||
(Cons)_args);
|
||||
|
||||
mw.visitTypeInsn(NEW,clazz);
|
||||
mw.visitInsn(DUP);
|
||||
|
||||
allocator.generateArgs(mw,args.length,args);
|
||||
|
||||
mw.visitMethodInsn(INVOKESPECIAL,
|
||||
clazz,
|
||||
"<init>",
|
||||
FactorJava.javaSignatureToVMSignature(
|
||||
args,void.class));
|
||||
|
||||
allocator.push(mw);
|
||||
|
||||
return 3 + args.length;
|
||||
}
|
||||
else
|
||||
throw new FactorCompilerException("Cannot compile jnew with non-literal parameters");
|
||||
} //}}}
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
/* :folding=explicit:collapseFolds=1: */
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2003, 2004 Slava Pestov.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package factor.primitives;
|
||||
|
||||
import factor.compiler.*;
|
||||
import factor.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.Set;
|
||||
import org.objectweb.asm.*;
|
||||
|
||||
public class JVarGet extends FactorWordDefinition
|
||||
{
|
||||
//{{{ JVarGet constructor
|
||||
public JVarGet(FactorWord word)
|
||||
{
|
||||
super(word);
|
||||
} //}}}
|
||||
|
||||
//{{{ eval() method
|
||||
public void eval(FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
FactorDataStack datastack = interp.datastack;
|
||||
Field field = FactorJava.jfield(
|
||||
(String)datastack.pop(String.class),
|
||||
(String)datastack.pop(String.class));
|
||||
datastack.push(
|
||||
FactorJava.jvarGet(
|
||||
field,datastack.pop()));
|
||||
} //}}}
|
||||
|
||||
//{{{ getStackEffect() method
|
||||
public StackEffect getStackEffect(Set recursiveCheck,
|
||||
LocalAllocator state) throws FactorStackException
|
||||
{
|
||||
state.ensure(state.datastack,3);
|
||||
state.pop(null);
|
||||
state.pop(null);
|
||||
state.pop(null);
|
||||
state.push(null);
|
||||
return new StackEffect(3,1,0,0);
|
||||
} //}}}
|
||||
|
||||
//{{{ compileCallTo() method
|
||||
/**
|
||||
* Compile a call to this word. Returns maximum JVM stack use.
|
||||
* XXX: does not use factor type system conversions.
|
||||
*/
|
||||
public int compileCallTo(
|
||||
CodeVisitor mw,
|
||||
LocalAllocator allocator,
|
||||
Set recursiveCheck)
|
||||
throws Exception
|
||||
{
|
||||
Object _field = allocator.popLiteral();
|
||||
Object _clazz = allocator.popLiteral();
|
||||
if(_clazz instanceof String &&
|
||||
_field instanceof String)
|
||||
{
|
||||
String field = (String)_field;
|
||||
String clazz = (String)_clazz;
|
||||
Class cls = FactorJava.getClass(clazz);
|
||||
clazz = clazz.replace('.','/');
|
||||
Field fld = cls.getField(field);
|
||||
|
||||
FactorJava.generateToConversionPre(mw,fld.getType());
|
||||
|
||||
allocator.pop(mw);
|
||||
FactorJava.generateFromConversion(mw,cls);
|
||||
|
||||
mw.visitFieldInsn(GETFIELD,clazz,field,
|
||||
FactorJava.javaClassToVMClass(fld.getType()));
|
||||
|
||||
FactorJava.generateToConversion(mw,fld.getType());
|
||||
|
||||
allocator.push(mw);
|
||||
|
||||
return 2;
|
||||
}
|
||||
else
|
||||
throw new FactorCompilerException("Cannot compile jvar$ with non-literal parameters");
|
||||
} //}}}
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
/* :folding=explicit:collapseFolds=1: */
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2003, 2004 Slava Pestov.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package factor.primitives;
|
||||
|
||||
import factor.compiler.*;
|
||||
import factor.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.Set;
|
||||
import org.objectweb.asm.*;
|
||||
|
||||
public class JVarGetStatic extends FactorWordDefinition
|
||||
{
|
||||
//{{{ JVarGetStatic constructor
|
||||
public JVarGetStatic(FactorWord word)
|
||||
{
|
||||
super(word);
|
||||
} //}}}
|
||||
|
||||
//{{{ eval() method
|
||||
public void eval(FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
FactorDataStack datastack = interp.datastack;
|
||||
Field field = FactorJava.jfield(
|
||||
(String)datastack.pop(String.class),
|
||||
(String)datastack.pop(String.class));
|
||||
datastack.push(
|
||||
FactorJava.jvarGetStatic(field));
|
||||
} //}}}
|
||||
|
||||
//{{{ getStackEffect() method
|
||||
public StackEffect getStackEffect(Set recursiveCheck,
|
||||
LocalAllocator state) throws FactorStackException
|
||||
{
|
||||
state.ensure(state.datastack,2);
|
||||
state.pop(null);
|
||||
state.pop(null);
|
||||
state.push(null);
|
||||
return new StackEffect(2,1,0,0);
|
||||
} //}}}
|
||||
|
||||
//{{{ compileCallTo() method
|
||||
/**
|
||||
* Compile a call to this word. Returns maximum JVM stack use.
|
||||
* XXX: does not use factor type system conversions.
|
||||
*/
|
||||
public int compileCallTo(
|
||||
CodeVisitor mw,
|
||||
LocalAllocator allocator,
|
||||
Set recursiveCheck)
|
||||
throws Exception
|
||||
{
|
||||
Object _field = allocator.popLiteral();
|
||||
Object _clazz = allocator.popLiteral();
|
||||
if(_clazz instanceof String &&
|
||||
_field instanceof String)
|
||||
{
|
||||
String field = (String)_field;
|
||||
String clazz = (String)_clazz;
|
||||
Class cls = FactorJava.getClass(clazz);
|
||||
clazz = clazz.replace('.','/');
|
||||
Field fld = cls.getField(field);
|
||||
|
||||
FactorJava.generateToConversionPre(mw,fld.getType());
|
||||
|
||||
mw.visitFieldInsn(GETSTATIC,clazz,field,
|
||||
FactorJava.javaClassToVMClass(fld.getType()));
|
||||
|
||||
FactorJava.generateToConversion(mw,fld.getType());
|
||||
|
||||
allocator.push(mw);
|
||||
|
||||
return 2;
|
||||
}
|
||||
else
|
||||
throw new FactorCompilerException("Cannot compile jvar-static$ with non-literal parameters");
|
||||
} //}}}
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
/* :folding=explicit:collapseFolds=1: */
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2003, 2004 Slava Pestov.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package factor.primitives;
|
||||
|
||||
import factor.compiler.*;
|
||||
import factor.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.Set;
|
||||
import org.objectweb.asm.*;
|
||||
|
||||
public class JVarSet extends FactorWordDefinition
|
||||
{
|
||||
//{{{ JVarSet constructor
|
||||
public JVarSet(FactorWord word)
|
||||
{
|
||||
super(word);
|
||||
} //}}}
|
||||
|
||||
//{{{ eval() method
|
||||
public void eval(FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
FactorDataStack datastack = interp.datastack;
|
||||
Field field = FactorJava.jfield(
|
||||
(String)datastack.pop(String.class),
|
||||
(String)datastack.pop(String.class));
|
||||
FactorJava.jvarSet(
|
||||
field,
|
||||
datastack.pop(),
|
||||
datastack.pop());
|
||||
} //}}}
|
||||
|
||||
//{{{ getStackEffect() method
|
||||
public StackEffect getStackEffect(Set recursiveCheck,
|
||||
LocalAllocator state) throws FactorStackException
|
||||
{
|
||||
state.ensure(state.datastack,4);
|
||||
state.pop(null);
|
||||
state.pop(null);
|
||||
state.pop(null);
|
||||
state.pop(null);
|
||||
return new StackEffect(4,0,0,0);
|
||||
} //}}}
|
||||
|
||||
//{{{ compileCallTo() method
|
||||
/**
|
||||
* Compile a call to this word. Returns maximum JVM stack use.
|
||||
* XXX: does not use factor type system conversions.
|
||||
*/
|
||||
public int compileCallTo(
|
||||
CodeVisitor mw,
|
||||
LocalAllocator allocator,
|
||||
Set recursiveCheck)
|
||||
throws Exception
|
||||
{
|
||||
Object _field = allocator.popLiteral();
|
||||
Object _clazz = allocator.popLiteral();
|
||||
if(_clazz instanceof String &&
|
||||
_field instanceof String)
|
||||
{
|
||||
String field = (String)_field;
|
||||
String clazz = (String)_clazz;
|
||||
Class cls = FactorJava.getClass(clazz);
|
||||
clazz = clazz.replace('.','/');
|
||||
Field fld = cls.getField(field);
|
||||
|
||||
allocator.pop(mw);
|
||||
FactorJava.generateFromConversion(mw,cls);
|
||||
|
||||
allocator.pop(mw);
|
||||
FactorJava.generateFromConversion(mw,fld.getType());
|
||||
|
||||
mw.visitFieldInsn(PUTFIELD,
|
||||
clazz,
|
||||
field,
|
||||
FactorJava.javaClassToVMClass(fld.getType()));
|
||||
|
||||
return 2;
|
||||
}
|
||||
else
|
||||
throw new FactorCompilerException("Cannot compile jvar@ with non-literal parameters");
|
||||
} //}}}
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
/* :folding=explicit:collapseFolds=1: */
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2003, 2004 Slava Pestov.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package factor.primitives;
|
||||
|
||||
import factor.compiler.*;
|
||||
import factor.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.Set;
|
||||
import org.objectweb.asm.*;
|
||||
|
||||
public class JVarSetStatic extends FactorWordDefinition
|
||||
{
|
||||
//{{{ JVarSetStatic constructor
|
||||
public JVarSetStatic(FactorWord word)
|
||||
{
|
||||
super(word);
|
||||
} //}}}
|
||||
|
||||
//{{{ eval() method
|
||||
public void eval(FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
FactorDataStack datastack = interp.datastack;
|
||||
Field field = FactorJava.jfield(
|
||||
(String)datastack.pop(String.class),
|
||||
(String)datastack.pop(String.class));
|
||||
FactorJava.jvarSetStatic(
|
||||
field,datastack.pop());
|
||||
} //}}}
|
||||
|
||||
//{{{ getStackEffect() method
|
||||
public StackEffect getStackEffect(Set recursiveCheck,
|
||||
LocalAllocator state) throws FactorStackException
|
||||
{
|
||||
state.ensure(state.datastack,3);
|
||||
state.pop(null);
|
||||
state.pop(null);
|
||||
state.pop(null);
|
||||
return new StackEffect(3,0,0,0);
|
||||
} //}}}
|
||||
|
||||
//{{{ compileCallTo() method
|
||||
/**
|
||||
* Compile a call to this word. Returns maximum JVM stack use.
|
||||
* XXX: does not use factor type system conversions.
|
||||
*/
|
||||
public int compileCallTo(
|
||||
CodeVisitor mw,
|
||||
LocalAllocator allocator,
|
||||
Set recursiveCheck)
|
||||
throws Exception
|
||||
{
|
||||
Object _field = allocator.popLiteral();
|
||||
Object _clazz = allocator.popLiteral();
|
||||
if(_clazz instanceof String &&
|
||||
_field instanceof String)
|
||||
{
|
||||
String field = (String)_field;
|
||||
String clazz = (String)_clazz;
|
||||
Class cls = FactorJava.getClass(clazz);
|
||||
clazz = clazz.replace('.','/');
|
||||
Field fld = cls.getField(field);
|
||||
|
||||
allocator.pop(mw);
|
||||
FactorJava.generateFromConversion(mw,fld.getType());
|
||||
|
||||
mw.visitFieldInsn(PUTSTATIC,
|
||||
clazz,
|
||||
field,
|
||||
FactorJava.javaClassToVMClass(fld.getType()));
|
||||
|
||||
return 2;
|
||||
}
|
||||
else
|
||||
throw new FactorCompilerException("Cannot compile jvar-static@ with non-literal parameters");
|
||||
} //}}}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/* :folding=explicit:collapseFolds=1: */
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2003, 2004 Slava Pestov.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package factor.primitives;
|
||||
|
||||
import factor.compiler.*;
|
||||
import factor.*;
|
||||
import java.util.Set;
|
||||
|
||||
public class Restack extends FactorWordDefinition
|
||||
{
|
||||
//{{{ Restack constructor
|
||||
public Restack(FactorWord word)
|
||||
{
|
||||
super(word);
|
||||
} //}}}
|
||||
|
||||
//{{{ eval() method
|
||||
public void eval(FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
FactorDataStack datastack = interp.datastack;
|
||||
Cons list = (Cons)datastack.pop(Cons.class);
|
||||
interp.callstack.push(datastack);
|
||||
interp.datastack = new FactorDataStack(list);
|
||||
} //}}}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
/* :folding=explicit:collapseFolds=1: */
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2003, 2004 Slava Pestov.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package factor.primitives;
|
||||
|
||||
import factor.compiler.*;
|
||||
import factor.*;
|
||||
|
||||
public class Set extends FactorWordDefinition
|
||||
{
|
||||
//{{{ Set constructor
|
||||
public Set(FactorWord word)
|
||||
{
|
||||
super(word);
|
||||
} //}}}
|
||||
|
||||
//{{{ eval() method
|
||||
public void eval(FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
FactorDataStack datastack = interp.datastack;
|
||||
Object name = datastack.pop();
|
||||
Object value = datastack.pop();
|
||||
core(interp,value,name);
|
||||
} //}}}
|
||||
|
||||
//{{{ core() method
|
||||
public static void core(FactorInterpreter interp,
|
||||
Object value, Object name) throws Exception
|
||||
{
|
||||
interp.callframe.namespace.setVariable(
|
||||
FactorJava.toString(name),value);
|
||||
} //}}}
|
||||
|
||||
//{{{ getStackEffect() method
|
||||
public StackEffect getStackEffect(java.util.Set recursiveCheck,
|
||||
LocalAllocator state) throws FactorStackException
|
||||
{
|
||||
state.ensure(state.datastack,2);
|
||||
state.pop(null);
|
||||
state.pop(null);
|
||||
return new StackEffect(2,0,0,0);
|
||||
} //}}}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/* :folding=explicit:collapseFolds=1: */
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2003, 2004 Slava Pestov.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package factor.primitives;
|
||||
|
||||
import factor.compiler.*;
|
||||
import factor.*;
|
||||
import java.util.Set;
|
||||
|
||||
public class Unstack extends FactorWordDefinition
|
||||
{
|
||||
//{{{ Unstack constructor
|
||||
public Unstack(FactorWord word)
|
||||
{
|
||||
super(word);
|
||||
} //}}}
|
||||
|
||||
//{{{ eval() method
|
||||
public void eval(FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
Cons unstack = interp.datastack.toList();
|
||||
interp.datastack = (FactorDataStack)interp.callstack.pop();
|
||||
interp.datastack.push(unstack);
|
||||
} //}}}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/* :folding=explicit:collapseFolds=1: */
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2003, 2004 Slava Pestov.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package factor.primitives;
|
||||
|
||||
import factor.compiler.*;
|
||||
import factor.*;
|
||||
import java.util.Set;
|
||||
|
||||
public class Unwind extends FactorWordDefinition
|
||||
{
|
||||
//{{{ Unwind constructor
|
||||
public Unwind(FactorWord word)
|
||||
{
|
||||
super(word);
|
||||
} //}}}
|
||||
|
||||
//{{{ eval() method
|
||||
public void eval(FactorInterpreter interp)
|
||||
throws Exception
|
||||
{
|
||||
interp.callstack.top = 0;
|
||||
} //}}}
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
! $Id$
|
||||
!
|
||||
! Copyright (C) 2003 Slava Pestov.
|
||||
! Copyright (C) 2003, 2004 Slava Pestov.
|
||||
!
|
||||
! Redistribution and use in source and binary forms, with or without
|
||||
! modification, are permitted provided that the following conditions are met:
|
||||
|
@ -25,64 +25,76 @@
|
|||
! OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
: randomAngle (-- theta)
|
||||
[ ] "factor.FactorMath" "randomAngle" jmethod jinvokeStatic ;
|
||||
: random-angle ( -- theta )
|
||||
[ ] "factor.FactorMath"
|
||||
"randomAngle" jinvoke-static ;
|
||||
|
||||
: randomBoolean (-- boolean)
|
||||
[ ] "factor.FactorMath" "randomBoolean" jmethod jinvokeStatic ;
|
||||
: random-boolean ( -- boolean )
|
||||
[ ] "factor.FactorMath"
|
||||
"randomBoolean" jinvoke-static ;
|
||||
|
||||
: randomInt (min max -- random)
|
||||
[ "int" "int" ] "factor.FactorMath" "randomInt" jmethod jinvokeStatic ;
|
||||
: random-digit ( -- digit )
|
||||
0 9 random-int ;
|
||||
|
||||
: randomSymmetricInt (max -- random)
|
||||
: random-float ( min max scale -- random )
|
||||
[ "int" "int" "float" ] "factor.FactorMath"
|
||||
"randomFloat" jinvoke-static ;
|
||||
|
||||
: random-int ( min max -- random )
|
||||
[ "int" "int" ] "factor.FactorMath"
|
||||
"randomInt" jinvoke-static ;
|
||||
|
||||
: random-symmetric-int ( max -- random )
|
||||
! Return a random integer between -max and max.
|
||||
dup neg swap randomInt ;
|
||||
dup neg swap random-int ;
|
||||
|
||||
: chance (n -- boolean)
|
||||
! Returns true with a 1/n probability, false with a (n-1)/n probability.
|
||||
1 swap randomInt 1 = ;
|
||||
|
||||
: randomElement (list -- random)
|
||||
! Returns a random element from the given list.
|
||||
dup length pred 0 swap randomInt get ;
|
||||
|
||||
: randomSubset (list -- list)
|
||||
! Returns a random subset of the given list. Each item is chosen with a 50%
|
||||
: chance ( n -- boolean )
|
||||
! Returns true with a 1/n probability, false with a (n-1)/n
|
||||
! probability.
|
||||
[ ] [ randomBoolean [ drop ] when ] map ;
|
||||
1 swap random-int 1 = ;
|
||||
|
||||
: car+ (list -- sum)
|
||||
: random-element ( list -- random )
|
||||
! Returns a random element from the given list.
|
||||
dup length pred 0 swap random-int get ;
|
||||
|
||||
: random-subset ( list -- list )
|
||||
! Returns a random subset of the given list. Each item is
|
||||
! chosen with a 50%
|
||||
! probability.
|
||||
[ random-boolean [ drop ] when ] map ;
|
||||
|
||||
: car+ ( list -- sum )
|
||||
! Adds the car of each element of the given list.
|
||||
0 swap [ car + ] each ;
|
||||
|
||||
: randomProbability (list -- sum)
|
||||
! Adds the car of each element of the given list, and returns a random
|
||||
! number between 1 and this sum.
|
||||
1 swap car+ randomInt ;
|
||||
: random-probability ( list -- sum )
|
||||
! Adds the car of each element of the given list, and
|
||||
! returns a random number between 1 and this sum.
|
||||
1 swap car+ random-int ;
|
||||
|
||||
: randomElementIter (list index -- elem)
|
||||
! Used by randomElement*. Do not call directly.
|
||||
: random-element-iter ( list index -- elem )
|
||||
! Used by random-element*. Do not call directly.
|
||||
[ unswons unswons ] dip (list elem probability index)
|
||||
-- (list elem index)
|
||||
swap - (list elem index)
|
||||
dup 0 <= [
|
||||
drop nip
|
||||
] [
|
||||
nip randomElementIter
|
||||
nip random-element-iter
|
||||
] ifte ;
|
||||
|
||||
: randomElement* (list -- elem)
|
||||
! Returns a random element of the given list of comma pairs. The
|
||||
! car of each pair is a probability, the cdr is the item itself.
|
||||
! Only the cdr of the comma pair is returned.
|
||||
dup 1 swap car+ randomInt randomElementIter ;
|
||||
: random-element* ( list -- elem )
|
||||
! Returns a random element of the given list of comma pairs.
|
||||
! The car of each pair is a probability, the cdr is the item
|
||||
! itself. Only the cdr of the comma pair is returned.
|
||||
dup 1 swap car+ random-int random-element-iter ;
|
||||
|
||||
: randomSubset* (list -- list)
|
||||
! Returns a random subset of the given list of comma pairs. The
|
||||
! car of each pair is a probability, the cdr is the item itself.
|
||||
! Only the cdr of the comma pair is returned.
|
||||
: random-subset* ( list -- list )
|
||||
! Returns a random subset of the given list of comma pairs.
|
||||
! The car of each pair is a probability, the cdr is the item
|
||||
! itself. Only the cdr of the comma pair is returned.
|
||||
dup [ [ [ ] ] dip car+ ] dip ([ ] probabilitySum list)
|
||||
[
|
||||
[ 1 over randomInt ] dip ([ ] probabilitySum probability elem)
|
||||
[ 1 over random-int ] dip ([ ] probabilitySum probability elem)
|
||||
uncons ([ ] probabilitySum probability elema elemd)
|
||||
-rot ([ ] probabilitySum elemd probability elema)
|
||||
> ([ ] probabilitySum elemd boolean)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
! $Id$
|
||||
!
|
||||
! Copyright (C) 2003 Slava Pestov.
|
||||
! Copyright (C) 2003, 2004 Slava Pestov.
|
||||
!
|
||||
! Redistribution and use in source and binary forms, with or without
|
||||
! modification, are permitted provided that the following conditions are met:
|
||||
|
@ -26,18 +26,18 @@
|
|||
! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
: <stream> ( -- stream )
|
||||
! Create a stream object. A stream is a namespace with the following
|
||||
! entries:
|
||||
! Create a stream object. A stream is a namespace with the
|
||||
! following entries:
|
||||
! - fflush
|
||||
! - freadln -- you must provide an implementation!
|
||||
! - fwriteln
|
||||
! - fwrite -- you must provide an implementation!
|
||||
! - fclose
|
||||
! Note that you must extend this object and provide your own implementations
|
||||
! of all entries except for fwriteln, which is defined to fwrite the string
|
||||
! followed by the newline by default.
|
||||
! Note that you must extend this object and provide your own
|
||||
! implementations of all entries except for fwriteln, which
|
||||
! is defined to fwrite the string followed by the newline by
|
||||
! default.
|
||||
<namespace> [
|
||||
|
||||
( -- string )
|
||||
[ "freadln not implemented." break ] @freadln
|
||||
( string -- )
|
||||
|
@ -50,91 +50,99 @@
|
|||
[ $namespace fwrite "\n" $namespace fwrite ] @fwriteln
|
||||
] extend ;
|
||||
|
||||
! These are in separate words so that they can be compiled.
|
||||
! Do not call them directly.
|
||||
|
||||
: <bytestream>/freadln ( -- string )
|
||||
$in [ "java.io.InputStream" ] "factor.FactorLib" "readLine"
|
||||
jinvoke-static ;
|
||||
|
||||
: <bytestream>/fwrite ( string -- )
|
||||
>bytes
|
||||
$out [ [ "byte" ] ]
|
||||
"java.io.OutputStream" "write" jinvoke ;
|
||||
|
||||
: <bytestream>/fflush ( -- )
|
||||
$out [ ] "java.io.OutputStream" "flush" jinvoke ;
|
||||
|
||||
: <bytestream>/fclose ( -- )
|
||||
$in [ ] "java.io.InputStream" "close" jinvoke
|
||||
$out [ ] "java.io.OutputStream" "close" jinvoke ;
|
||||
|
||||
: <bytestream> ( in out -- stream )
|
||||
! Creates a new stream for reading from the java.io.InputStream in, and
|
||||
! writing to the java.io.OutputStream out.
|
||||
! Creates a new stream for reading from the
|
||||
! java.io.InputStream in, and writing to the
|
||||
! java.io.OutputStream out.
|
||||
<stream> [
|
||||
@out
|
||||
@in
|
||||
|
||||
( -- string )
|
||||
[
|
||||
$in [ "java.io.InputStream" ] "factor.FactorLib" "readLine"
|
||||
jmethod jinvokeStatic
|
||||
] @freadln
|
||||
|
||||
[ <bytestream>/freadln ] @freadln
|
||||
( string -- )
|
||||
[
|
||||
>bytes
|
||||
$out [ "[B" ] "java.io.OutputStream" "write" jmethod jinvoke
|
||||
] @fwrite
|
||||
|
||||
[ <bytestream>/fwrite ] @fwrite
|
||||
( -- )
|
||||
[
|
||||
$out [ ] "java.io.OutputStream" "flush" jmethod jinvoke
|
||||
] @fflush
|
||||
|
||||
[ <bytestream>/fflush ] @fflush
|
||||
( -- )
|
||||
[
|
||||
$in [ ] "java.io.InputStream" "close" jmethod jinvoke
|
||||
$out [ ] "java.io.OutputStream" "close" jmethod jinvoke
|
||||
] @fclose
|
||||
[ <bytestream>/fclose ] @fclose
|
||||
] extend ;
|
||||
|
||||
: <charstream>/freadln ( -- string )
|
||||
$in [ ] "java.io.BufferedReader" "readLine"
|
||||
jinvoke ;
|
||||
|
||||
: <charstream>/fwrite ( string -- )
|
||||
$out [ "java.lang.String" ] "java.io.Writer" "write"
|
||||
jinvoke ;
|
||||
|
||||
: <charstream>/fflush ( -- )
|
||||
$out [ ] "java.io.Writer" "flush" jinvoke ;
|
||||
|
||||
: <charstream>/fclose ( -- )
|
||||
$in [ ] "java.io.Reader" "close" jinvoke
|
||||
$out [ ] "java.io.Writer" "close" jinvoke ;
|
||||
|
||||
: <charstream> ( in out -- stream )
|
||||
! Creates a new stream for reading from the java.io.BufferedReader in, and
|
||||
! writing to the java.io.Reader out.
|
||||
! Creates a new stream for reading from the
|
||||
! java.io.BufferedReader in, and writing to the
|
||||
! java.io.Reader out.
|
||||
<stream> [
|
||||
@out
|
||||
@in
|
||||
|
||||
( -- string )
|
||||
[
|
||||
$in [ ] "java.io.BufferedReader" "readLine" jmethod jinvoke
|
||||
] @freadln
|
||||
|
||||
[ <charstream>/freadln ] @freadln
|
||||
( string -- )
|
||||
[
|
||||
$out [ "java.lang.String" ] "java.io.Writer" "write" jmethod jinvoke
|
||||
] @fwrite
|
||||
|
||||
[ <charstream>/fwrite ] @fwrite
|
||||
( -- )
|
||||
[
|
||||
$out [ ] "java.io.Writer" "flush" jmethod jinvoke
|
||||
] @fflush
|
||||
|
||||
[ <charstream>/fflush ] @fflush
|
||||
( -- )
|
||||
[
|
||||
$in [ ] "java.io.Reader" "close" jmethod jinvoke
|
||||
$out [ ] "java.io.Writer" "close" jmethod jinvoke
|
||||
] @fclose
|
||||
[ <charstream>/fclose ] @fclose
|
||||
] extend ;
|
||||
|
||||
: <filecr> ( path -- stream )
|
||||
[ |java.lang.String ] |java.io.FileReader jconstructor jnew <breader>
|
||||
[ |java.lang.String ] |java.io.FileReader jnew <breader>
|
||||
f
|
||||
<charstream> ;
|
||||
|
||||
: <filecw> ( path -- stream )
|
||||
f
|
||||
[ |java.lang.String ] |java.io.FileWriter jconstructor jnew <bwriter>
|
||||
[ |java.lang.String ] |java.io.FileWriter jnew <bwriter>
|
||||
<charstream> ;
|
||||
|
||||
: <filebr> ( path -- stream )
|
||||
[ |java.lang.String ] |java.io.FileInputStream jconstructor jnew
|
||||
[ |java.lang.String ] |java.io.FileInputStream jnew
|
||||
f
|
||||
<bytestream> ;
|
||||
|
||||
: <filebw> ( path -- stream )
|
||||
f
|
||||
[ |java.lang.String ] |java.io.FileOutputStream jconstructor jnew
|
||||
[ |java.lang.String ] |java.io.FileOutputStream jnew
|
||||
<bytestream> ;
|
||||
|
||||
: <bwriter> (writer -- bwriter)
|
||||
[ |java.io.Writer ] |java.io.BufferedWriter jconstructor jnew ;
|
||||
[ |java.io.Writer ] |java.io.BufferedWriter jnew ;
|
||||
|
||||
: <owriter> (outputstream -- owriter)
|
||||
[ |java.io.OutputStream ] |java.io.OutputStreamWriter jconstructor jnew ;
|
||||
[ |java.io.OutputStream ] |java.io.OutputStreamWriter jnew ;
|
||||
|
||||
: read ( -- string )
|
||||
$stdio freadln ;
|
||||
|
@ -165,30 +173,30 @@
|
|||
[ [ $in ] bind ] dip
|
||||
[ $out ] bind
|
||||
[ "java.io.InputStream" "java.io.OutputStream" ]
|
||||
"factor.FactorLib" "copy" jmethod jinvokeStatic ;
|
||||
"factor.FactorLib" "copy" jinvoke-static ;
|
||||
|
||||
"java.lang.System" "in" jfield jvarStatic$ <ireader> <breader> @stdin
|
||||
"java.lang.System" "out" jfield jvarStatic$ <owriter> @stdout
|
||||
"java.lang.System" "in" jvar-static$ <ireader> <breader> @stdin
|
||||
"java.lang.System" "out" jvar-static$ <owriter> @stdout
|
||||
$stdin $stdout <charstream> @stdio
|
||||
|
||||
!(file -- freader)
|
||||
|<freader> [
|
||||
[ |java.lang.String ] |java.io.FileReader jconstructor jnew <breader>
|
||||
[ |java.lang.String ] |java.io.FileReader jnew <breader>
|
||||
] define
|
||||
|
||||
: <file> (path -- file)
|
||||
dup "java.io.File" is not [
|
||||
[ "java.lang.String" ] "java.io.File" jconstructor jnew
|
||||
[ "java.lang.String" ] "java.io.File" jnew
|
||||
] when ;
|
||||
|
||||
: exists? (file -- boolean)
|
||||
<file> [ ] "java.io.File" "exists" jmethod jinvoke ;
|
||||
<file> [ ] "java.io.File" "exists" jinvoke ;
|
||||
|
||||
: directory? (file -- boolean)
|
||||
<file> [ ] "java.io.File" "isDirectory" jmethod jinvoke ;
|
||||
<file> [ ] "java.io.File" "isDirectory" jinvoke ;
|
||||
|
||||
: directory ( file -- listing )
|
||||
<file> [ ] "java.io.File" "list" jmethod jinvoke
|
||||
<file> [ ] "java.io.File" "list" jinvoke
|
||||
array>list ;
|
||||
|
||||
: rename ( from to -- )
|
||||
|
@ -196,26 +204,27 @@ $stdin $stdout <charstream> @stdio
|
|||
! java.io.File instances.
|
||||
<file> swap <file>
|
||||
[ "java.io.File" ] "java.io.File" "renameTo"
|
||||
jmethod jinvoke ;
|
||||
jinvoke ;
|
||||
|
||||
!(string -- reader)
|
||||
|<sreader> [
|
||||
[ |java.lang.String ] |java.io.StringReader jconstructor jnew
|
||||
[ |java.lang.String ] |java.io.StringReader jnew
|
||||
] define
|
||||
|
||||
: close (stream --)
|
||||
dup "java.io.Reader" is
|
||||
[ ] "java.io.Reader" "close" jmethod
|
||||
[ ] "java.io.Writer" "close" jmethod
|
||||
?
|
||||
jinvoke ;
|
||||
dup "java.io.Reader" is [
|
||||
[ ] "java.io.Reader" "close" jinvoke
|
||||
] [
|
||||
[ ] "java.io.Writer" "close" jinvoke
|
||||
] ifte ;
|
||||
|
||||
: exec (args -- exitCode)
|
||||
[ "[Ljava.lang.String;" ] "factor.FactorLib" "exec" jmethod jinvokeStatic ;
|
||||
: exec ( args -- exitCode )
|
||||
[ [ "java.lang.String" ] ] "factor.FactorLib" "exec"
|
||||
jinvoke-static ;
|
||||
|
||||
!(stream -- string)
|
||||
|read* [
|
||||
[ ] |java.io.BufferedReader |readLine jmethod jinvoke
|
||||
[ ] |java.io.BufferedReader |readLine jinvoke
|
||||
] define
|
||||
|
||||
: print* (string stream --)
|
||||
|
@ -225,6 +234,6 @@ $stdin $stdout <charstream> @stdio
|
|||
!(string stream --)
|
||||
|write* [
|
||||
tuck
|
||||
[ |java.lang.String ] |java.io.Writer |write jmethod jinvoke
|
||||
[ ] |java.io.Writer |flush jmethod jinvoke
|
||||
[ |java.lang.String ] |java.io.Writer |write jinvoke
|
||||
[ ] |java.io.Writer |flush jinvoke
|
||||
] define
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
! $Id$
|
||||
!
|
||||
! Copyright (C) 2003 Slava Pestov.
|
||||
! Copyright (C) 2003, 2004 Slava Pestov.
|
||||
!
|
||||
! Redistribution and use in source and binary forms, with or without
|
||||
! modification, are permitted provided that the following conditions are met:
|
||||
|
@ -35,103 +35,186 @@
|
|||
! [ #\" , """ ]
|
||||
] @entities
|
||||
|
||||
: >str ( obj -- string )
|
||||
! Returns the Java string representation of this object.
|
||||
[ ] "java.lang.Object" "toString" jinvoke ;
|
||||
|
||||
: >bytes ( string -- array )
|
||||
! Converts a string to an array of ASCII bytes. An exception is thrown
|
||||
! if the string contains non-ASCII characters.
|
||||
! Converts a string to an array of ASCII bytes. An exception
|
||||
! is thrown if the string contains non-ASCII characters.
|
||||
"ASCII" swap
|
||||
[ "java.lang.String" ] "java.lang.String" "getBytes" jmethod jinvoke ;
|
||||
[ "java.lang.String" ] "java.lang.String" "getBytes"
|
||||
jinvoke ;
|
||||
|
||||
: cat ([ "a" "b" "c" ] -- "abc")
|
||||
[ "factor.FactorList" ] "factor.FactorLib" "cat" jmethod jinvokeStatic ;
|
||||
: <sbuf> ( -- StringBuffer )
|
||||
[ ] "java.lang.StringBuffer" jnew ;
|
||||
|
||||
: cat2 ("a" "b" -- "ab")
|
||||
[ "java.lang.Object" "java.lang.Object" ]
|
||||
"factor.FactorLib" "cat2" jmethod jinvokeStatic ;
|
||||
: sbuf-append ( str buf -- buf )
|
||||
[ "java.lang.String" ] "java.lang.StringBuffer" "append"
|
||||
jinvoke ;
|
||||
|
||||
: cat3 ("a" "b" "c" -- "abc")
|
||||
[ "java.lang.Object" "java.lang.Object" "java.lang.Object" ]
|
||||
"factor.FactorLib" "cat3" jmethod jinvokeStatic ;
|
||||
: cat ( [ "a" "b" "c" ] -- "abc" )
|
||||
! If f appears in the list, it is not appended to the
|
||||
! string.
|
||||
<sbuf> swap [ [ swap sbuf-append ] when* ] each >str ;
|
||||
|
||||
: cat4 ("a" "b" "c" "d" -- "abcd")
|
||||
cat2 cat3 ;
|
||||
: cat2 ( "a" "b" -- "ab" )
|
||||
swap <sbuf> sbuf-append sbuf-append >str ;
|
||||
|
||||
: chars>entities (str -- str)
|
||||
: cat3 ( "a" "b" "c" -- "abc" )
|
||||
[ ] cons cons cons cat ;
|
||||
|
||||
: cat4 ( "a" "b" "c" "d" -- "abcd" )
|
||||
[ ] cons cons cons cons cat ;
|
||||
|
||||
: char? ( obj -- boolean )
|
||||
"java.lang.Character" is ;
|
||||
|
||||
: chars>entities ( str -- str )
|
||||
! Convert <, >, &, ' and " to HTML entities.
|
||||
"" [ dup $entities assoc dup [ nip ] [ drop ] ifte ] strmap ;
|
||||
[ dup $entities assoc dup [ nip ] [ drop ] ifte ] strmap ;
|
||||
|
||||
: group (index match --)
|
||||
: group ( index match -- )
|
||||
[ "int" ] "java.util.regex.Matcher" "group"
|
||||
jmethod jinvoke ;
|
||||
jinvoke ;
|
||||
|
||||
: groupCount (matcher -- count)
|
||||
: group-count ( matcher -- count )
|
||||
[ ] "java.util.regex.Matcher" "groupCount"
|
||||
jmethod jinvoke ;
|
||||
jinvoke ;
|
||||
|
||||
: groups* (matcher -- list)
|
||||
: groups* ( matcher -- list )
|
||||
[
|
||||
[
|
||||
dup groupCount [
|
||||
dup group-count [
|
||||
succ over group swap
|
||||
] times* drop
|
||||
] cons expand
|
||||
] [matches] ;
|
||||
] [re-matches] ;
|
||||
|
||||
: groups (input regex -- list)
|
||||
: groups ( input regex -- list )
|
||||
<regex> <matcher> groups* ;
|
||||
|
||||
: [matches] ( matcher code -- boolean )
|
||||
! If the matcher's matches* function returns true,
|
||||
: index-of* ( index string substring -- index )
|
||||
dup char? [
|
||||
-rot
|
||||
! Why is the first parameter an int and not a char?
|
||||
[ "int" "int" ]
|
||||
"java.lang.String" "indexOf"
|
||||
jinvoke
|
||||
] [
|
||||
-rot
|
||||
[ "java.lang.String" "int" ]
|
||||
"java.lang.String" "indexOf"
|
||||
jinvoke
|
||||
] ifte ;
|
||||
|
||||
: index-of ( string substring -- index )
|
||||
0 -rot index-of* ;
|
||||
|
||||
: [re-matches] ( matcher code -- boolean )
|
||||
! If the matcher's re-matches* function returns true,
|
||||
! evaluate the code with the matcher at the top of the
|
||||
! stack. Otherwise, pop the matcher off the stack and
|
||||
! push f.
|
||||
[ dup matches* ] dip [ drop f ] ifte ;
|
||||
[ dup re-matches* ] dip [ drop f ] ifte ;
|
||||
|
||||
: <matcher> (string pattern -- matcher)
|
||||
: <matcher> ( string pattern -- matcher )
|
||||
[ "java.lang.CharSequence" ]
|
||||
"java.util.regex.Pattern" "matcher"
|
||||
jmethod jinvoke ;
|
||||
jinvoke ;
|
||||
|
||||
: matches* (matcher -- boolean)
|
||||
: re-matches* ( matcher -- boolean )
|
||||
[ ] "java.util.regex.Matcher" "matches"
|
||||
jmethod jinvoke ;
|
||||
jinvoke ;
|
||||
|
||||
: matches (input regex -- boolean)
|
||||
<regex> <matcher> matches* ;
|
||||
: re-matches ( input regex -- boolean )
|
||||
<regex> <matcher> re-matches* ;
|
||||
|
||||
: replace* ( replace matcher -- string )
|
||||
: re-replace* ( replace matcher -- string )
|
||||
[ "java.lang.String" ] "java.util.regex.Matcher"
|
||||
"replaceAll" jmethod jinvoke ;
|
||||
"replaceAll" jinvoke ;
|
||||
|
||||
: replace ( input regex replace -- string )
|
||||
: re-replace ( input regex replace -- string )
|
||||
! Replaces all occurrences of the regex in the input string
|
||||
! with the replace string.
|
||||
-rot <regex> <matcher> replace* ;
|
||||
-rot <regex> <matcher> re-replace* ;
|
||||
|
||||
: re-split ( string split -- list )
|
||||
<regex> [ "java.lang.CharSequence" ]
|
||||
"java.util.regex.Pattern" "split" jinvoke array>list ;
|
||||
|
||||
: <regex> (pattern -- regex)
|
||||
! Compile the regex, if its not already compiled.
|
||||
dup "java.util.regex.Pattern" is not [
|
||||
[ "java.lang.String" ] "java.util.regex.Pattern" "compile"
|
||||
jmethod jinvokeStatic
|
||||
[ "java.lang.String" ]
|
||||
"java.util.regex.Pattern" "compile"
|
||||
jinvoke-static
|
||||
] when ;
|
||||
|
||||
: strget (index str -- char)
|
||||
[ "int" ] "java.lang.String" "charAt" jmethod jinvoke ;
|
||||
: split ( string split -- list )
|
||||
2dup index-of dup -1 = [
|
||||
2drop unit
|
||||
] [
|
||||
swap [ str// ] dip split cons
|
||||
] ifte ;
|
||||
|
||||
: strlen (str -- length)
|
||||
[ ] "java.lang.String" "length" jmethod jinvoke ;
|
||||
: str/ ( str index -- str str )
|
||||
! Returns 2 strings, that when concatenated yield the
|
||||
! original string.
|
||||
2dup strtail [ str-head ] dip ;
|
||||
|
||||
: streach (str [ code ] --)
|
||||
! Execute the code, with each character of the string pushed onto the
|
||||
! stack.
|
||||
over strlen [
|
||||
-rot 2dup [ [ strget ] dip call ] 2dip
|
||||
: str// ( str index -- str str )
|
||||
! Returns 2 strings, that when concatenated yield the
|
||||
! original string, without the character at the given
|
||||
! index.
|
||||
2dup succ strtail [ str-head ] dip ;
|
||||
|
||||
: str-each ( str [ code ] -- )
|
||||
! Execute the code, with each character of the string pushed
|
||||
! onto the stack.
|
||||
over str-length [
|
||||
-rot 2dup [ [ str-get ] dip call ] 2dip
|
||||
] times* 2drop ;
|
||||
|
||||
: strmap (str initial [ code ] -- [ mapping ])
|
||||
! If the 'initial' parameter is f, turn it into "".
|
||||
! Maybe cat should handle this instead?
|
||||
[ dup [ drop "" ] unless ] dip
|
||||
swapd [ ] cons cons cons
|
||||
restack
|
||||
streach
|
||||
unstack cat ;
|
||||
: str-expand ( [ code ] -- str )
|
||||
expand cat ;
|
||||
|
||||
: str-get (index str -- char)
|
||||
[ "int" ] "java.lang.String" "charAt" jinvoke ;
|
||||
|
||||
: str-head ( str index -- str )
|
||||
! Returns a new string, from the beginning of the string
|
||||
! until the given index.
|
||||
0 transp substring ;
|
||||
|
||||
: str-headcut ( str begin -- str str )
|
||||
str-length str/ ;
|
||||
|
||||
: str-head? ( str begin -- str )
|
||||
! If the string starts with begin, return the rest of the
|
||||
! string after begin. Otherwise, return f.
|
||||
2dup str-length> [
|
||||
tuck str-headcut
|
||||
[ = ] dip f ?
|
||||
] [
|
||||
2drop f
|
||||
] ifte ;
|
||||
|
||||
: str-length ( str -- length )
|
||||
[ ] "java.lang.String" "length" jinvoke ;
|
||||
|
||||
: str-length> ( str str -- boolean )
|
||||
! Compare string lengths.
|
||||
[ str-length ] apply2 > ;
|
||||
|
||||
: str-map ( str [ code ] -- [ mapping ] )
|
||||
2list restack str-each unstack cat ;
|
||||
|
||||
: strtail ( str index -- str )
|
||||
! Returns a new string, from the given index until the end
|
||||
! of the string.
|
||||
over str-length rot substring ;
|
||||
|
||||
: substring ( start end str -- str )
|
||||
[ "int" "int" ] "java.lang.String" "substring"
|
||||
jinvoke ;
|
||||
|
|
|
@ -1 +1 @@
|
|||
"0.29" @version
|
||||
"0.36" @version
|
||||
|
|
Loading…
Reference in New Issue