]> gitweb.factorcode.org Git - factor.git/commitdiff
Factor jEdit plugin!
authorSlava Pestov <slava@factorcode.org>
Fri, 6 Aug 2004 06:51:32 +0000 (06:51 +0000)
committerSlava Pestov <slava@factorcode.org>
Fri, 6 Aug 2004 06:51:32 +0000 (06:51 +0000)
27 files changed:
TODO.FACTOR.txt
build.sh
build.xml
factor/jedit/FactorPlugin.java [new file with mode: 0644]
factor/jedit/FactorPlugin.props [new file with mode: 0644]
factor/listener/FactorDesktop.java
factor/listener/FactorListenerPanel.java [new file with mode: 0644]
library/cross-compiler.factor
library/image.factor
library/init.factor
library/platform/jvm/arithmetic.factor
library/platform/jvm/init.factor
library/platform/jvm/listener.factor
library/platform/native/arithmetic.factor
library/platform/native/errors.factor
library/platform/native/init.factor
library/platform/native/unparser.factor
native/bignum.h
native/complex.c [new file with mode: 0644]
native/complex.h [new file with mode: 0644]
native/error.h
native/float.c
native/float.h
native/primitives.c
native/primitives.h
native/types.c
native/types.h

index 1c66319c131ebf5740f9688ad607d49f596d2d1a..9415c55bc75ff56d0ff72ad56fb6c7f16bd800dd 100644 (file)
@@ -1,5 +1,16 @@
+- java factor memory leak\r
+- tail call optimization broken again\r
+\r
++ listener:\r
+\r
+- link style lingers\r
+- back space then type: input style gone\r
+- fedit broken with listener\r
+- press enter in the middle of a line\r
+\r
 + native:\r
 \r
+- native float>bits\r
 - printing floats: append .0 always\r
 - vector=\r
 - make-image: take a parameter, include le & be images in dist\r
@@ -32,17 +43,8 @@ ERROR: I/O error: [ "primitive_read_line_fd_8" "Resource temporarily unavailable
 - FactorLib.equal() not very good\r
 - IN: format base: work with all types of numbers\r
 \r
-+ listener:\r
-\r
-- link style lingers\r
-- back space then type: input style gone\r
-- fedit broken with listener\r
-- press enter in the middle of a line\r
-- new-listener shouldn't suspend continuation in current listener\r
-\r
 + compiler:\r
 \r
-- tail call optimization broken again\r
 - don't compile inline words\r
 - recursive words with code after ifte\r
 - less unnecessary args to auxiliary methods\r
index 056f96997ce2a3a652a39442c364bd0543a82f60..8904f745207664c56965e3658c456aaccbed146b 100644 (file)
--- a/build.sh
+++ b/build.sh
@@ -1,5 +1,5 @@
 export CC=gcc34
-export CFLAGS="-pedantic -Wall -Winline -Os -march=pentium4 -fomit-frame-pointer"
+export CFLAGS="-pedantic -Wall -Winline -O3 -march=pentium4 -fomit-frame-pointer"
 
 $CC $CFLAGS -o f native/*.c
 
index 81dd7086dc7ed96dc97bc85a67a6305b31a6bbd5..08922392c3e9f317fa5003257356eda5d03471b5 100644 (file)
--- a/build.xml
+++ b/build.xml
                        optimize="true"
                >
                <include name="**/*.java"/>
+               <exclude name="factor/jedit/*.java"/>
                </javac>
        </target>
-       <target name="dist" depends="compile">
+       <target name="compile-jedit">
+               <javac
+                       srcdir="."
+                       destdir="."
+                       deprecation="on"
+                       includeJavaRuntime="yes"
+                       debug="true"
+                       optimize="true"
+               >
+               <include name="factor/jedit/*.java"/>
+               </javac>
+       </target>
+       <target name="dist" depends="compile,compile-jedit">
                <jar
                        jarfile="Factor.jar"
                        manifest="Factor.manifest"
@@ -23,6 +36,8 @@
                        <fileset dir=".">
                                <include name="factor/*.class"/>
                                <include name="factor/**/*.class"/>
+                               <include name="factor/**/*.props"/>
+                               <include name="*.xml"/>
                                <include name="library/**/*.factor"/>
                                <include name="org/**/*.class"/>
                                <include name="*.factor"/>
diff --git a/factor/jedit/FactorPlugin.java b/factor/jedit/FactorPlugin.java
new file mode 100644 (file)
index 0000000..786519a
--- /dev/null
@@ -0,0 +1,53 @@
+/* :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.jedit;
+
+import factor.listener.FactorListenerPanel;
+import factor.FactorInterpreter;
+import org.gjt.sp.jedit.*;
+import java.util.WeakHashMap;
+
+public class FactorPlugin extends EditPlugin
+{
+       private static WeakHashMap views = new WeakHashMap();
+
+       public static FactorInterpreter getInterpreter(View view)
+       {
+               FactorInterpreter interp = (FactorInterpreter)
+                       views.get(view);
+               if(interp == null)
+               {
+                       interp = FactorListenerPanel.newInterpreter(
+                               new String[] { "-jedit" });
+                       views.put(view,interp);
+               }
+               return interp;
+       }
+}
diff --git a/factor/jedit/FactorPlugin.props b/factor/jedit/FactorPlugin.props
new file mode 100644 (file)
index 0000000..cd17135
--- /dev/null
@@ -0,0 +1,21 @@
+### Plugin properties
+
+plugin.factor.jedit.FactorPlugin.activate=defer
+
+plugin.factor.jedit.FactorPlugin.name=Factor
+plugin.factor.jedit.FactorPlugin.version=0.60.10
+plugin.factor.jedit.FactorPlugin.author=Slava Pestov
+plugin.factor.jedit.FactorPlugin.docs=index.html
+
+plugin.factor.jedit.FactorPlugin.depend.0=jedit 04.02.15.00
+
+plugin.factor.jedit.FactorPlugin.menu=factor \
+       - \
+       factor-run-file \
+       factor-eval-selection
+
+factor.label=Factor Listener
+factor-run-file.label=Run Current File
+factor-eval-selection.label=Evaluate Selection
+
+factor.title=Factor
index e3e8075aab1d3336940172a456cad9f5e830bd56..4308b07df2f811f0b21bfb977f2d5b6a45e98d82 100644 (file)
@@ -39,11 +39,6 @@ import javax.swing.text.html.*;
 
 public class FactorDesktop extends JFrame
 {
-       private JTabbedPane tabs;
-       private FactorInterpreter interp;
-       private boolean standalone;
-       private Map listeners;
-
        //{{{ main() method
        public static void main(String[] args)
        {
@@ -54,26 +49,10 @@ public class FactorDesktop extends JFrame
        public FactorDesktop(String[] args, boolean standalone)
        {
                super("Factor");
-               tabs = new JTabbedPane();
-               this.standalone = standalone;
-               listeners = new HashMap();
-
-               getContentPane().add(BorderLayout.CENTER,tabs);
 
-               try
-               {
-                       interp = new FactorInterpreter();
-                       interp.interactive = false;
-                       interp.init(args,null);
-                       interp.global.setVariable("desktop",this);
-               }
-               catch(Exception e)
-               {
-                       System.err.println("Failed to initialize interpreter:");
-                       e.printStackTrace();
-               }
-
-               newListener();
+               getContentPane().add(BorderLayout.CENTER,
+                       new FactorListenerPanel(
+                       FactorListenerPanel.newInterpreter(args)));
 
                setSize(640,480);
                setDefaultCloseOperation(standalone
@@ -81,100 +60,4 @@ public class FactorDesktop extends JFrame
                        : DISPOSE_ON_CLOSE);
                show();
        } //}}}
-
-       //{{{ newListener() method
-       public FactorListener newListener()
-       {
-               final FactorListener listener = new FactorListener();
-               listener.addEvalListener(new EvalHandler());
-
-               try
-               {
-                       interp.call(new Cons(listener,
-                               new Cons(interp.searchVocabulary(
-                                       "listener","new-listener-hook"),
-                               null)));
-                       interp.run();
-               }
-               catch(Exception e)
-               {
-                       System.err.println("Failed to initialize listener:");
-                       e.printStackTrace();
-               }
-
-               JScrollPane scroller = new JScrollPane(listener);
-               listeners.put(listener,scroller);
-               tabs.addTab("Listener",scroller);
-
-               SwingUtilities.invokeLater(new Runnable()
-               {
-                       public void run()
-                       {
-                               listener.requestFocus();
-                       }
-               });
-
-               return listener;
-       } //}}}
-
-       //{{{ closeListener() method
-       public void closeListener(FactorListener listener)
-       {
-               // remove tab containing the listener
-               tabs.remove((Component)listeners.get(listener));
-               if(tabs.getTabCount() == 0)
-               {
-                       if(standalone)
-                               System.exit(0);
-                       else
-                               dispose();
-               }
-       } //}}}
-
-       //{{{ getInterpreter() method
-       public FactorInterpreter getInterpreter()
-       {
-               return interp;
-       } //}}}
-
-       //{{{ eval() method
-       public void eval(Cons cmd)
-       {
-               try
-               {
-                       interp.call(cmd);
-                       interp.run();
-               }
-               catch(Exception e)
-               {
-                       System.err.println("Failed to eval " + cmd + ":");
-                       e.printStackTrace();
-               }
-       } //}}}
-
-       //{{{ EvalHandler class
-       class EvalHandler implements EvalListener
-       {
-               public void eval(Cons cmd)
-               {
-                       FactorDesktop.this.eval(cmd);
-               }
-       } //}}}
-
-       //{{{ EvalAction class
-       class EvalAction extends AbstractAction
-       {
-               private Cons code;
-
-               public EvalAction(String label, Cons code)
-               {
-                       super(label);
-                       this.code = code;
-               }
-
-               public void actionPerformed(ActionEvent evt)
-               {
-                       FactorDesktop.this.eval(code);
-               }
-       } //}}}
 }
diff --git a/factor/listener/FactorListenerPanel.java b/factor/listener/FactorListenerPanel.java
new file mode 100644 (file)
index 0000000..5eadd78
--- /dev/null
@@ -0,0 +1,133 @@
+/* :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.listener;
+
+import factor.*;
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.text.*;
+import javax.swing.text.html.*;
+
+public class FactorListenerPanel extends JPanel
+{
+       private FactorInterpreter interp;
+       private FactorListener listener;
+
+       //{{{ newInterpreter() method
+       public static FactorInterpreter newInterpreter(String[] args)
+       {
+               try
+               {
+                       FactorInterpreter interp = new FactorInterpreter();
+                       interp.interactive = false;
+                       interp.init(args,null);
+                       return interp;
+               }
+               catch(Exception e)
+               {
+                       System.err.println("Failed to initialize interpreter:");
+                       e.printStackTrace();
+                       return null;
+               }
+       } //}}}
+
+       //{{{ FactorListenerPanel constructor
+       public FactorListenerPanel(FactorInterpreter interp)
+       {
+               setLayout(new BorderLayout());
+
+               this.interp = interp;
+
+               add(BorderLayout.CENTER,new JScrollPane(
+                       listener = newListener()));
+       } //}}}
+
+       //{{{ newListener() method
+       private FactorListener newListener()
+       {
+               final FactorListener listener = new FactorListener();
+               listener.addEvalListener(new EvalHandler());
+
+               try
+               {
+                       interp.call(new Cons(listener,
+                               new Cons(interp.searchVocabulary(
+                                       "listener","new-listener-hook"),
+                               null)));
+                       interp.run();
+               }
+               catch(Exception e)
+               {
+                       System.err.println("Failed to initialize listener:");
+                       e.printStackTrace();
+               }
+
+               return listener;
+       } //}}}
+
+       //{{{ requestDefaultFocus() method
+       public boolean requestDefaultFocus()
+       {
+               listener.requestFocus();
+               return true;
+       } //}}}
+
+       //{{{ getInterpreter() method
+       public FactorInterpreter getInterpreter()
+       {
+               return interp;
+       } //}}}
+
+       //{{{ eval() method
+       public void eval(Cons cmd)
+       {
+               try
+               {
+                       interp.call(cmd);
+                       interp.run();
+               }
+               catch(Exception e)
+               {
+                       System.err.println("Failed to eval " + cmd + ":");
+                       e.printStackTrace();
+               }
+       } //}}}
+
+       //{{{ EvalHandler class
+       class EvalHandler implements EvalListener
+       {
+               public void eval(Cons cmd)
+               {
+                       FactorListenerPanel.this.eval(cmd);
+               }
+       } //}}}
+}
index 89d61b4e0e0b4786af4baf7fefa6afaa91034155..5a5a198769aff351a2955a84987efea7bb109eb0 100644 (file)
@@ -51,6 +51,8 @@ DEFER: save-image
 DEFER: handle?
 DEFER: room
 DEFER: os-env
+DEFER: type-of
+DEFER: size-of
 
 IN: strings
 DEFER: str=
@@ -134,6 +136,7 @@ IN: cross-compiler
         float?
         str>float
         unparse-float
+        float>bits
         complex?
         real
         imaginary
@@ -199,6 +202,8 @@ IN: cross-compiler
         millis
         init-random
         (random-int)
+        type-of
+        size-of
     ] [
         swap succ tuck primitive,
     ] each drop ;
index a6566cd8b7cdecda190fcb59c7837e78c29614d5..ac7a1e8d42032e20952e61915e379d2d3c82ab0e 100644 (file)
@@ -48,6 +48,12 @@ USE: words
 
 : image "image" get ;
 : emit ( cell -- ) image vector-push ;
+
+: emit64 ( bignum -- )
+    #! Little endian byte order
+    dup HEX: ffffffff bitand emit
+    32 shift> HEX: ffffffff bitand emit ;
+
 : fixup ( value offset -- ) image set-vector-nth ;
 
 ( Object memory )
@@ -72,6 +78,17 @@ USE: words
 : header-tag   BIN: 110 ;
 : gc-fwd-ptr   BIN: 111 ; ( we don't output these )
 
+: f-type      6 ;
+: t-type      7 ;
+: empty-type  8 ;
+: array-type  9 ;
+: vector-type 10 ;
+: string-type 11 ;
+: sbuf-type   12 ;
+: handle-type 13 ;
+: bignum-type 14 ;
+: float-type  15 ;
+
 : immediate ( x tag -- tagged ) swap tag-bits shift< bitor ;
 : >header ( id -- tagged ) header-tag immediate ;
 
@@ -108,13 +125,31 @@ USE: words
 
 : 'fixnum ( n -- tagged ) fixnum-tag immediate ;
 
+( Floats )
+
+: 'float ( f -- tagged )
+    object-tag here-as
+    float-type >header emit
+    0 emit ( alignment -- FIXME 64-bit arch )
+    float>bits emit64 ;
+
+( Bignums )
+
+: 'bignum ( bignum -- tagged )
+    dup .
+    #! Very bad!
+    object-tag here-as
+    bignum-type >header emit
+    0 emit ( alignment -- FIXME 64-bit arch )
+    ( bignum -- ) emit64 ;
+
 ( Special objects )
 
 ! Padded with fixnums for 8-byte alignment
 
-: f, object-tag here-as "f" set 6 >header emit 0 'fixnum emit ;
-: t, object-tag here-as "t" set 7 >header emit 0 'fixnum emit ;
-: empty, 8 >header emit 0 'fixnum emit ;
+: f, object-tag here-as "f" set f-type >header emit 0 'fixnum emit ;
+: t, object-tag here-as "t" set t-type >header emit 0 'fixnum emit ;
+: empty, empty-type >header emit 0 'fixnum emit ;
 
 ( Beginning of the image )
 ! The image proper begins with the header, then EMPTY, F, T
@@ -184,7 +219,7 @@ DEFER: '
 
 : string, ( string -- )
     object-tag here-as swap
-    11 >header emit
+    string-type >header emit
     dup str-length emit
     dup hashcode emit
     pack-string
@@ -247,7 +282,7 @@ IN: cross-compiler
 : 'array ( list -- untagged )
     [ ' ] inject
     here >r
-    9 >header emit
+    array-type >header emit
     dup length emit
     ( elements -- ) [ emit ] each
     pad r> ;
@@ -255,7 +290,7 @@ IN: cross-compiler
 : 'vector ( vector -- pointer )
     dup vector>list 'array swap vector-length
     object-tag here-as >r
-    10 >header emit
+    vector-type >header emit
     emit ( length )
     emit ( array ptr )
     pad r> ;
@@ -265,6 +300,8 @@ IN: cross-compiler
 : ' ( obj -- pointer )
     [
         [ fixnum? ] [ 'fixnum      ]
+        [ bignum? ] [ 'bignum      ]
+        [ float?  ] [ 'float       ]
         [ word?   ] [ 'word        ]
         [ cons?   ] [ 'cons        ]
         [ char?   ] [ 'fixnum      ]
index 5f648e11a8397290f266217b47781c3fed1b0bb0..a4eb23b74e5e76810fbb4c72988802d5c18810b7 100644 (file)
@@ -134,6 +134,8 @@ USE: strings
         init-toplevel
 
         [
+            print-banner
+            room.
             interpreter-loop
         ] [
             [ default-error-handler suspend ] when*
index 34a7ee3a4bf955f06757ce37c850423181174646..a5b00683457deafcd89b1f1e32f1963784356df6 100644 (file)
@@ -143,3 +143,8 @@ USE: stack
 : gcd ( a b -- c )
     [ "java.lang.Number" "java.lang.Number" ]
     "factor.math.FactorMath" "gcd" jinvoke-static ;
+
+: float>bits ( f -- bignum )
+    [ "double" ]
+    "java.lang.Double" "doubleToRawLongBits"
+    jinvoke-static >bignum ;
index 10a1b23ab2b4a51f9c9460f8f0e3cfedd95e4a70..d15521ea742a1409b443f3e5ae413b245ecef320 100644 (file)
@@ -77,5 +77,4 @@ USE: strings
 
     t "startup-done" set
     
-    print-banner
     init-interpreter ;
index cbd9d3c0148a7a47c81e09a16d2f654e7cac3fc5..f332192848b09fbcd1d6ebd285865b21416ef1ce 100644 (file)
@@ -143,28 +143,12 @@ USE: unparser
         [ this fwrite "\n" this fwrite ] "fprint" set
     ] extend ;
 
-: close-listener ( listener -- )
-    #! Closes the listener. If no more listeners remain, the
-    #! desktop exits.
-    "desktop" get
-    [ "factor.listener.FactorListener" ]
-    "factor.listener.FactorDesktop" "closeListener"
-    jinvoke ;
-
 : new-listener-hook ( listener -- )
-    #! Called when user opens a new listener in the desktop.
+    #! Called when user opens a new listener
     <namespace> [
         dup "listener" set
         <listener-stream> "stdio" set
+        print-banner
+        room.
         interpreter-loop
-        "listener" get close-listener
     ] bind ;
-
-: new-listener ( -- )
-    #! Opens a new listener.
-    "desktop" get
-    [ ] "factor.listener.FactorDesktop" "newListener"
-    jinvoke ;
-
-: running-desktop? ( -- )
-    this "factor.listener.FactorDesktop" is ;
index e39f8e95862be8c5540aa1a25b09d941345ca842..0506083119c9200a3bd28b306980b4f844b9cc30 100644 (file)
@@ -22,3 +22,7 @@ USE: stack
 : succ 1 + ; inline
 
 : neg 0 swap - ; inline
+    
+!: e 2.7182818284590452354 ; inline
+!: pi 3.14159265358979323846 ; inline
+!: pi/2 1.5707963267948966 ; inline
index 19c08005e44ecf621fea2fd04b9cfb4e92fe1427..a6d7facfba51078c0e385acdfd6d36ccefe24a40 100644 (file)
@@ -64,6 +64,7 @@ USE: vectors
         "Incompatible handle: "
         "I/O error: "
         "Overflow"
+        "Incomparable types: "
     ] ?nth ;
 
 : ?kernel-error ( cons -- error# param )
index e80002f49cec6485426fff3931750cd812d882a1..bca2ff0e7689bfd3b78292cda5e0da935196088d 100644 (file)
@@ -75,10 +75,6 @@ USE: unparser
     init-styles
     init-vocab-styles
 
-    print-banner
-
     run-user-init
 
-    room.
-
     init-interpreter ;
index 881b450ea70dd7f9db105ecd910fdfd6ac11d036..27601bed06a80012900dffeb11ae2b9175471a39 100644 (file)
@@ -60,6 +60,9 @@ USE: vocabularies
     denominator integer- integer%
     %> ;
 
+: unparse-complex ( num -- str )
+    >rect <% "#{ " % swap unparse % " " % unparse % " }" % %> ;
+
 : >base ( num radix -- string )
     #! Convert a number to a string in a certain base.
     <namespace> [ "base" set unparse-integer ] bind ;
@@ -113,6 +116,7 @@ USE: vocabularies
         [ integer? ] [ unparse-integer ]
         [ ratio?   ] [ unparse-ratio ]
         [ float?   ] [ unparse-float ]
+        [ complex? ] [ unparse-complex ]
         [ string?  ] [ unparse-str ]
         [ drop t   ] [ <% "#<" % class-of % ">" % %> ]
     ] cond ;
index c9ebf0a221c644027242d2b8bc718a50e3365dee..ed1c4b9ebab3712d337eb9d6ea977ad9f9da9685 100644 (file)
@@ -2,6 +2,10 @@ typedef long long BIGNUM_2;
 
 typedef struct {
        CELL header;
+/* FIXME */
+#ifndef FACTOR_64
+       CELL alignment;
+#endif
        BIGNUM_2 n;
 } BIGNUM;
 
diff --git a/native/complex.c b/native/complex.c
new file mode 100644 (file)
index 0000000..eb6916d
--- /dev/null
@@ -0,0 +1,191 @@
+#include "factor.h"
+
+COMPLEX* complex(CELL real, CELL imaginary)
+{
+       COMPLEX* complex = allot(sizeof(COMPLEX));
+       complex->real = real;
+       complex->imaginary = imaginary;
+       return complex;
+}
+
+CELL possibly_complex(CELL real, CELL imaginary)
+{
+       if(zerop(imaginary))
+               return real;
+       else
+               return tag_complex(complex(real,imaginary));
+}
+
+void primitive_complexp(void)
+{
+       check_non_empty(env.dt);
+       env.dt = tag_boolean(typep(COMPLEX_TYPE,env.dt));
+}
+
+void primitive_real(void)
+{
+       switch(type_of(env.dt))
+       {
+       case FIXNUM_TYPE:
+       case BIGNUM_TYPE:
+       case FLOAT_TYPE:
+       case RATIO_TYPE:
+               /* No op */
+               break;
+       case COMPLEX_TYPE:
+               env.dt = untag_complex(env.dt)->real;
+               break;
+       default:
+               type_error(COMPLEX_TYPE,env.dt);
+               break;
+       }
+}
+
+void primitive_imaginary(void)
+{
+       switch(type_of(env.dt))
+       {
+       case FIXNUM_TYPE:
+       case BIGNUM_TYPE:
+       case FLOAT_TYPE:
+       case RATIO_TYPE:
+               env.dt = tag_fixnum(0);
+               break;
+       case COMPLEX_TYPE:
+               env.dt = untag_complex(env.dt)->imaginary;
+               break;
+       default:
+               type_error(COMPLEX_TYPE,env.dt);
+               break;
+       }
+}
+
+void primitive_to_rect(void)
+{
+       COMPLEX* c;
+       switch(type_of(env.dt))
+       {
+       case FIXNUM_TYPE:
+       case BIGNUM_TYPE:
+       case FLOAT_TYPE:
+       case RATIO_TYPE:
+               dpush(env.dt);
+               env.dt = tag_fixnum(0);
+               break;
+       case COMPLEX_TYPE:
+               c = untag_complex(env.dt);
+               env.dt = c->imaginary;
+               dpush(c->real);
+               break;
+       default:
+               type_error(COMPLEX_TYPE,env.dt);
+               break;
+       }
+}
+
+void primitive_from_rect(void)
+{
+       CELL imaginary = env.dt;
+       CELL real = dpop();
+       check_non_empty(imaginary);
+       check_non_empty(real);
+
+       if(!realp(imaginary))
+               type_error(REAL_TYPE,imaginary);
+
+       if(!realp(real))
+               type_error(REAL_TYPE,real);
+
+       env.dt = possibly_complex(real,imaginary);
+}
+
+CELL number_eq_complex(CELL x, CELL y)
+{
+       COMPLEX* cx = (COMPLEX*)UNTAG(x);
+       COMPLEX* cy = (COMPLEX*)UNTAG(y);
+       return tag_boolean(
+               untag_boolean(number_eq(cx->real,cy->real)) &&
+               untag_boolean(number_eq(cx->imaginary,cy->imaginary)));
+}
+
+CELL add_complex(CELL x, CELL y)
+{
+       COMPLEX* cx = (COMPLEX*)UNTAG(x);
+       COMPLEX* cy = (COMPLEX*)UNTAG(y);
+       return possibly_complex(
+               add(cx->real,cy->real),
+               add(cx->imaginary,cy->real));
+}
+
+CELL subtract_complex(CELL x, CELL y)
+{
+       COMPLEX* cx = (COMPLEX*)UNTAG(x);
+       COMPLEX* cy = (COMPLEX*)UNTAG(y);
+       return possibly_complex(
+               subtract(cx->real,cy->real),
+               subtract(cx->imaginary,cy->real));
+}
+
+CELL multiply_complex(CELL x, CELL y)
+{
+       COMPLEX* cx = (COMPLEX*)UNTAG(x);
+       COMPLEX* cy = (COMPLEX*)UNTAG(y);
+       return possibly_complex(
+               subtract(
+                       multiply(cx->real,cy->real),
+                       multiply(cx->imaginary,cy->imaginary)),
+               add(
+                       multiply(cx->real,cy->imaginary),
+                       multiply(cx->imaginary,cy->real)));
+}
+
+#define COMPLEX_DIVIDE(x,y) \
+       COMPLEX* cx = (COMPLEX*)UNTAG(x); \
+       COMPLEX* cy = (COMPLEX*)UNTAG(y); \
+\
+       CELL mag = add( \
+               multiply(cy->real,cy->real), \
+               multiply(cy->imaginary,cy->imaginary)); \
+\
+       CELL r = add( \
+               multiply(cx->real,cy->real), \
+               multiply(cx->imaginary,cy->imaginary)); \
+       CELL i = subtract( \
+               multiply(cx->imaginary,cy->real), \
+               multiply(cx->real,cy->imaginary));
+
+CELL divide_complex(CELL x, CELL y)
+{
+       COMPLEX_DIVIDE(x,y);
+       return possibly_complex(divide(r,mag),divide(i,mag));
+}
+
+CELL divfloat_complex(CELL x, CELL y)
+{
+       COMPLEX_DIVIDE(x,y);
+       return possibly_complex(divfloat(r,mag),divfloat(i,mag));
+}
+
+CELL less_complex(CELL x, CELL y)
+{
+       general_error(ERROR_INCOMPARABLE,tag_cons(cons(x,y)));
+       return F;
+}
+
+CELL lesseq_complex(CELL x, CELL y)
+{
+       general_error(ERROR_INCOMPARABLE,tag_cons(cons(x,y)));
+       return F;
+}
+
+CELL greater_complex(CELL x, CELL y)
+{
+       general_error(ERROR_INCOMPARABLE,tag_cons(cons(x,y)));
+       return F;
+}
+
+CELL greatereq_complex(CELL x, CELL y)
+{
+       general_error(ERROR_INCOMPARABLE,tag_cons(cons(x,y)));
+       return F;
+}
diff --git a/native/complex.h b/native/complex.h
new file mode 100644 (file)
index 0000000..0a6a4da
--- /dev/null
@@ -0,0 +1,34 @@
+typedef struct {
+       CELL real;
+       CELL imaginary;
+} COMPLEX;
+
+INLINE COMPLEX* untag_complex(CELL tagged)
+{
+       type_check(COMPLEX_TYPE,tagged);
+       return (COMPLEX*)UNTAG(tagged);
+}
+
+INLINE CELL tag_complex(RATIO* ratio)
+{
+       return RETAG(ratio,COMPLEX_TYPE);
+}
+
+COMPLEX* complex(CELL real, CELL imaginary);
+CELL possibly_complex(CELL real, CELL imaginary);
+
+void primitive_complexp(void);
+void primitive_real(void);
+void primitive_imaginary(void);
+void primitive_to_rect(void);
+void primitive_from_rect(void);
+CELL number_eq_complex(CELL x, CELL y);
+CELL add_complex(CELL x, CELL y);
+CELL subtract_complex(CELL x, CELL y);
+CELL multiply_complex(CELL x, CELL y);
+CELL divide_complex(CELL x, CELL y);
+CELL divfloat_complex(CELL x, CELL y);
+CELL less_complex(CELL x, CELL y);
+CELL lesseq_complex(CELL x, CELL y);
+CELL greater_complex(CELL x, CELL y);
+CELL greatereq_complex(CELL x, CELL y);
index 57d3be328bf102301632c572510e898ce1deef41..def830d0d76f52555f0de83c3eaafefa0c277e57 100644 (file)
@@ -7,6 +7,7 @@
 #define ERROR_HANDLE_INCOMPAT (6<<3)
 #define ERROR_IO (7<<3)
 #define ERROR_OVERFLOW (8<<3)
+#define ERROR_INCOMPARABLE (9<<3)
 
 void fatal_error(char* msg, CELL tagged);
 void critical_error(char* msg, CELL tagged);
index 92dbff6b164b4beee4e1bbe28c9886783e024ea4..5d2a8f1e804236f8a36925ee2a2c7918b5b48526 100644 (file)
@@ -43,6 +43,11 @@ void primitive_float_to_str(void)
        env.dt = tag_object(from_c_string(tmp));
 }
 
+void primitive_float_to_bits(void)
+{
+       /* FIXME */
+}
+
 CELL number_eq_float(CELL x, CELL y)
 {
        return tag_boolean(((FLOAT*)UNTAG(x))->n
index d4d7ecab9146c8ffe8542c2810b19a00e1e8d367..a001f22577fce94671236da706050225991b8084 100644 (file)
@@ -1,5 +1,9 @@
 typedef struct {
        CELL header;
+/* FIXME */
+#ifndef FACTOR_64
+       CELL alignment;
+#endif
        double n;
 } FLOAT;
 
@@ -21,6 +25,7 @@ FLOAT* to_float(CELL tagged);
 void primitive_to_float(void);
 void primitive_str_to_float(void);
 void primitive_float_to_str(void);
+void primitive_float_to_bits(void);
 CELL number_eq_float(CELL x, CELL y);
 CELL add_float(CELL x, CELL y);
 CELL subtract_float(CELL x, CELL y);
index e963313916a6d1a4fd1cfe095647a167db4d60b4..97a61f38eadea0531931b553e21e59c1c4567db2 100644 (file)
@@ -48,6 +48,7 @@ XT primitives[] = {
        primitive_floatp,
        primitive_str_to_float,
        primitive_float_to_str,
+       primitive_float_to_bits,
        primitive_complexp,
        primitive_real,
        primitive_imaginary,
@@ -112,7 +113,9 @@ XT primitives[] = {
        primitive_os_env,
        primitive_millis,
        primitive_init_random,
-       primitive_random_int
+       primitive_random_int,
+       primitive_type_of,
+       primitive_size_of
 };
 
 CELL primitive_to_xt(CELL primitive)
index 3847b25c062bff61d2265fc5193fadffec038931..fd371c7d8b6f29d3da462fd4e58f6ddb914d657c 100644 (file)
@@ -1,4 +1,4 @@
 extern XT primitives[];
-#define PRIMITIVE_COUNT 112
+#define PRIMITIVE_COUNT 115
 
 CELL primitive_to_xt(CELL primitive);
index ec7899abb08d1de8990885cb245952072d23f68c..413d1d5564ba745c67b9a270865411fa536afd36 100644 (file)
@@ -64,6 +64,9 @@ CELL object_size(CELL pointer)
 
        switch(TAG(pointer))
        {
+       case FIXNUM_TYPE:
+               size = 0;
+               break;
        case CONS_TYPE:
                size = sizeof(CONS);
                break;
@@ -130,3 +133,15 @@ CELL untagged_object_size(CELL pointer)
 
        return align8(size);
 }
+
+void primitive_type_of(void)
+{
+       check_non_empty(env.dt);
+       env.dt = tag_fixnum(type_of(env.dt));
+}
+
+void primitive_size_of(void)
+{
+       check_non_empty(env.dt);
+       env.dt = tag_fixnum(object_size(env.dt));
+}
index 5f12ce5c640dcd2770cd409a3fcea023d2ad0636..ea33053de27da7d89e776ccb4777c5afb2542c5b 100644 (file)
@@ -87,3 +87,5 @@ INLINE CELL object_type(CELL tagged)
 void* allot_object(CELL type, CELL length);
 CELL untagged_object_size(CELL pointer);
 CELL object_size(CELL pointer);
+void primitive_type_of(void);
+void primitive_size_of(void);