Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/main/java/org/meteordev/starscript/Instruction.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ public enum Instruction {
Modulo,
Power,

BitwiseAnd,
BitwiseOr,
BitwiseXor,
BitwiseNot,
LeftShift,
RightShift,
UnsignedRightShift,

AddConstant,

Pop,
Expand Down
16 changes: 12 additions & 4 deletions src/main/java/org/meteordev/starscript/Starscript.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,26 @@ public Section run(Script script, StringBuilder sb) {
case Modulo: { Value b = pop(); Value a = pop(); if (a.isNumber() && b.isNumber()) push(Value.number(a.getNumber() % b.getNumber())); else error("Can only modulo 2 numbers."); break; }
case Power: { Value b = pop(); Value a = pop(); if (a.isNumber() && b.isNumber()) push(Value.number(Math.pow(a.getNumber(), b.getNumber()))); else error("Can only power 2 numbers."); break; }

case BitwiseAnd: { Value b = pop(); Value a = pop(); if (a.isNumber() && b.isNumber()) push(Value.number((long) a.getNumber() & (long) b.getNumber())); else error("This operation requires 2 numbers."); break; }
case BitwiseOr: { Value b = pop(); Value a = pop(); if (a.isNumber() && b.isNumber()) push(Value.number((long) a.getNumber() | (long) b.getNumber())); else error("This operation requires 2 numbers."); break; }
case BitwiseXor: { Value b = pop(); Value a = pop(); if (a.isNumber() && b.isNumber()) push(Value.number((long) a.getNumber() ^ (long) b.getNumber())); else error("This operation requires 2 numbers."); break; }
case LeftShift: { Value b = pop(); Value a = pop(); if (a.isNumber() && b.isNumber()) push(Value.number((long) a.getNumber() << (long) b.getNumber())); else error("This operation requires 2 numbers."); break; }
case RightShift: { Value b = pop(); Value a = pop(); if (a.isNumber() && b.isNumber()) push(Value.number((long) a.getNumber() >> (long) b.getNumber())); else error("This operation requires 2 numbers."); break; }
case UnsignedRightShift: { Value b = pop(); Value a = pop(); if (a.isNumber() && b.isNumber()) push(Value.number((long) a.getNumber() >>> (long) b.getNumber())); else error("This operation requires 2 numbers."); break; }

case AddConstant: { Value b = script.constants.get(script.code[ip++] & 0xFF); Value a = pop(); if (a.isNumber() && b.isNumber()) push(Value.number(a.getNumber() + b.getNumber())); else if (a.isString()) push(Value.string(a.getString() + b.toString())); else error("Can only add 2 numbers or 1 string and other value."); break; }

case Pop: pop(); break;
case Not: push(Value.bool(!pop().isTruthy())); break;
case Negate: { Value a = pop(); if (a.isNumber()) push(Value.number(-a.getNumber())); else error("This operation requires a number."); break; }
case BitwiseNot: { Value a = pop(); if (a.isNumber()) push(Value.number(~((long) a.getNumber()))); else error("This operation requires a number."); break; }

case Equals: push(Value.bool(pop().equals(pop()))); break;
case NotEquals: push(Value.bool(!pop().equals(pop()))); break;
case Greater: { Value b = pop(); Value a = pop(); if (a.isNumber() && b.isNumber()) push(Value.bool(a.getNumber() > b.getNumber())); else error("This operation requires 2 number."); break; }
case GreaterEqual: { Value b = pop(); Value a = pop(); if (a.isNumber() && b.isNumber()) push(Value.bool(a.getNumber() >= b.getNumber())); else error("This operation requires 2 number."); break; }
case Less: { Value b = pop(); Value a = pop(); if (a.isNumber() && b.isNumber()) push(Value.bool(a.getNumber() < b.getNumber())); else error("This operation requires 2 number."); break; }
case LessEqual: { Value b = pop(); Value a = pop(); if (a.isNumber() && b.isNumber()) push(Value.bool(a.getNumber() <= b.getNumber())); else error("This operation requires 2 number."); break; }
case Greater: { Value b = pop(); Value a = pop(); if (a.isNumber() && b.isNumber()) push(Value.bool(a.getNumber() > b.getNumber())); else error("This operation requires 2 numbers."); break; }
case GreaterEqual: { Value b = pop(); Value a = pop(); if (a.isNumber() && b.isNumber()) push(Value.bool(a.getNumber() >= b.getNumber())); else error("This operation requires 2 numbers."); break; }
case Less: { Value b = pop(); Value a = pop(); if (a.isNumber() && b.isNumber()) push(Value.bool(a.getNumber() < b.getNumber())); else error("This operation requires 2 numbers."); break; }
case LessEqual: { Value b = pop(); Value a = pop(); if (a.isNumber() && b.isNumber()) push(Value.bool(a.getNumber() <= b.getNumber())); else error("This operation requires 2 numbers."); break; }

case Variable: { String name = script.constants.get(script.code[ip++] & 0xFF).getString(); Supplier<Value> s = globals.getRaw(name); push(s != null ? s.get() : Value.null_()); break; }
case Get: { String name = script.constants.get(script.code[ip++] & 0xFF).getString(); Value v = pop(); if (!v.isMap()) { push(Value.null_()); break; } Supplier<Value> s = v.getMap().getRaw(name); push(s != null ? s.get() : Value.null_()); break; }
Expand Down
34 changes: 21 additions & 13 deletions src/main/java/org/meteordev/starscript/compiler/Compiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,19 +88,26 @@ public void visitBinary(Expr.Binary expr) {
else compile(expr.getRight());

switch (expr.op) {
case Plus: script.write(Instruction.Add); break;
case Minus: script.write(Instruction.Subtract); break;
case Star: script.write(Instruction.Multiply); break;
case Slash: script.write(Instruction.Divide); break;
case Percentage: script.write(Instruction.Modulo); break;
case UpArrow: script.write(Instruction.Power); break;

case EqualEqual: script.write(Instruction.Equals); break;
case BangEqual: script.write(Instruction.NotEquals); break;
case Greater: script.write(Instruction.Greater); break;
case GreaterEqual: script.write(Instruction.GreaterEqual); break;
case Less: script.write(Instruction.Less); break;
case LessEqual: script.write(Instruction.LessEqual); break;
case Plus: script.write(Instruction.Add); break;
case Minus: script.write(Instruction.Subtract); break;
case Star: script.write(Instruction.Multiply); break;
case Slash: script.write(Instruction.Divide); break;
case Percentage: script.write(Instruction.Modulo); break;
case UpArrow: script.write(Instruction.Power); break;

case EqualEqual: script.write(Instruction.Equals); break;
case BangEqual: script.write(Instruction.NotEquals); break;
case Greater: script.write(Instruction.Greater); break;
case GreaterEqual: script.write(Instruction.GreaterEqual); break;
case Less: script.write(Instruction.Less); break;
case LessEqual: script.write(Instruction.LessEqual); break;

case Ampersand: script.write(Instruction.BitwiseAnd); break;
case VBar: script.write(Instruction.BitwiseOr); break;
case VBarUpArrow: script.write(Instruction.BitwiseXor); break;
case DoubleLess: script.write(Instruction.LeftShift); break;
case DoubleGreater: script.write(Instruction.RightShift); break;
case TripleGreater: script.write(Instruction.UnsignedRightShift); break;
}
}

Expand All @@ -110,6 +117,7 @@ public void visitUnary(Expr.Unary expr) {

if (expr.op == Token.Bang) script.write(Instruction.Not);
else if (expr.op == Token.Minus) script.write(Instruction.Negate);
else if (expr.op == Token.Tilde) script.write(Instruction.BitwiseNot);
}

@Override
Expand Down
26 changes: 24 additions & 2 deletions src/main/java/org/meteordev/starscript/compiler/Lexer.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,26 @@ public void next() {

case '=': if (match('=')) createToken(Token.EqualEqual); else unexpected(); break;
case '!': createToken(match('=') ? Token.BangEqual : Token.Bang); break;
case '>': createToken(match('=') ? Token.GreaterEqual : Token.Greater); break;
case '<': createToken(match('=') ? Token.LessEqual : Token.Less); break;
case '>':
if (match('=')) {
createToken(Token.GreaterEqual);
break;
}
if (match('>')) {
createToken(match('>') ? Token.TripleGreater : Token.DoubleGreater);
break;
}
createToken(Token.Greater); break;
case '<':
if (match('=')) {
createToken(Token.LessEqual);
break;
}
if (match('<')) {
createToken(Token.DoubleLess);
break;
}
createToken(Token.Less); break;

case '+': createToken(Token.Plus); break;
case '-': createToken(Token.Minus); break;
Expand All @@ -71,6 +89,10 @@ public void next() {
createToken(Token.Section, source.substring(start + 1, current));
break;

case '&': createToken(Token.Ampersand); break;
case '|': createToken(match('^') ? Token.VBarUpArrow : Token.VBar); break;
case '~': createToken(Token.Tilde); break;

default: unexpected();
}
}
Expand Down
19 changes: 16 additions & 3 deletions src/main/java/org/meteordev/starscript/compiler/Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,22 @@ private Expr term() {

private Expr factor() {
int start = previous.start;
Expr expr = unary();
Expr expr = bitwise();

while (match(Token.Star, Token.Slash, Token.Percentage, Token.UpArrow)) {
Token op = previous.token;
Expr right = bitwise();
expr = new Expr.Binary(start, previous.end, expr, op, right);
}

return expr;
}

private Expr bitwise() {
int start = previous.start;
Expr expr = unary();

while (match(Token.Ampersand, Token.VBar, Token.VBarUpArrow, Token.DoubleLess, Token.DoubleGreater, Token.TripleGreater)) {
Token op = previous.token;
Expr right = unary();
expr = new Expr.Binary(start, previous.end, expr, op, right);
Expand All @@ -159,7 +172,7 @@ private Expr factor() {
}

private Expr unary() {
if (match(Token.Bang, Token.Minus)) {
if (match(Token.Bang, Token.Minus, Token.Tilde)) {
int start = previous.start;

Token op = previous.token;
Expand Down Expand Up @@ -352,7 +365,7 @@ public static class Result {

/** Helper method that returns true if there was 1 or more errors. */
public boolean hasErrors() {
return errors.size() > 0;
return !errors.isEmpty();
}

public void accept(Expr.Visitor visitor) {
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/org/meteordev/starscript/compiler/Token.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,10 @@ public enum Token {

Section,

Ampersand, VBar,
Tilde, VBarUpArrow,
DoubleGreater, TripleGreater,
DoubleLess,

Error, EOF
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ public static void get(String source, List<SemanticToken> tokens) {
case Bang:
case QuestionMark:
case Colon:
case Ampersand:
case VBar:
case VBarUpArrow:
case DoubleLess:
case DoubleGreater:
case TripleGreater:
case Tilde:
tokens.add(new SemanticToken(SemanticTokenType.Operator, lexer.start, lexer.current));
break;

Expand Down