Skip to content

Commit

Permalink
progress on the time/date/duration trio
Browse files Browse the repository at this point in the history
Add Aryint same as Arylong.
Missing prim char equals in Const.
Missing 128 Add
Missing String quoted
ConvAST more parens wrapping; handles more cases.
Invoke int converts, null-strings more cases
Ternary can narrow
Missed places where construct -> $construct
Missed addNative
  • Loading branch information
cliffclick committed Nov 5, 2024
1 parent c550ce1 commit 07cb63e
Show file tree
Hide file tree
Showing 20 changed files with 286 additions and 60 deletions.
25 changes: 12 additions & 13 deletions javatools_backend/src/main/java/org/xvm/XEC.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
package org.xvm;

import org.xvm.xrun.*;
import org.xvm.xtc.FilePart;
import org.xvm.xtc.ModPart;
import org.xvm.xtc.Part;
import org.xvm.util.S;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import org.xvm.util.S;
import org.xvm.xrun.*;
import org.xvm.xtc.FilePart;
import org.xvm.xtc.ModPart;
import org.xvm.xtc.Part;

/**
Exploring XTC bytecodes. Fakes as a XEC runtime translator to JVM bytecodes.
Expand All @@ -31,9 +30,9 @@ public class XEC {

// The main Ecstasy module
public static ModPart ECSTASY;

// Main Launcher.
// Usage: (-L path)* [-M main] file.xtc args
// Usage: (-L path)* [-M main] file.xtc args
public static void main( String[] args ) throws IOException {

// Parse options
Expand All @@ -48,15 +47,15 @@ public static void main( String[] args ) throws IOException {
// Arguments
String[] xargs = args(ndx,args);


REPO = new ModRepo();
// Load XTC file into repo
ModPart mod = REPO.load(xtc);
// Load XDK
for( String lib : libs ) REPO.load(lib);
// Link the repo
REPO.link();

// Start the thread pool up
XRuntime.start();

Expand All @@ -65,7 +64,7 @@ public static void main( String[] args ) throws IOException {
// Start the initial container
MainContainer M = new MainContainer(N,mod);
CONTAINER.set(M);

/*Joinable J=*/M.invoke(xrun,xargs); // Returns something to join against
//J.join();
}
Expand All @@ -91,7 +90,7 @@ private static String xtc(int ndx, String[] args) {
System.err.println("Usage: xec (-L path)* [-M main] file.xtc args");
System.exit(1);
}

// File to parse
String xtc = args[ndx];
if( !xtc.endsWith(".xtc") ) {
Expand All @@ -100,7 +99,7 @@ private static String xtc(int ndx, String[] args) {
}
return xtc;
}

// Parse options: args to the main file
private static String[] args(int ndx, String[] args) {
return Arrays.copyOfRange(args,ndx,args.length);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.xvm.xec.ecstasy.collections.Array.Mutability;
import org.xvm.xec.ecstasy.collections.Hashable;
import org.xvm.xec.ecstasy.numbers.Int64;
import org.xvm.xec.ecstasy.text.Char;
import org.xvm.xec.ecstasy.text.Stringable;
import org.xvm.xrun.Never;
import org.xvm.xtc.*;
Expand Down Expand Up @@ -76,6 +77,10 @@ private static boolean xeq(PropPart p) {
// Lost all type info, need to make sure same subclass
return c0 instanceof Int64 i0 && i0._i == i;
}
public static boolean equals$Const(XTC gold, Const c0, char c ) {
// Lost all type info, need to make sure same subclass
return c0 instanceof Char i0 && i0._i == c;
}

public static boolean equals$Const(XTC gold, XTC c0, XTC c1 ) { return equals$Const(gold,(Const)c0,(Const)c1); }

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
package org.xvm.xec.ecstasy.collections;

import java.util.Arrays;
import java.util.Random;
import java.util.function.IntUnaryOperator;
import org.xvm.XEC;
import org.xvm.util.SB;
import org.xvm.xec.XTC;
import org.xvm.xec.ecstasy.AbstractRange;
import org.xvm.xec.ecstasy.Boolean;
import org.xvm.xec.ecstasy.Iterator;
import org.xvm.xec.ecstasy.numbers.Int32;
import org.xvm.xrun.XRuntime;
import static org.xvm.xec.ecstasy.collections.Array.Mutability.*;

// ArrayList with primitives and an exposed API for direct use by code-gen.
// Not intended for hand use.
@SuppressWarnings("unused")
public class Aryint extends Array<Int32> {
public static final Aryint GOLD = new Aryint();
public static final Aryint EMPTY= new Aryint();

public int[] _es;
private Aryint(Mutability mut, int[] es) { super(Int32.GOLD,mut,es.length); _es = es; }
public Aryint( ) { this(Mutable , new int[ 0 ]); }
public Aryint(int len ) { this(Fixed , new int[len]); }
public Aryint(double x, int... es) { this(Constant, es); }
public Aryint(Mutability mut, Aryint as) { this(mut,as._es.clone()); }
public Aryint(Aryint as) { this(as._mut,as); }
public Aryint(double x, long... es) {
super(Int32.GOLD,Constant,es.length);
_es = new int[es.length];
for( int i=0; i<es.length; i++ )
_es[i] = (int)es[i];
}

public Aryint( int len, IntUnaryOperator fcn ) {
this((int)len);
if( _len != len ) throw XEC.TODO(); // Too Big
for( int i=0; i<_len; i++ )
_es[i] = fcn.applyAsInt(i);
}
public static Aryint construct(Mutability mut, Aryint as) { return new Aryint(mut,as); }
public static Aryint construct() { return new Aryint(); }
public static Aryint construct( int len, IntUnaryOperator fcn ) { return new Aryint(len,fcn); }
public static Aryint construct(int len) { return new Aryint((int)len); }


// Fetch element
public int at8(long idx) {
if( 0 <= idx && idx < _len )
return _es[(int)idx];
throw new ArrayIndexOutOfBoundsException( idx+" >= "+_len );
}
@Override public Int32 at(long idx) { return Int32.make(at8(idx)); }

// Add an element, doubling base array as needed
public Aryint add( int e ) {
if( _len >= _es.length ) _es = Arrays.copyOf(_es,Math.max(1,_es.length<<1));
_es[_len++] = e;
return this;
}

// Add an element, doubling base array as needed
public Aryint add( Int32 e ) {
if( _len >= _es.length ) _es = Arrays.copyOf(_es,Math.max(1,_es.length<<1));
_es[_len++] = e._i; // Unbox
return this;
}

/** Slice */
public Aryint slice( AbstractRange r ) {
throw XEC.TODO();
}

public Aryint addAll( Aryint ls ) {
for( int i=0; i<ls._len; i++ )
add(ls._es[i]);
return this;
}

public int indexOf( int e ) {
for( int i=0; i<_len; i++ )
if( _es[i]==e )
return XRuntime.True(i);
return XRuntime.False(-1);
}
public Aryint removeUnordered(int e) {
int idx = indexOf(e);
return idx== -1 ? this : deleteUnordered(idx);
}
public Aryint deleteUnordered(int idx) {
_es[(int)idx] = _es[--_len];
return this;
}

public Aryint delete(int idx) {
System.arraycopy(_es,(int)idx+1,_es,(int)idx,--_len-(int)idx);
return this;
}

public Aryint shuffled(Boolean inPlace) { return shuffled(inPlace._i); }
public Aryint shuffled(boolean inPlace) {
if( inPlace )
throw XEC.TODO();
// Not inPlace so clone
Aryint ary = new Aryint(_mut,this);
Random R = new Random();
for( int i=0; i<_len; i++ ) {
int idx = R.nextInt(_len);
int x = ary._es[i]; ary._es[i] = ary._es[idx]; ary._es[idx] = x;
}
return ary;
}

/** @return an iterator */
public Iterint iterator() { return new Iterint(); }
public class Iterint extends Iterator<Int32> {
private int _i;
@Override public Int32 next() { return Int32.make(next8()); }
@Override public long next8() { return (XRuntime.$COND = hasNext()) ? _es[_i++] : 0; }
@Override public boolean hasNext() { return _i<_len; }
@Override public final String toString() { return _i+".."+_len; }
// --- Comparable
@Override public boolean equals( XTC x0, XTC x1 ) { throw org.xvm.XEC.TODO(); }
}

// --- Freezable
@Override public Aryint freeze(boolean inPlace) {
if( _mut==Constant ) return this;
if( !inPlace ) return construct(Constant,this);
_mut = Constant;
return this;
}

// --- Appender
@Override public String toString() {
SBX.p("[ ");
for( int i=0; i<_len; i++ )
SBX.p(_es[i]).p(", ");
String str = SBX.unchar(2).p("]").toString();
SBX.clear();
return str;
}

// Note that the hashCode() and equals() are not invariant to changes in the
// underlying array. If the hashCode() is used (e.g., inserting into a
// HashMap) and the then the array changes, the hashCode() will change also.
@Override public boolean equals( Object o ) {
if( this==o ) return true;
if( !(o instanceof Aryint ary) ) return false;
if( _len != ary._len ) return false;
if( _es == ary._es ) return true;
for( int i=0; i<_len; i++ )
if( _es[i] != ary._es[i] )
return false;
return true;
}
@Override public int hashCode( ) {
int sum=_len;
for( int i=0; i<_len; i++ )
sum += _es[i];
return (int)(sum ^ (sum>>32));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,14 @@ public class Int128 extends IntNumber {
public Int128 sub( long x ) { throw XEC.TODO(); }
public Int128 mul( long x ) { throw XEC.TODO(); }
public Int128 div( long x ) { throw XEC.TODO(); }
public Int128 add( Int128 x ) { throw XEC.TODO(); }
public Int128 add( Int128 x ) {
long lo = _lo+x._lo;
long hi = _hi+x._hi;
if( (~(_lo | x._lo)) < 0 && lo < 0 ) {
throw XEC.TODO(); // Overflow
}
return construct(lo,hi);
}
public Int128 sub( Int128 x ) { throw XEC.TODO(); }
public Int128 mul( Int128 x ) {
long lo = _lo*x._lo;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ public class Char extends Const {
public Char(char c) {_i=c;}
public static Char make(char c) { return new Char(c); }
public final char _i;
public static Char construct(char c) { return new Char(c); }

public static <E extends Char> boolean equals$Char( XTC gold, E ord0, E ord1 ) { return ord0==ord1; }
@Override public boolean equals ( XTC x0, XTC x1 ) { return ((Char)x0)._i == ((Char)x1)._i; }
@Override public boolean equals( Object o ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class String extends Const implements Iterable<Char> {
@Override public java.lang.String toString() { return _i; }

public static java.lang.String quoted( java.lang.String s ) {
throw XEC.TODO();
return '"'+s+'"';
}
// Conditional return
public static long indexOf( java.lang.String src, java.lang.String find, long start ) {
Expand Down
20 changes: 14 additions & 6 deletions javatools_backend/src/main/java/org/xvm/xtc/ClzBuilder.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package org.xvm.xtc;

import java.util.BitSet;
import java.util.HashMap;
import java.util.HashSet;
import org.xvm.XEC;
import org.xvm.util.Ary;
import org.xvm.util.S;
import org.xvm.util.SB;
import org.xvm.xec.ecstasy.Comparable;
import org.xvm.xec.ecstasy.Enum;
import org.xvm.xec.ecstasy.Orderable;
import org.xvm.xec.ecstasy.Service;
import org.xvm.xec.ecstasy.collections.Array.Mutability;
Expand Down Expand Up @@ -179,8 +179,10 @@ private void jclass_body() {
_sb.p("extends ").p(_tclz._super._name);
_tclz._super.clz_generic_use( _sb, _tclz );
if( _clz._f==Part.Format.CONST ) {
IMPORTS.add(XEC.XCLZ+".ecstasy.Const");
IMPORTS.add(XEC.XCLZ+".ecstasy.Ordered");
IMPORTS.add( XEC.XCLZ + ".ecstasy.Const" );
IMPORTS.add( XEC.XCLZ + ".ecstasy.Ordered" );
} else if( _clz._f==Part.Format.ENUM ) {
IMPORTS.add(XEC.XCLZ+".ecstasy.Enum");
} else if( _clz._f==Part.Format.SERVICE ) {
IMPORTS.add(XEC.XCLZ+".ecstasy.Service");
}
Expand Down Expand Up @@ -436,6 +438,10 @@ private void jclass_body() {
_clz.child("toString")==null )
org.xvm.xec.ecstasy.Const.make_toString(_clz,_sb);

// Enum classes get a values property, not in the kids list
if( _clz._f == Part.Format.ENUM )
Enum.makeValues(_clz,_sb);

// If the run method has a string array arguments -
// - make a no-arg run, which calls the arg-run with nulls.
// - make a main() which forwards to the arg-run
Expand Down Expand Up @@ -598,7 +604,6 @@ public void jmethod( MethodPart m, String mname ) {
if( xfun.ret()!=XCons.VOID )
_sb.p("return ");
_sb.p(mname).p("( ");
int delta = xfun.nargs() - m._args.length;
for( int i = 0; i < m._args.length; i++ ) {
_sb.p(jname(m._args[i]._name));
if( xfun.arg(i).isUnboxed() )
Expand Down Expand Up @@ -674,7 +679,7 @@ public void jmethod_body( MethodPart m, String mname, boolean constructor ) {
// This is a XTC constructor, which in Java is implemented as a factory
// method - which has the normal no-arg Java constructor already called -
// but now the XTC constructor method needs to end in a Java return.
if( constructor )
if( constructor && !(blk._kids[blk._kids.length-1] instanceof ThrowAST) )
blk = blk.add(new ReturnAST(m,false,new RegAST(-5/*A_THIS*/,"this",_tclz)));
blk.jcode(_sb);
_sb.nl();
Expand Down Expand Up @@ -740,8 +745,10 @@ public static XClz add_import( XClz tclz ) {
assert IMPORTS != null;
// If the compiling class has the same path, tclz will be compiled in the
// same source code
if( tclz._clz!=null && tclz._clz._path!=null && S.eq(CCLZ._path._str,tclz._clz._path._str) )
if( tclz._clz!=null && tclz._clz._path!=null && S.eq(CCLZ._path._str,tclz._clz._path._str) ) {
if( tclz._clz._par instanceof MethodPart ) add_nested(tclz);
return tclz;
}

// External; needs an import
if( !tclz.needs_import(true) ) return tclz;
Expand Down Expand Up @@ -850,6 +857,7 @@ public static String jname( String name ) {
// Mangle names colliding with java keywords
return switch( name ) {
case "default", "assert", "char", "int" -> name+"0";
case "construct" -> "$construct";
case "_" -> "$ignore";
default -> name;
};
Expand Down
Loading

0 comments on commit 07cb63e

Please sign in to comment.