Core Java

ZeptoN is Putting Program into Java

1. Introduction

The Java programming language or “Java” was introduced in 1995. Yet in the almost quarter-century it has added features not originally in the core language. Such features include enumerations, generics, many enhancements to the basic C-style functional switch statement, assertions, etcetera. Java is a programming language that has evolved over time to meet the needs of Java software developers. Note that the Java environment, as in the runtime and supporting libraries, packages, tools, and utilities have also added and removed elements (like the Java shell, and Java applets, respectively.) But the emphasis herein is Java, the programming language.

Java’s success and popularity have led to it being used to teach coding. The AP (Advanced Placement) Exam for computer science uses Java. The problem with Java is a paradox. With Java’s success, and many developers writing Java code, those new to programming, those trying to learn programming are forgotten.

2. Problem is No Program in Programming

Once an aspiring developer in the 1980s and 1990s began learning to code with the ubiquitous BASIC, and then moved to Pascal (or FORTRAN, C) and then on to more powerful object-oriented languages such as Objective-C, C++, Smalltalk, Java. In this progression, the transition was from elementary programming concepts such as variables versus a constant, input or output, if statements, etcetera on objects, classes, and then to object-oriented principles, and design patterns—to name a few things along the path of a software developer.

But a novice or “newbie” to learning to code with Java has to contend with a myriad of features that either is to be ignored, but used without knowing what the feature is useful for. This is the “Pay No Attention to the Man Behind the Curtain” (from the Wizard of Oz) approach. Or an alien feature of Java is yet another feature that adds to cognitive overload; that is, “…a situation where the teacher gives too much information or too many tasks to learners simultaneously, resulting in the learner being unable to process this information.” [Brit 2019] This is the myth of where the novice throws their computer out the window in frustration, and then loses interested learning to code.

3. The Program Entity

Thus, programming in Java lacks a program entity to write simply an application or program. Older, structured programming languages like BASIC and Pascal were nothing but a program entity. So for Java’s sophistication, elegance, and powerful features, it lacks the simplest feature of all–a program. Consider the following classic program but simple program from BASIC, to read a user’s name, and then print a greeting back. [Wiki 2019a] The BASIC source code is:

10 PRINT "what is your name?"
20 INPUT "...(Enter Your Name)...", a$
30 PRINT
40 PRINT "hello, "; a$; ", I am your computer, nice to meet you." 
60 END

The same BASIC program in Java source code is:

import java.util.Scanner; 

class WhatIsYourName {

  private WhatIsYourName(){}

  public static void main(String[] args){
    System.out.println("what is your name?");
    System.out.print("...(Enter Your Name)..."); 
    String name = System.console().readLine();
    System.out.printf("hello, %s, I am your computer, nice to meet you.%n", name);
    System.exit(0); 
  }//end main;

}//end class WhatIsYourName

In comparison, both programming languages achieve the same end result as a program, reading the user’s name, and then printing a greeting back to them. However, the Java version requires exposing some details that either requires further understanding or ignoring. Consider some of the possible the questions a novice would ask about the Java code:

  1. What is a class?
  2. What is a constructor?
  3. What is a void method?

4. Everything Object-Oriented

There are many object-oriented features required for such a basic, simple program application using Java. For another example, consider the simple and infamous “Hello, World!!!” in BASIC versus Java.

4.1 Program into Java with Zepton

This illustrative example demonstrates the need for a program entity construct. Similar to a class, except a program is a unit of execution or application, not an object for reuse. An example is the same BASIC program but expressed in ZeptoN as a program and not a Java class:

prog WhatIsYourName { 

begin

  println("what is your name?");
  print("...(Enter Your Name)..."); String name = readLine();
  printf("hello, %s, I am your computer, nice to meet you.%n", name);
  exit(0);

}//end prog WhatIsYourName

The ZeptoN program is much more readable, simple, and compact. The ZeptoN transcompiler [Gilr 2019b] when it transpiles a ZeptoN program into a Java class will create the necessary main(String[] args) method automatically, and also some “boilerplate” source code that provides a default environment within ZeptoN.

The boilerplate source code is simply method calls that are wrapped in a public, static method. Thus
“System.out.println(…)” is simply “println(…)” with the same parameter type signature. Or “System.exit(…)” is
simply “exit(…)” with the same parameter type as well.

The required import statements are automatically generated. Overall, there are approximately seventy methods and attributes in the boilerplate source code. An important principle is few ZeptoN specific methods and attributes, and that the method name is the same, with the same parameter type signature. Thus a ZeptoN developer can move back to Java, or from Java to ZeptoN without any problems.

4.2 Non-standard Methods in ZeptoN

One non-standard static method is “String[] getArgs()” which gets the command-line program arguments. Another is “void nop()” for no operation for a stub method. Java has an empty statement, but a “nop()” is more explicit. Some non-standard constants are EMPTY_STRING, EMPTY_CHAR, and NULL_CHAR.

Again the non-standard methods and attributes are kept to a few and are to avoid convoluted Java source code. A standard method is “String readLine()” but doesn’t require using the Java Scanner, BufferedReader, or other classes. ZeptoN is an emphasis on simplicity and minimality. And, as ZeptoN’s creator, developer, and first programmer, it always annoyed me the String class did not have a magic constant EMPTY_STRING, or the Character class EMPTY_CHAR or NULL_CHAR. I’m trying to be logical, but I still am…jaded. But many a programming language often has the idiosyncrasies of the designer from their experience.

4.3 Summary of ZeptoN

ZeptoN is Java, but it transcompiles the program entity into a class from the program entity, transpiles a
main() method, and adds a set of boilerplate methods and attributes that are similar to the methods and
attributes in other classes. Thus creating a default environment for use by a developer. This is simple enough
to implement using a transcompiler, avoiding the overhead and complexity of a complete Java compiler
implementation. The transcompiler transcompiles ZeptoN into Java, and then the Java Compiler API is used
to compile into bytecode.

For the particular JDK version, ZeptoN “auto-magically” has those features. So for example, if using JDK 13, then text blocks are part of a feature in ZeptoN. ZeptoN as Java is inclusive of the features of Java. Thus for the next version of Java, JDK 14, records are potentially a feature that if in JDK 14 are in ZeptoN.

Now as ZeptoN is a basic transcompiler, it is possible to extend ZeptoN to add further features that then are transcompiled to Java. The goal is to add such a feature consistently but also avoid a complete compiler implementation. Fortunately, Java has a feature-rich set of packages and classes that make this possible with some work and creative thought.

5. Extending ZeptoN

Primitive types are sometimes the wrinkle in writing Java and by extension ZeptoN. So the feature is to automatically convert primitive types into the class wrapper type in ZeptoN. This feature of an automatic conversion from a primitive type to an object form (which I term “promotion to object”) is readily implemented using a transcompiler. The arguments are both advocating for [Moor 2014] and against [Alpe 2000] using primitive types. Yet the best approach is to give the developer this choice in writing source code in ZeptoN.

5.1 Primitive Types

The Java Language Specification, Java SE 13 Edition [Orac 2019] defines a primitive type as “A primitive type is predefined by the Java programming language and named by its reserved keyword.” A more descriptive definition is a primitive type that is predefined datum in the Java programming language. The types “null” and “void” are not among the primitive types.

Null is a default reference value, or “The null type has one value, the null reference, represented by the null
literal null” [Orac 2019] The void type indicates a non-return value method, or “Used at method declaration
and definition to specify that the method does not return any type, the method returns void. It is not a type
and there is no void references/pointers as in C/C++.” [Wiki 2019b]

As ZeptoN is Java, hence it follows that primitive types are exactly similar.

5.2 Object Wrapper Types

Primitive types are efficient, but the one “wrinkle” in Java that is not an object. Primitive types are not referenced and have no object or state. But an object type is sometimes necessary and useful. Thus Java provides object wrapper types to objectify the primitives.

Eckel [Ecke 2003] describes object type wrappers as, “The “wrapper” classes for the primitive data types
allow you to make a nonprimitive object on the heap to represent that primitive type.”

For example, to use the primitive types with any of the Java collections, it requires the primitive type as an object type. Java has a feature to auto-magically promote a primitive type to an object type wrapper.

5.3 Auto-Boxing Performance

There is the feature of auto-boxing (since Java 5 thus in ZeptoN) but a simpler approach is to simply promote all primitive types to an object. Java uses auto-boxing between most of the primitives (excepting null and void) but there is the disconnect between the primitive type such as int, which is simply datum, and the wrapper type Integer, which is an object.

Another important consideration is performance, and unrestricted and unconsidered use of auto-boxing can lead to performance issues [DZone article] in Java bytecode. One of the biggest advantages of this feature of promotion to an object is less code to write, and the source code is cleaner.

Two primitive types, null and void are not a datum, and thus not promoted to an object. The eight primitive types of boolean, byte, char, double, float, int, long, short are promoted to an object. But object types as compared to primitive types will utilize more memory.

5.4 Transpiling ZeptoN Source with Primitive Types

Consider the following simple ZeptoN program “polyMathPrimitive1.zep” that calculates a number from the index within a for loop (hence a polynomial) but using the primitive type int for the calculation. A static method “polyMathLoop” is used as the method to call from the program block.

package javacodegeeks; 

prog polyMathPrimitive1 {

  static void polyMathLoop(final int loopLimit){

    for (int index = 0; index < loopLimit; index++) {
      int number = index * index * index + index * index + index; 
    }//end for

  }//end polyMathLoop

begin

  long timeStart = nanoTime();
  polyMathLoop(1000);
  long timeClose = nanoTime();
  printf("Total time: %d nanosec%n",(timeClose-timeStart)); println();
  exit(0);
}

The polyMathLoop() method is invoked with an integer literal of 1000. The method does not really do anything except repeatedly calculating the same polynomial.

When compiled with the ZeptoN compiler, and then run:

/Users/williamgilreath$java -cp . Zep polyMathPrimitive.zep 
/Users/williamgilreath$java -cp . javacodegeeks.polyMathPrimitive1 
Total time: 18484 nanosec

The equivalent ZeptoN when transpiled is illustrated with the ZeptoN program “polyMathObject.zep” is:

package javacodegeeks; 

prog polyMathObject {

static void polyMathLoop(final Integer loopLimit){

  for (Integer index = 0; index < loopLimit; index++) {
    Integer number = index * index * index + index * index + index;   
  }//end for

}//end polyMathLoop

begin

  long timeStart = nanoTime();
  polyMathLoop(1000);
  long timeClose = nanoTime();
  printf("Total time: %d nanosec%n",(timeClose-timeStart)); println();
  exit(0);

}

When compiled with the ZeptoN compiler, and then run:

/Users/williamgilreath$java -cp . ZepC polyMathObject.zep 
/Users/williamgilreath$java -cp . javacodegeeks.polyMathObject 
Total time: 512084 nanosec

The ratio of the two performance times demonstrates the overall ratio of 1: 27.7 difference. Clearly complete promoting every primitive to object type can be problematic for performance.

Consider an alternative approach, where not every integer in the ZeptoN program is either a primitive int or object wrapper Integer. The ZeptoN source code is:

package javacodegeeks; 

prog polyMathPrimitive2 {

  static void polyMathLoop(final Integer loopLimit){ 
    for (int index = 0; index < loopLimit; index++) {
      int number = index * index * index + index * index + index;  
    }//end for
  }//end polyMathLoop

begin

  long timeStart = nanoTime();
  polyMathLoop(1000);
  long timeClose = nanoTime();
  printf("Total time: %d nanosec%n",(timeClose-timeStart)); 
  println();
  exit(0);
}

When compiled with the ZeptoN compiler, and then run:

/Users/williamgilreath$java -cp . Zep polyMathPrimitive2.zep 
/Users/williamgilreath$java -cp . javacodegeeks.polyMathPrimitive2 Total time: 92350 nanosec

The ratio of the performance time demonstrates the overall ratio of 1: 5 difference. This is an improvement in performance against a pure object wrapper type implementation. A mixed approach is more efficient in performance.

5.5 Feature Syntax of “Promotion to Object”

The examples of before and after illustrate the transpiling from primitive int to object wrapper Integer is all or
nothing. Performance is clearly impacted drastically. Yet there are also cases when a developer wants to
specify a primitive type remains a primitive type—especially in the metric of performance. This mirrors the
aforementioned approach in this feature of giving the developer the choice of primitive or object type.

The syntax is one of exclusion from promotion from primitive type to object type. For the syntax a normal
primitive without any other indicator is promoted to an object type. Thus int becomes Integer, double
becomes Double, and so forth etcetera.

The syntax for exclusion is “borrowed” from JavaCC [ref] syntax for the expression of a grammar rule as
Copeland [Cope 2009] explains, “…is the ? quantifier, which matches zero or once occurrence of the
specified pattern.”

A primitive type that is excluded from promotion to an object type has a trailing “hook” or “question mark” of
character ‘?’ after the identifier to indicate to the transcompiler not to promote the primitive type to an object
type. With a character of ‘?’ the primitive type remains a primitive type. Thus “int?” is transcompiled to “int”
not “Integer” as no promotion to object type occurs.

Rewriting the original mixed syntax of primitive type and object type, this syntax in ZeptoN source code is:

package javacodegeeks;

prog polyMathSyntax {

  static void polyMathLoop(final int loopLimit){

    for (int? index = 0; index < loopLimit; index++) {
      int? number = index * index * index + index * index + index;
    }//end for
  }//end polyMathLoop

begin
  long? timeStart = nanoTime();
  polyMathLoop(1000);
  long? timeClose = nanoTime();
  printf("Total time: %d nanosec%n",(timeClose-timeStart)); println();
  exit(0);
}

The “polyMathSyntax.zep” ZeptoN program is equivalent as “polyMathPrimitive2.zep” ZeptoN program—
after transcompilation from the syntax into common Java source code.

The syntax allows a developer the choice of whether a primitive remains a primitive type, or is promoted into an object type wrapper. Thus the developer is in control, not the ZeptoN transcompiler. The syntax is somewhat familiar, similar to a JavaCC production rule, the syntax of Kotlin for allowable nullity, or the syntax of Swift for nil. Thus the syntax is somewhat familiar, although the semantic meaning is entirely different.

6. Transpiler for the Feature Syntax

The syntax is simple and familiar for specifying a primitive type remains primitive. The question is how to
implement this feature in the transcompiler so that ZeptoN is transcompiled into Java source code. But the
ZeptoN transcompiler already will transpile ZeptoN source code into Java source code, which is then
compiled using the Java Compiler API.

The software implementation to transpile the feature syntax has two challenges:

  1. Implement transpiling of the feature syntax

  2. Utilize the existing ZeptoN transcompiler

This is a classic software development engineer task—implement a feature in existing legacy software. In short, create a new algorithm, and then implement within legacy code of the ZeptoN transcompiler.

6.1 Algorithm for the Feature

The algorithm for the feature of primitive type to object type is simple, and more a search and replace
process with a regular expression than any more complex compilation.

There are three steps to the algorithm:

  1. Rename primitives to stay primitive to intermediate identifier

  2. Rename primitive types as the object type wrapper

  3. Rename intermediate identifiers to the primitive types

Each step of the algorithm the resulting character string is then processed in the next step in sequence until the original ZeptoN source with the syntax feature is transformed into ZeptoN source code with both primitive and object types.

6.1.1 Rename Primitive to Intermediate Identifier

This first step of the algorithm preserves the primitives that are to stay primitive. But a rename is necessary to avoid the search and replace for the object wrapper type. Any non-identical substitution can be used, but using the uppercase of the primitive with the letter ‘Q’ concatenated simplifies the code to be written as each primitive identifier can be used in both the search and replace by regex.

6.1.2 Rename Primitive as Object Type Wrapper

The intermediate step is a search and replace of the primitive type identifier with the object type identifier in the ZeptoN source code. Each primitive identifier is checked and substituted. Thus the primitive stays a primitive and is restored in the last step of the algorithm.

6.1.3 Rename Intermediate Identifier as Primitive Type

The last step in the algorithm restores the primitive types that were renamed. Using the unique, non-identical identifier, the primitive type identifier is substituted without the trailing question mark, and the primitive indicated to stay primitive in the syntax is so in the ZeptoN source code.

6.2 Implementation of Feature Syntax

The algorithm can be implemented using three for-loops over a list of primitive types, or even more simply with an infamous “one liner” that is more like a stream that uses one for-loop. Thus the Java source code to transpile a ZeptoN source code string with the primitive types to promote and remain in base ZeptoN source code is the “transpileCode()” method:

public static String transpileCode(final String zepCode){ 

  String result = zepCode;
  final String[] primitiveList = new String[]{
    "boolean", "byte", "char", "double", "float", "int", "long", “short" };

  final String[] objectTypeList = new String[]{
    "Boolean", "Byte", "Character", "Double", "Float", "Integer", "Long", “Short" };

  for(int x=0;x<primitiveList.length;x++){

    //primitive type with '?' at end
    String prim = String.format("%s[?]", primitiveList[x]); 
    
    if(result.contains(primitiveList[x])){
      //primitive type to uppercase
      String upper = String.format("%SQ", primitiveList[x]);
      
      //exact match of primitive type
      String result = result 
                    . replaceAll(prim, upper)
                    . replaceAll(type, objectTypeList[x]) 
                    . replaceAll(upper, primitiveList[x]);
    }//end if

  }//end for

  return result; 

}//end transpileCode

6.3 Transpile then Export to File

After the “transpileCode()” method transpiles the feature syntax to ZeptoN source code, the source code is then written to an external file. The source code for the overall “transpile()” method is:

private static void transpile(String fileNameOrig) { 

  String srcCode = "";
  try {
    srcCode = new String(Files.readAllBytes(Paths.get(fileNameOrig))); 
  } catch (Exception ex) {
    System.out.printf("Failure reading source file: %s!%n", fileNameOrig);
    return; 
  }//end try
  
  //transpile to ZeptoN source from extended feature syntax 
  srcCode = transpileCode(srcCode);
  String path = fileNameOrig.replace(".orig", ".zep");
  try {
    Files.write(Paths.get(path),  srcCode.getBytes(Charset.defaultCharset()));
  } catch (Exception ex) {
    System.out.printf("Source code write failure!%n"); return;
  }//end try

}//end transpile

The “transpile()” method uses an external file, the new features syntax in a “.zep” file to “.orig” file. The source code file is read into a String, transpiled into ZeptoN source code. The ZeptoN source code files Is then written to a “.zep” file. This preserves the original file arguments passed, along with any command-line parameter arguments. The rest of the compiler is implemented using the existing ZeptoN transcompiler.

7. Transcompiler Implementation with ZeptoN

The ZeptoN transcompiler is used as the legacy or pre-existing code for the transcompiler to integrate the
new feature syntax. The approach is:

  1. An external file is for intermediate code with the pre-processing transcompiler

  2. The existing ZeptoN transcompiler is a post-processor transcompiler and compiler

Thus the new transcompiler with the feature syntax in ZeptoN will use external files, so will not compile
internally. This had the advantage that the intermediate ZeptoN source can be stored as part of the overall
compilation process after pre-processing the ZeptoN source code with the new syntax.

The existing ZeptoN transcompiler (using an in-memory Java compiler to compile transcompiled ZeptoN to Java source code) is used as a package or library. Thus the existing ZeptoN compiler is not modified or sub- classed, but used in the final stage of compilation.

7.1 Zep the Existing ZeptoN Transcompiler

The existing ZeptoN transcompiler, “Zep.java” is open source Java released in a Github repository. The
transcompiler transpiles ZeptoN source code in a file “source.zep” into Java source code internally, and then
uses the Java Compiler API in-memory to compile into a bytecode .class file.

The two core methods of the transcompiler Zep.java class are of course “main(String[] args)” the main method for invocation, and the “compile(String[] args)” method which does the actual transcompilation and then compiling into a Java bytecode .class file. The question is which method to invoke after transpiling primitive types to object wrapper types. The two methods are the “main()” method, or the “compile()” method, both of which are static so stateless methods.

7.1.1 The main() Method

The ZeptoN transcompiler “Zep.java” has a “main()” method that could be used, as all parameters are preserved and external files used. The “main()” method source code is:

public static void main(final String[] args) {

  try {
    if (args.length == 0) {
      System.out.printf("%s %s%n%s%n", RELEASE, VERSION, LICENSE); 
    }//end if
    Zep.compile(args);
  } catch(Exception ex) {
    error("ZeptoN Compiler Exception: '%s' is '%s'.%n",
    ex.getClass().getName(), ex.getMessage()); ex.printStackTrace();
    System.exit(EXIT_CODE_FAILURE); 
  }//end try
  System.exit(EXIT_CODE_SUCCESS); 

}//end main

Invoking the ZeptoN transcompiler through “main” has the inordinate problem as “System.exit()” is invoked for success or failure. Thus compiling multiple files with the new syntax feature is impossible, as the first file compiled will terminate on success or failure.

7.1.2 The compile() Method

The ZeptoN transcompiler method “compile()” is invoked by the “main()” method. The method creates an instance of the ZeptoN compiler, processes the command-line arguments, and configures the command-line parameters. If there are no arguments passed, or no files given to transcompiler, an error is raised.

The source code for the “compile()” method of the ZeptoN transcompiler is:

public static void compile(final String[] args) {

  if (args.length == 0) { 
    error(ERROR_NO_INPUT);
  }//end if

  final Zep comp = new Zep();
  comp.processCommandLineArgs(args);
  if (files.isEmpty()) { 
    error(ERROR_NO_FILES);
  }//end if
  comp.configureParams();
  for (String sourceFile : files) {
    comp.compileZeptoN( Zep.transpile(sourceFile), sourceFile );
  }//end for 

}//end compile

The actual ZeptoN transcompiler uses the “transpile()” method which returns a Java source file object, that is passed to the compiler instance method “compileZeptoN()” to generate a Java bytecode .class file. The “transpile()” method reads the external ZeptoN source file into a String object, and transpiles into Java source, which then is compiled.

7.1.3 Invoking the compile() Method

The “compile()” method is used to compile the transpiled feature syntax into a bytecode .class file. There are
two possible errors since external files are used:

  1. File error is not possible as external files created by the primitive to object transcompile method.
  2. Zero arguments is not possible as the transcompile method creates ZeptoN source files.
private static void compile(String[] args) { 

  String[] fileList = getFileList(args);
  for(String fileName : fileList) { 
    //rename, transpile fileList arguments
  }//end for
  Zep.compile(args); 

}//end transpile

After renaming files and then transpiling the new syntax feature into ZeptoN source code, the ZeptoN transcompiler “compile()” is invoked, and the ZeptoN transcompiler does the work of transpiling into Java bytecode .class files.

Afterward the original source code files with the new feature syntax in the file “.orig” are renamed after the intermediate “.zep” files are deleted. The source code for this step in the “compile()” method is:

private static void compile(String[] args) { 

  //...
  Zep.compile(args);

  for(String fileName : fileList) { 
    Path path = Paths.get(fileName); 
    try {
      Files.delete(path); 
    } catch (Exception ex) {
      System.out.printf("Failure deleting file path:%s!%n", path);
    }//end try

    String fileNameOrig = fileName.replace(".zep", ".orig");
    Path oldFile = Paths.get(fileNameOrig); 
    Path newFile = Paths.get(fileName);
    try {
      Files.move(oldFile, newFile, StandardCopyOption.REPLACE_EXISTING); 
    } catch (Exception ex) {
      System.out.printf("Error: Unable to rename file %s!%n", oldFile); 
    }//end try
    
  }//end for

}//end transpile

Once the intermediate files are successfully deleted and the “.orig” source code files renamed to “.zep” the transcompilation process is finished.

7.1.4 Summary of the Extended Feature Syntax Transcompiler

The overall process of trans compiling the new syntax features into Java bytecode .class files use external files, so much of the process is renaming, deleting, reading, and writing source code files. But all this data movement allows the existing ZeptoN transcompiler to be invoked with “compile()” with the parameters to the compiler and file names. The overall process is:

  1. Rename new feature syntax file from “.zep” to “.orig”

  2. Read “.orig” into String, transcompiles into ZeptoN source code as String.

  3. Write String to file name “.zep”

  4. Invoke existing ZeptoN transcompiler “compile()” method with external file, arguments

  5. Delete intermediate “.zep” files

  6. Rename “.orig” files into “.zep”

7.2 Putting the New Syntax Feature to the Test

The implementation of the new syntax feature is complete, but now to test the new feature added to the
ZeptoN programming language.

Testing the new syntax feature uses the four ZeptoN source files. The test is simple, using the original
ZeptoN transpiler: Zep; and the modified ZeptoN transpiler: ZepPTO. The ZeptoN source code files used in
the test are:

  1. polyMathPrimitive1.zep: all types are primitives

  2. polyMathPrimitive2.zep: mixed types are primitives and object types

  3. polyMathObject.zep: all types are object types

  4. polyMathSyntax.zep: types are using the new feature syntax

The Zep original ZeptoN source code transpiler will compile all the ZeptoN source files, except the
‘polyMathSyntax.zep’ which contains the new features syntax. The ZepPTO extended featured syntax
transpiler will compile all the files.

As all files will compile except ‘polyMathSyntax.zep’ which will fail with the Zep transcompiler, but will succeed with the ZepPTO transcompiler, the output using this file is used to compare to avoid needless duplication and explanation.

7.2.1 Transcompile New Syntax with ZeptoN

When compiled with the ZeptoN transcompiler, the result is:

ZeptoN - Compiler Errors
Figure 1: ZeptoN Compiler Errors

There are eleven errors, primarily related to the new syntax, not surprisingly as the existing ZeptoN
transcompiler does not implement the new syntax feature—yet.

7.2.2 Transcompiler with ZepPTO

When compiled with the new ZepPTO (Promote To Object) transcompiler, the result is:

/Users/williamgilreath$java javacodegeeks.zepton.ZepPTO -echo polyMathSyntax.zep
ZeptoN Compiler Options: [-d, /Users/williamgilreath, -g] Files: [polyMathSyntax.zep] Encoding: UTF-8
ZeptoN Compiler result for file: 'polyMathSyntax.zep' is: Success.

Now running the generated Java bytecode .class file, the result is:

/Users/williamgilreath$java -cp . javacodegeeks.polyMathSyntax Total time: 301515 nanosec

The transcompiled ZeptoN source code into a bytecode .class file runs using the Java runtime.

7.2.3 Compiling other Files with Zep

The other ZeptoN source files, that have the regular ZeptoN syntax are compiled with the non-extended ZeptoN transcompiler “Zep” with the parameter “-echo” to echo the Javac parameters used, and the overall success or failure of the compiler.

/Users/williamgilreath$java io.github.wgilreath.ZeptoN.Zep -echo polyMathObject.zep
ZeptoN Compiler Options: [-d, /Users/williamgilreath, -g] Files: [polyMathObject.zep] Encoding: UTF-8
ZeptoN Compiler result for file: 'polyMathObject.zep' is: Success.

The regular ZeptoN compiler has compiled the ZeptoN source file “polyMathObject.zep” successfully.

/Users/williamgilreath$java io.github.wgilreath.ZeptoN.Zep -echo polyMathPrimitive1.zep
ZeptoN Compiler Options: [-d, /Users/williamgilreath, -g] Files: [polyMathPrimitive1.zep] Encoding: UTF-8
ZeptoN Compiler result for file: 'polyMathPrimitive1.zep' is: Success.

The regular ZeptoN compiler has compiled the ZeptoN source file “polyMathPrimitive1.zep” successfully.

/Users/williamgilreath$java io.github.wgilreath.ZeptoN.Zep -echo polyMathPrimitive2.zep
ZeptoN Compiler Options: [-d, /Users/williamgilreath, -g] Files: [polyMathPrimitive2.zep] Encoding: UTF-8
ZeptoN Compiler result for file: 'polyMathPrimitive2.zep' is: Success.

The regular ZeptoN compiler has compiled the ZeptoN source file “polyMathPrimitive2.zep” successfully.

7.2.4 Compiling Other Files with ZepPTO

The other ZeptoN source files, that have the regular ZeptoN syntax are compiled with the extended ZeptoN transcompiler “ZepPTO” with the parameter “-echo” to echo the Javac parameters used, and the overall success or failure of the compiler.

/Users/williamgilreath$java javacodegeeks.zepton.ZepPTO -echo polyMathObject.zep
ZeptoN Compiler Options: [-d, /Users/williamgilreath, -g] Files: [polyMathObject.zep] Encoding: UTF-8
ZeptoN Compiler result for file: 'polyMathObject.zep' is: Success.

The extended ZeptoN compiler has compiled the ZeptoN source file “polyMathObject.zep” successfully.

/Users/williamgilreath$java javacodegeeks.zepton.ZepPTO -echo polyMathPrimitive1.zep
ZeptoN Compiler Options: [-d, /Users/williamgilreath, -g] Files: [polyMathPrimitive1.zep] Encoding: UTF-8
ZeptoN Compiler result for file: 'polyMathPrimitive1.zep' is: Success.

The extended ZeptoN compiler has compiled the ZeptoN source file “polyMathPrimitive1.zep” successfully.

/Users/williamgilreath$java javacodegeeks.zepton.ZepPTO -echo polyMathPrimitive2.zep
ZeptoN Compiler Options: [-d, /Users/williamgilreath, -g] Files: [polyMathPrimitive2.zep] Encoding: UTF-8
ZeptoN Compiler result for file: 'polyMathPrimitive2.zep' is: Success.

The extended ZeptoN compiler has compiled the ZeptoN source file “polyMathPrimitive2.zep” successfully.

7.2.5 Summary of Testing

The testing of the normal ZeptoN source files and the extended syntax feature with both transcompilers shows that the extended transcompiler ZepPTO compiles into Java bytecode .class files. The new feature syntax works to promote primitive types to object type wrappers, and excludes primitive types with the new feature syntax to remain primitive types.

8. Conclusion

The ZeptoN programming language is Java, only focusing on a program entity, a feature the Java programming language lacks. This creates a programming language that is Java syntax similar and compatible; such a programming language is easily transcompiled into Java source code, and then compiled into a bytecode .class file using the Java Compiler API.

The ZeptoN programming language was extended by adding a new feature with new syntax. This feature
was to convert primitive types (excluding null and void) to the object wrapper types. This is a common theme
with programming languages often in the extreme called “creeping featuritis” or “feature creep.” But for a
new feature in the programming language syntax, it must be designed and implemented.

The new feature syntax was implemented using a transcompiler that transpiles ZeptoN source code with
new feature syntax into ordinary ZeptoN source code. The source code is the transcompiled into Java
bytecode using the existing ZeptoN transcompiler. This has the advantage of using existing transcompiler for
ZeptoN, but customizing and extending the language with a new feature. This avoids an entirely new
implementation for the new syntax feature added to ZeptoN

Hence the emphasis was on implementing the transpiler for the new syntax feature, and then implementing, leveraging an existing transcompiler, and compiler since the ZeptoN transcompiler transpiles into Java source code, and then into a Java bytecode .class file. This same approach can be used to extend Java with a new feature, use the WEJAC compiler [Gilr 2019b] to compile transcompiled Java source code to pure Java source code, and then to a bytecode .class file.

9. References

[Alpe 2000] Alpert, Sherman R. “Primitive Types Considered Harmful.” in More Java Gems, Cambridge University Press, New York, New York, 2000, pp. 435-454.

[Brit 2019] British Council. “Cognitive overload,” May 20, 2015, https://www.teachingenglish.org.uk/article/cognitive-overload. Accessed November 9, 2019.

[Cope 2009] Copeland, Tom. Generating Parsers with JavaCC, Centennial Books, Alexandria, Virginia,
2009, p 29.

[Ecke 2003] Eckel, Bruce. Thinking in Java, Prentice-Hall, Upper Saddle River, New Jersey, 2003, p. 90

[Gilr 2019a] Gilreath, William F. GitHub Repository “WEJAC: Will’s Elided Java API Compiler,” https://wgilreath.github.io/WEJAC/ Accessed December 31, 2019.

[Gilr 2019b] Gilreath, William F. GitHub Repository “ZepC – the ZeptoN Echo Transcompiler,” https://wgilreath.github.io/ZeptoN/ Accessed December 31, 2019.

[Moor 2014] Moore, John. “A case for keeping primitives in Java,” JavaWorld, https://www.javaworld.com/article/2150208/a-case-for-keeping-primitives-in-java.html. May 2014. Accessed December 27, 2019.

[Orac 2019] Oracle America, Inc., The Java Language Specification, 13th edition, https://docs.oracle.com/javase/specs/jls/se13/jls13.pdf. Accessed December 27, 2019.

[Wiki 2019a] Wikibooks, Java Programming. The WikiBooks Edition, https://en.wikibooks.org/wiki/Java_Programming/Keywords/void. Accessed December 30, 2019.

[Wiki 2019b] Wikibooks. BASIC Programming, October 13, 2019. https://en.wikibooks.org/wiki/BASIC_Programming/Beginning_BASIC/User_Input, Accessed November 9, 2019.

10. Download the Source Code

Download
You can download the full source code of this example here: ZeptoN is Putting Program into Java

William Gilreath

I am a software development engineer, computer scientist, mathematician, and writer. I am a senior machine learning engineer at VMware, Inc. https://www.wfgilreath.xyz
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Elena gillbert
4 years ago

Hi…
I’m Elena gillbert.Search Results
Featured snippet from the web
ZeptoN is Java, but it transcompiles the program entity into a class from the program entity, transpiles a main() method, and adds a set of boilerplate methods and attributes that are similar to the methods and attributes in other classes. Thus creating a default environment for use by a developer

Back to top button