Skip to content

Commit

Permalink
chore: remove symbol type and initial cast
Browse files Browse the repository at this point in the history
  • Loading branch information
Eddie authored and Eddie committed Jun 17, 2024
1 parent eb5621e commit 24990b2
Show file tree
Hide file tree
Showing 25 changed files with 285 additions and 149 deletions.
43 changes: 43 additions & 0 deletions README-types.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
Types
=====

| Name | Java Name | Min | Max |
|-----------|-----------|-----------|----------|
| `boolean` | `boolean` | `false` | `true` |
| `unicode` | `char` | `0` | `2^16-1` |
| `i8` | `byte` | `-128` | `127` |
| `i16` | `short` | `-2^15` | `2^15-1` |
| `i32` | `int` | `-2^31` | `2^31-1` |
| `i64` | `long` | `-2^63` | `2^63-1` |
| `f32` | `float` | | |
| `f64` | `double` | | |

## Implicit Conversion

- All integer and floating-point operations will preserve accuracy by converting to the largest precision type

```
x = 123 # i32 (default integer)
y = x + 0.0 # f32 (default float) implicit cast
```

## Explicit Conversion

- To limit precision, use explicit casting, for example:
- Casting from floating-point to integer
- Casting from i32 to i8

Syntax Idea:

```
x = 123 # i32 (default integer)
y = i8(x) # i8 decrease precision
z = f64(x) # f64 increase precision
```

Unicode Idea:

```
i = ordinal('0') # return index of the unicode
u = unicode(48) # return unicode value of numeric
```
Binary file modified out/artifacts/jungle_jar/jungle.jar
Binary file not shown.
4 changes: 2 additions & 2 deletions programs/hello-world.ast
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
SEQUENCE
PRINT
LITERAL_STRING Hello, World!\n
LITERAL_STRING Hello, World!\n
;
;
;
1 change: 1 addition & 0 deletions programs/loop.source
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ i = 3
loop (greaterThan i 0) {
print(i)
print('\n')
sleep 1000
i = - i 1
}
print("Blast off!\n")
5 changes: 5 additions & 0 deletions src/main/java/com/jungle/ast/INode.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,19 @@

public interface INode {
@NotNull NodeType getType();

// values
@Nullable String getRawValue();
@NotNull Boolean getBooleanValue();
@NotNull Character getCharacterValue();
@NotNull Integer getIntegerValue();
@NotNull Float getFloatValue();
@NotNull String getStringValue();

// children
@Nullable INode getLeft();
@Nullable INode getRight();

// helpers
boolean isLeaf();
}
11 changes: 4 additions & 7 deletions src/main/java/com/jungle/ast/Node.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import com.jungle.error.LoadError;
import com.jungle.error.SaveError;
import com.jungle.logger.FileLogger;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;

Expand Down Expand Up @@ -62,13 +61,11 @@ public Boolean getBooleanValue() {
@Override
@NotNull
public Character getCharacterValue() {
if (getRawValue() == null) {
throw new Error("failed to parse value as character - value is null");
}
if (getRawValue().length() != 1) {
String stringValue = getStringValue();
if (stringValue.length() != 1) {
throw new Error("failed to parse character as integer");
}
return StringEscapeUtils.unescapeJava(getRawValue()).charAt(0);
return stringValue.charAt(0);
}

@Override
Expand Down Expand Up @@ -103,7 +100,7 @@ public String getStringValue() {
if (getRawValue() == null) {
throw new Error("failed to parse value as string - value is null");
}
return StringEscapeUtils.unescapeJava(getRawValue());
return getRawValue();
}

// endregion
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/com/jungle/ast/NodeType.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ public enum NodeType {
LITERAL_STRING,

CAST_INTEGER,
CAST_LONG,
CAST_FLOAT,
CAST_CHARACTER,
CAST_DOUBLE,

// region Binary Operators - math
OPERATOR_ADD,
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/com/jungle/common/StringUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.jungle.common;

import org.apache.commons.lang3.StringEscapeUtils;
import org.jetbrains.annotations.NotNull;

public class StringUtils {
@NotNull
public static String unescapeString(@NotNull String s) {
return StringEscapeUtils.unescapeJava(s);
}
}
37 changes: 14 additions & 23 deletions src/main/java/com/jungle/compiler/operand/OperandStackContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import com.jungle.compiler.symbol.SymbolEntry;
import com.jungle.compiler.symbol.SymbolTable;
import com.jungle.compiler.symbol.SymbolType;
import com.jungle.logger.FileLogger;

import org.jetbrains.annotations.NotNull;
Expand All @@ -18,28 +17,29 @@ public class OperandStackContext {
// When the jvm instruction adds to the stack, add the node type to this compile-time stack
// When the jvm instruction removes from the stack, remove the type from this compile-time stack
@NotNull
private final Stack<OperandStackType> operandStackTypeStack;
private final Stack<OperandType> operandTypeStack;

@NotNull
private final SymbolTable symbolTable;

public OperandStackContext() {
super();
this.operandStackTypeStack = new Stack<>();
this.operandTypeStack = new Stack<>();
this.symbolTable = new SymbolTable();
}

@NotNull
public OperandStackType peek() {
return operandStackTypeStack.peek();
public OperandType peek() {
return operandTypeStack.peek();
}

@NotNull
public OperandStackType pop() {
return operandStackTypeStack.pop();
public OperandType pop() {
return operandTypeStack.pop();
}

public void push(@NotNull OperandStackType type) {
operandStackTypeStack.push(type);
public void push(@NotNull OperandType type) {
operandTypeStack.push(type);
}

@NotNull
Expand All @@ -60,15 +60,7 @@ public void visitLoad(
}

mv.visitVarInsn(entry.getType().getLoadOpcode(), entry.getIndex());

switch (entry.getType()) {
case BOOLEAN: push(OperandStackType.BOOLEAN); break;
case CHARACTER: push(OperandStackType.CHARACTER); break;
case INTEGER: push(OperandStackType.INTEGER); break;
case FLOAT: push(OperandStackType.FLOAT); break;
case OBJECT: push(OperandStackType.REFERENCE_OBJECT); break;
default: throw new Error("cannot push operand stack type - unhandled symbol type");
}
push(entry.getType());
}

public void visitStore(
Expand All @@ -78,20 +70,19 @@ public void visitStore(
// Pop value off the operand stack and set local variable index value
logger.debug("visit store " + variableName);

OperandStackType variableType = pop();
SymbolType variableSymbolType = variableType.getSymbolType();
OperandType variableType = pop();

SymbolEntry entry = getSymbolTable().get(variableName);
boolean isNotDefined = entry == null;
if (isNotDefined) {
entry = getSymbolTable().set(variableName, variableSymbolType);
entry = getSymbolTable().set(variableName, variableType);
} else {
if (entry.getType() != variableSymbolType) {
if (entry.getType() != variableType) {
throw new Error(
"symbol type mismatch - expected symbol type " +
entry.getType() +
" but got " +
variableSymbolType
variableType
);
}
}
Expand Down
25 changes: 0 additions & 25 deletions src/main/java/com/jungle/compiler/operand/OperandStackType.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,18 +1,79 @@
package com.jungle.compiler.symbol;
package com.jungle.compiler.operand;

import org.jetbrains.annotations.NotNull;
import org.objectweb.asm.Opcodes;

public enum SymbolType {
/**
* Types that exist on the operand stack.
*
* Used to determine the data type currently on the stack to validate and
* make decisions when program is compiled.
*
* https://docs.oracle.com/javase/specs/jvms/se6/html/Overview.doc.html
*/

public enum OperandType {
ADDRESS, // return address
INDEX,

// Reference types...
ARRAY,
OBJECT,
// Primitives...

BOOLEAN,
CHAR,

// Integral types...
BYTE,
CHARACTER,
SHORT,
INTEGER,
LONG,
FLOAT,
DOUBLE;

// Floating-point types...
DOUBLE,
FLOAT;

public int getConvertOpcode(@NotNull OperandType that) {
switch (this) {
case INTEGER: {
switch (that) {
case CHAR: return Opcodes.I2C;
case BYTE: return Opcodes.I2B;
case SHORT: return Opcodes.I2S;
case LONG: return Opcodes.I2L;
case FLOAT: return Opcodes.I2F;
case DOUBLE: return Opcodes.I2D;
default: break;
}
}
case LONG: {
switch (that) {
case INTEGER: return Opcodes.L2I;
case FLOAT: return Opcodes.L2F;
case DOUBLE: return Opcodes.L2D;
default: break;
}
}
case FLOAT: {
switch (that) {
case INTEGER: return Opcodes.F2I;
case LONG: return Opcodes.F2L;
case DOUBLE: return Opcodes.F2D;
default: break;
}
}
case DOUBLE: {
switch (that) {
case INTEGER: return Opcodes.D2I;
case LONG: return Opcodes.D2L;
case FLOAT: return Opcodes.D2F;
default: break;
}
}
default: break;
}
throw new Error("no convert opcode from " + this + " to " + that);
}

public int getAddOpcode() {
switch (this) {
Expand Down Expand Up @@ -61,7 +122,7 @@ public int getModuloOpcode() {

public int getStoreOpcode() {
switch (this) {
case CHARACTER: return Opcodes.ISTORE;
case CHAR: return Opcodes.ISTORE;
case INTEGER: return Opcodes.ISTORE;
case FLOAT: return Opcodes.FSTORE;
case DOUBLE: return Opcodes.DSTORE;
Expand All @@ -72,7 +133,7 @@ public int getStoreOpcode() {

public int getLoadOpcode() {
switch (this) {
case CHARACTER: return Opcodes.ILOAD;
case CHAR: return Opcodes.ILOAD;
case INTEGER: return Opcodes.ILOAD;
case FLOAT: return Opcodes.FLOAD;
case DOUBLE: return Opcodes.DLOAD;
Expand Down
11 changes: 8 additions & 3 deletions src/main/java/com/jungle/compiler/symbol/SymbolEntry.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,20 @@

import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import com.jungle.compiler.operand.OperandType;

public class SymbolEntry {
// identifier type
private final SymbolType type;
@NotNull
private final OperandType type;

// index of the local variable array
private final int index;

public SymbolEntry(int index, SymbolType type) {
public SymbolEntry(int index, @NotNull OperandType type) {
super();
this.index = index;
this.type = type;
Expand All @@ -21,7 +25,8 @@ public int getIndex() {
return index;
}

public SymbolType getType() {
@NotNull
public OperandType getType() {
return type;
}

Expand Down
Loading

0 comments on commit 24990b2

Please sign in to comment.