The LOLCODE forum

Discussions in support of the LOLCODE.com wiki

You are not logged in.

Announcement

New registrations are disabled. Please see this announcement.

#1 2007-11-04 01:21:59

JoshSuereth
Moderator
Registered: 2007-07-14
Posts: 221

Java LOLCode integration

So I was hoping to more formally define some LOLCode/Java interaction.  It's my goal to get LOLCode to compile to byte-code and interact with Java as if it were a class (ala groovy).  I know Brett Kail has done some good work so far with a Java Module for LOLCode so i was going to start off with his LOLCode interface to Java as a starting point and work on a Java ineterface to LOLCode.


bjkail wrote:

Module: JAVA
------------
+ Usage
  - This module introduces a new expression:
      JAVA <expression>
    The expression operand is implicitly cast to YARN, and the result is passed
    to Class.forName.  If the class cannot be found, BadJavaClass is thrown.
    The result of the expression is a JAVA value.

+ JAVA value
  - JAVA values wrap a Java object, which includes arrays and Class objects.
    JAVA values can be implicitly cast to YARN, which returns the result of
    calling toString() on the underlying object.  Attempting to cast a JAVA
    value to TROOF, NUMBR, or NUMBAR results in BadJavaUse.
  - Fields and methods of the underlying object can be accessed by using BUKKIT
    slot syntax.  Fields cannot be declared.  When setting a field or passing
    method arguments, LOLCODE values are converted to Java values (see "LOLCODE
    to Java conversion").  When a field value or method value is returned, Java
    values are converted to LOLCODE values (see "Java to LOLCode conversion").
  - If a method slot is found but none of the methods have the appropriate
    number of arguments, BadArgumentCount is thrown.  If a method slot is found
    but none of the methods can be called because an argument fails to be
    converted, then BadJavaType is thrown.
  - If an exception is thrown while executing a method, the type of the
    exception for an O NOES clause is the class name of the exception.
  - If a JAVA value represents a Class, then only static members of the class
    can be accessed.  Otherwise, both static and non-static members of the
    object's class can be accessed.
  - If a value represents a class, a slot named "new" is available.
    - If the class is an array, then the slot may be called with a single
      argument that is implicitly cast to NUMBR that specifies the size of the
      array.
    - Otherwise, the slot may be called, and a constructor is selected using
      the same algorithm as method slots.
  - If a value represents an array
    - Numerical indices can be used.  If the index is out of bounds, then
      BadSlot is thrown.
    - A slot named "length" is available that returns the length of the array.
  - Attempting to assign a method slot, the "new" slot of a class, or the
    "length" slot of an array, then BadSlot is thrown.

+ LOLCODE to Java conversion
  - If the value is NOOB, it is converted to null.  If the target type is a
    primitive type, BadJavaType is thrown.
  - If the value is JAVA, it is unwrapped.  If the target type is
    incompatible, BadJavaType is thrown.
  - boolean, Boolean - implicit cast to TROOF
  - byte, Byte, short, Short, char, Character, int, Integer, long, Long -
    implicit cast to NUMBR
  - float, Float, double, Double - implicit cast to NUMBR
  - String - implicit cast to YARN
  - Object
    - TROOF - Boolean
    - NUMBR - Integer
    - NUMBAR - Float
    - YARN - String
  - BadJavaType is thrown.

+ Java to LOLCODE conversion
  - null - NOOB
  - Long, Double, String - YARN
  - Float - NUMBAR
  - Number - NUMBR
  - All other values are converted as a JAVA value

So... we have the following convention "primitive" convention

Java            LOLCode
----------------------------------
null       <-> NOOB
Long       -> YARN   (I'd prefer Numbr)
Double    -> YARN (I'd prefer Numbar)
String   <-> YARN
Float     <-> NUMBAR
Number <-> NUMBR
Integer  <-> NUMBR



Next... How does a LOLCode file compile to interact with java?


I'd like to see the following:

Cheezburger.lol

Code:

HAI

I HAS A name ITZ "class"


O HAI IM Cheezburger

     I HAS A name ITZ "instance"

     HOW DUZ I foo YR bar?
         FOUND YR SMOOSH bar AN "-extra" MKAY
     IF U SAY SO
KTHX


KTHXBYE

Test.java

Code:

import Cheezburger;
import junit.*;
import static junit.assert.*;

public class Test {
     @Test
     public tryJavaInteract() {
          //Global variable map as class statics
          assertEquals("class", Cheezburger.name());

          //Classes map as classes, if filenames line up, otherwise they become nested inner-classes
          Cheezburger b = new Cheezburger();

          //Property slots map to getters/setters
          assertEquals("instance", b.getName());

          //Method slots map as real methods.   Classes pass through
          assertEquals("test-extra", b.foo("extra"));
     } 
}

Ok, now as for access Java from lolcode...


Widget.java

Code:

public class Widget {
     private int id;
     private Point location;


     public int getId() { return id; }
     public void setId(int id) { this.id = id; }

    public void someMethod(String arg1, Integer arg2) { ... }
    .... 

}

Test.lol

Code:

HAI

CAN HAS Widget?    BTW Uses some classloaderish mechanism to pull in a .class file.  LOLCode impl needs to do some magic to make this work.

I HAS A w ITZ A Widget  BTW "prototypes" the class.  

BTW Java beans props map to slots...  private/public constraints enforced at runtime and throw exception
w-id R 5


VISIBLE w!!id  BTW 5

BTW Function call syntax
w someMethod YR "Yarn" AN YR w-id MKAY

KTHXBYE

-------------------------------------------
-Josh

"To hurry through one's leisure is the most unbusiness-like of actions." - G.K. Chesterton

Offline

 

#2 2007-11-05 14:59:54

JoshSuereth
Moderator
Registered: 2007-07-14
Posts: 221

Re: Java LOLCode integration

Has anyone read the JSR 223 Spec?  That's basically what I'm pushing for...


-------------------------------------------
-Josh

"To hurry through one's leisure is the most unbusiness-like of actions." - G.K. Chesterton

Offline

 

#3 2007-11-05 16:08:39

bjkail
New member
Registered: 2007-09-16
Posts: 5

Re: Java LOLCode integration

JoshSuereth wrote:

So... we have the following convention "primitive" convention

Java            LOLCode
----------------------------------
null       <-> NOOB
Long       -> YARN   (I'd prefer Numbr)
Double    -> YARN (I'd prefer Numbar)
String   <-> YARN
Float     <-> NUMBAR
Number <-> NUMBR
Integer  <-> NUMBR

I wanted the conversions to be lossless.  Since long-to-int and double-to-float are truncating operations, I decided to convert to YARN.  Long.valueOf(String).intValue() is one way to convert.  A better option would probably have been to just return Long and Double objects.

JoshSuereth wrote:

Next... How does a LOLCode file compile to interact with java?

I started thinking about this, and coming up with a nice ABI was the challenging part.

JoshSuereth wrote:

Has anyone read the JSR 223 Spec?  That's basically what I'm pushing for...

I haven't read the spec, but I have read through the javax.script javadoc.  I didn't finish implementing, so it ended up as a TODO in the README.

Offline

 

#4 2007-11-06 03:59:55

JoshSuereth
Moderator
Registered: 2007-07-14
Posts: 221

Re: Java LOLCode integration

I understand not wanting to lose precision.  I was thinking of making the LOLtypes just be larger... i.e. Numbar <-> Double,   Numbr <-> Long.

Yeah... the ABI would be hard to do.  Especially with bukkits having prototype OO.


I was thinking of a groovy solution:

Every .lol file compiles to a .class file.

Variable definitions (I HAS A) turn into static variables.
Function definitions (HOW DUZ I) turn into static methods.
General statments get placed on the <clinit> block of the class.

// For 1.3 Bukkit spec as it exists now....
Bukkits turn into "nested" class files
Variables on bukkit turn into instance variables
Functions on bukkit turn into instance variables
Instances of bukkit created turn into dynamic proxies.  These first check for any "new" slots added to a bukkit before delegating to existing "compiled" functions.


There's a LOT left unsaid, but this was the first approach I sort of came by.  We need a way of defining a function and delegating to it at runtime, and still having it find things on the scope appropriately (using LOLCode rules not Java).   I'm thinking there needs to be some sort of "Runtime" object (can be thread-local) that's used to look up variables.  If this function fails, then we attempt to access a "local" property and fail.


K... it's late so I may be repeating myself or not making sense anymore.   Let me know what you think.


-------------------------------------------
-Josh

"To hurry through one's leisure is the most unbusiness-like of actions." - G.K. Chesterton

Offline

 

#5 2007-11-14 23:07:06

JoshSuereth
Moderator
Registered: 2007-07-14
Posts: 221

Re: Java LOLCode integration

Let me know what you think of this for syntax within java to call LOLCode...

This assumed that you have a "MyLOLFile.lol" that has been compiled to "MyLOLFile.class" and added to the path.


Code:

import MyLOLFile;
import com.lolcode.core; // This is where all the abstract LOL interfaces exist for java to access 'live" LOL variables.


public static void main...blah..blah..blah {


                //Accessing a variable
                MyLOLFile.get("variablename");
                MyLOLFile.getVariablename();  //if available statically
                MyLOLFile.set("variablename", "value");
                MyLOLFile.setVariablename("value");  //if available statically

        //Access a function...
        MyLOLFile.fooin("value");
        
        //Access a random Bukkit from the .lol file
        Bukkit obj = new MyLOLFile.TestBukkit();
        
        
        //IF the bukkit has the same name as the lol file
        obj = new MyLOLFile();
        
        //Invoking bukkit functions
        obj.invoke("fooin", "value");
        obj.invoke("fooin", new Object[] {"value"});
        ((MyLOLFile)obj).fooin("value"); //If fooin is defined within the MyLOLFile.lol, otherwise it's not available statically.
        
        // Accessing slots
        obj.get("slotname");
        obj.set("slotname", "value");
        obj.getSlotname(); // if available statically
        obj.setSlotname("value"); //if available statically

}

The getters/setters take POJOs (which LOLcode then casts).   I'm thinking LOLCode might have to interact directly with Strings, Doubles, Longs and Booleans.  Basically for the ABI I was going to use the Java .class file format for maximum Java-LOL integration.  The problem there is we'd have to do some nifty hack to get the apropriate runtime behavior for LOL classes.


-------------------------------------------
-Josh

"To hurry through one's leisure is the most unbusiness-like of actions." - G.K. Chesterton

Offline

 

#6 2007-11-14 23:17:13

Coda
Moderator
Registered: 2007-10-30
Posts: 308

Re: Java LOLCode integration

Assuming your interpreter is itself written in Java, whatever syntax you use can be equivalent to the way the interpreter itself works.

Offline

 

#7 2007-11-14 23:31:09

JoshSuereth
Moderator
Registered: 2007-07-14
Posts: 221

Re: Java LOLCode integration

Coda wrote:

Assuming your interpreter is itself written in Java, whatever syntax you use can be equivalent to the way the interpreter itself works.

This is no more "interpreter" really.  Things compile down to java byte-code in a .class file, and you can use regular java semantics to load/run LOLCode programs.  You should read above.


-------------------------------------------
-Josh

"To hurry through one's leisure is the most unbusiness-like of actions." - G.K. Chesterton

Offline

 

Board footer

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson