Skip to content

Commit

Permalink
First correct implementation of Interfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
Ruk33 committed Feb 14, 2016
1 parent 7783187 commit 91a13fe
Show file tree
Hide file tree
Showing 23 changed files with 390 additions and 25 deletions.
8 changes: 8 additions & 0 deletions src/main/java/com/ruke/vrjassc/Config.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.ruke.vrjassc;

public class Config {

public static final String VTYPE_NAME = "vtype";
public static final String STRUCT_HASHTABLE_NAME = "vrjass_structs";

}
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ protected String buildGetter() {
loadFunc = HashtableFunctionGetter.getLoadFunction(
property.getSymbol().getType()
);
} else {
loadFunc = HashtableFunctionGetter.getLoadFunction(null);
}

args.push(this.getHashtableName());
Expand All @@ -115,12 +117,17 @@ protected String buildGetter() {

protected String buildSetter() {
Chainable last = this.chain.peek();
Type symbolType = last.getSymbol().getType();
String result = this.buildGetter();

if (last.getSymbol().hasModifier(Modifier.STATIC)) {
if (last.getSymbol() != null && last.getSymbol().hasModifier(Modifier.STATIC)) {
result += "=" + this.value;
} else {
Type symbolType = null;

if (last.getSymbol() != null) {
symbolType = last.getSymbol().getType();
}

result = result.replaceFirst(
HashtableFunctionGetter.getLoadFunction(symbolType),
HashtableFunctionGetter.getSaveFunction(symbolType)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package com.ruke.vrjassc.translator;

import com.ruke.vrjassc.Config;
import com.ruke.vrjassc.translator.expression.BooleanExpression;
import com.ruke.vrjassc.translator.expression.BooleanExpression.Operator;
import com.ruke.vrjassc.translator.expression.ElseIfStatement;
import com.ruke.vrjassc.translator.expression.ExpressionList;
import com.ruke.vrjassc.translator.expression.FunctionDefinition;
import com.ruke.vrjassc.translator.expression.FunctionExpression;
import com.ruke.vrjassc.translator.expression.FunctionStatement;
import com.ruke.vrjassc.translator.expression.IfStatement;
import com.ruke.vrjassc.translator.expression.RawExpression;
import com.ruke.vrjassc.translator.expression.ReturnStatement;
import com.ruke.vrjassc.translator.expression.VariableExpression;
import com.ruke.vrjassc.vrjassc.symbol.ClassSymbol;
import com.ruke.vrjassc.vrjassc.symbol.FunctionSymbol;
import com.ruke.vrjassc.vrjassc.symbol.InterfaceSymbol;
import com.ruke.vrjassc.vrjassc.symbol.Symbol;

public class InterfaceMethodDefinition {

public static FunctionDefinition build(InterfaceSymbol _interface, FunctionSymbol method) {
FunctionDefinition function = new FunctionDefinition(method);
IfStatement checks = new IfStatement(new RawExpression("false"));
ElseIfStatement check = null;
Symbol implementation = null;
FunctionExpression func = null;
ExpressionList params = new ExpressionList();

params.add(new RawExpression("this"));

for (Symbol param : method.getParams()) {
params.add(new VariableExpression(param, null));
}

for (ClassSymbol _class : _interface.getImplementations()) {
check = new ElseIfStatement(
new BooleanExpression(
new RawExpression(Config.VTYPE_NAME),
Operator.EQUAL_EQUAL,
new RawExpression(String.valueOf(_class.getTypeId()))
)
);

implementation = _class.resolve(method.getName());
func = new FunctionExpression(implementation, false, params);

if (method.getType() == null) {
check.add(new FunctionStatement(func));
} else {
check.add(new ReturnStatement(func));
}

checks.add(check);
}

function.add(checks);

if (method.getType() == null) {
function.add(new FunctionStatement(func));
} else {
function.add(new ReturnStatement(func));
}

return function;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public String translate() {
if (this.name instanceof ChainExpression) {
((ChainExpression) this.name).setValue(this.value);

if (this.name.getSymbol().hasModifier(Modifier.STATIC)) {
if (this.name.getSymbol() != null && this.name.getSymbol().hasModifier(Modifier.STATIC)) {
return "set " + this.name.translate();
} else {
return "call " + this.name.translate();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import java.util.LinkedList;

import com.ruke.vrjassc.Config;
import com.ruke.vrjassc.translator.ChainExpressionTranslator;
import com.ruke.vrjassc.vrjassc.symbol.InterfaceSymbol;
import com.ruke.vrjassc.vrjassc.symbol.Modifier;
import com.ruke.vrjassc.vrjassc.symbol.Symbol;
import com.ruke.vrjassc.vrjassc.symbol.UserTypeSymbol;
Expand Down Expand Up @@ -47,16 +49,53 @@ public String translate() {
this.expressions.removeLast();

boolean isStatic = last.getSymbol().hasModifier(Modifier.STATIC);
boolean isInterface = last.getSymbol().getParentScope() instanceof InterfaceSymbol;
FunctionExpression func = ((FunctionExpression) last);

if (!isStatic) {
if (isInterface) {
ChainExpression vtype = new ChainExpression();
vtype.setHashtableName(this.chainTranslator.getHashtableName());

Expression lastInstance = null;

for (Expression i : this.expressions) {
if (i.getSymbol().getType() instanceof UserTypeSymbol) {
lastInstance = i;
}
}

vtype.append(lastInstance, null);
vtype.append(new RawExpression(Config.VTYPE_NAME), null);

func.getArguments().getList().addFirst(vtype);
}

func.getArguments().getList().addFirst(this);
} else if (last.getSymbol().getName().equals("allocate")) {
Expression lastInstance = null;

for (Expression e : this.expressions) {
if (e.getSymbol() instanceof UserTypeSymbol) {
lastInstance = e;
}
}

func.getArguments().getList().addFirst(
new RawExpression(
((UserTypeSymbol) lastInstance.getSymbol().getType()).getTypeId()
)
);
}

String result = last.translate();

if (!isStatic) {
func.getArguments().getList().removeFirst();

if (isInterface) {
func.getArguments().getList().removeFirst();
}
}

this.expressions.add(last);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@

import java.util.Collection;

import com.ruke.vrjassc.Config;
import com.ruke.vrjassc.vrjassc.symbol.ClassSymbol;
import com.ruke.vrjassc.vrjassc.symbol.FunctionSymbol;
import com.ruke.vrjassc.vrjassc.symbol.InterfaceSymbol;
import com.ruke.vrjassc.vrjassc.symbol.Modifier;
import com.ruke.vrjassc.vrjassc.symbol.Symbol;
import com.ruke.vrjassc.vrjassc.symbol.Type;
import com.ruke.vrjassc.vrjassc.symbol.UserTypeSymbol;
import com.ruke.vrjassc.vrjassc.util.Prefix;
import com.ruke.vrjassc.vrjassc.util.VariableTypeDetector;

Expand Down Expand Up @@ -43,6 +46,13 @@ public String translate() {
if (!this.function.hasModifier(Modifier.STATIC) && !thisAdded) {
this.getList().add(0, new RawExpression("integer this"));
}
} else if (this.function.getParentScope() instanceof InterfaceSymbol) {
this.getList().add(0, new RawExpression("integer this"));
this.getList().add(1, new RawExpression("integer " + Config.VTYPE_NAME));
}

if (this.function.getName().equals("allocate")) {
this.getList().add(0, new RawExpression("integer vrjass_type"));
}

if (this.expressions.isEmpty()) {
Expand Down Expand Up @@ -73,6 +83,23 @@ public Collection<Symbol> getUsedFunctions() {

@Override
public void add(Statement e) {
if (this.function.getName().equals("allocate")) {
if (e instanceof ReturnStatement) {
ChainExpression vtype = new ChainExpression();

vtype.setHashtableName(Config.STRUCT_HASHTABLE_NAME);
vtype.append(new VariableExpression(e.getSymbol(), null), null);
vtype.append(new RawExpression(Config.VTYPE_NAME), null);

this.body.add(
new AssignmentStatement(
vtype,
new RawExpression("vrjass_type")
)
);
}
}

this.body.add(e);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ public RawExpression(String expression) {
this(expression, null);
}

public RawExpression(int expression) {
this(String.valueOf(expression), null);
}

@Override
public Symbol getSymbol() {
return this.symbol;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.ruke.vrjassc.translator.expression;

import com.ruke.vrjassc.vrjassc.symbol.Symbol;

public class ReturnStatement extends Statement {

protected Expression value;
Expand All @@ -21,4 +23,10 @@ public String translate() {
return "return";
}

@Override
public Symbol getSymbol() {
if (this.value != null) return this.value.getSymbol();
return null;
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.ruke.vrjassc.translator.expression;

import com.ruke.vrjassc.vrjassc.symbol.ClassSymbol;
import com.ruke.vrjassc.vrjassc.symbol.Modifier;
import com.ruke.vrjassc.vrjassc.symbol.Symbol;
import com.ruke.vrjassc.vrjassc.util.Prefix;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import com.ruke.vrjassc.vrjassc.symbol.ScopeSymbol;
import com.ruke.vrjassc.vrjassc.symbol.Symbol;
import com.ruke.vrjassc.vrjassc.symbol.Type;
import com.ruke.vrjassc.vrjassc.symbol.UserTypeSymbol;
import com.ruke.vrjassc.vrjassc.symbol.VariableSymbol;
import com.ruke.vrjassc.vrjassc.util.TokenSymbolBag;
import com.ruke.vrjassc.vrjassc.util.Validator;
Expand All @@ -38,7 +39,9 @@ public class DefinitionPhase extends vrjassBaseVisitor<Symbol> {
private Validator validator;

private ScopeSymbol scope;


private int classesCount;

public DefinitionPhase(TokenSymbolBag symbols, ScopeSymbol scope) {
this.symbols = symbols;
this.validator = new Validator();
Expand Down Expand Up @@ -99,7 +102,7 @@ public Symbol visitInterfaceDefinition(InterfaceDefinitionContext ctx) {
String name = ctx.validName().getText();
Token token = ctx.getStart();

InterfaceSymbol _interface = new InterfaceSymbol(name, null, token);
InterfaceSymbol _interface = new InterfaceSymbol(name, 0, null, token);
_interface.setModifier(Modifier.PUBLIC, ctx.PUBLIC() != null);

this.defineOrThrowAlreadyDefinedException(this.scope, _interface);
Expand All @@ -120,7 +123,7 @@ public Symbol visitStructDefinition(StructDefinitionContext ctx) {
String name = ctx.name.getText();
Token token = ctx.name.getStart();

ClassSymbol _class = new ClassSymbol(name, null, token);
ClassSymbol _class = new ClassSymbol(name, ++this.classesCount, null, token);
_class.setModifier(Modifier.PUBLIC, ctx.PUBLIC() != null);

this.defineOrThrowAlreadyDefinedException(this.scope, _class);
Expand Down Expand Up @@ -169,7 +172,7 @@ public Symbol visitFunctionSignature(FunctionSignatureContext ctx) {

function.setModifier(Modifier.PUBLIC, ctx.PUBLIC() != null);

if (this.scope instanceof ClassSymbol) {
if (this.scope instanceof UserTypeSymbol) {
function.setModifier(Modifier.STATIC, ctx.STATIC() != null);
} else {
function.setModifier(Modifier.STATIC, true);
Expand Down Expand Up @@ -243,7 +246,9 @@ public Symbol visitVariableDeclaration(VariableDeclarationContext ctx) {
@Override
public Symbol visitGlobalVariableStatement(GlobalVariableStatementContext ctx) {
Symbol variable = this.visit(ctx.variableDeclaration());

variable.setModifier(Modifier.PUBLIC, ctx.PUBLIC() != null);
variable.setModifier(Modifier.STATIC, true);

this.symbols.put(ctx, variable);
this.defineOrThrowAlreadyDefinedException(this.scope, variable);
Expand Down
25 changes: 25 additions & 0 deletions src/main/java/com/ruke/vrjassc/vrjassc/phase/TranslationPhase.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.ruke.vrjassc.vrjassc.phase;

import com.ruke.vrjassc.translator.InterfaceMethodDefinition;
import com.ruke.vrjassc.translator.expression.AssignmentStatement;
import com.ruke.vrjassc.translator.expression.BooleanExpression;
import com.ruke.vrjassc.translator.expression.ChainExpression;
Expand Down Expand Up @@ -47,6 +48,7 @@
import com.ruke.vrjassc.vrjassc.antlr4.vrjassParser.GlobalVariableStatementContext;
import com.ruke.vrjassc.vrjassc.antlr4.vrjassParser.IfStatementContext;
import com.ruke.vrjassc.vrjassc.antlr4.vrjassParser.InitContext;
import com.ruke.vrjassc.vrjassc.antlr4.vrjassParser.InterfaceDefinitionContext;
import com.ruke.vrjassc.vrjassc.antlr4.vrjassParser.LibraryDefinitionContext;
import com.ruke.vrjassc.vrjassc.antlr4.vrjassParser.LibraryStatementContext;
import com.ruke.vrjassc.vrjassc.antlr4.vrjassParser.LocalVariableStatementContext;
Expand Down Expand Up @@ -75,6 +77,7 @@
import com.ruke.vrjassc.vrjassc.symbol.BuiltInTypeSymbol;
import com.ruke.vrjassc.vrjassc.symbol.ClassSymbol;
import com.ruke.vrjassc.vrjassc.symbol.FunctionSymbol;
import com.ruke.vrjassc.vrjassc.symbol.InterfaceSymbol;
import com.ruke.vrjassc.vrjassc.symbol.LibrarySymbol;
import com.ruke.vrjassc.vrjassc.symbol.Modifier;
import com.ruke.vrjassc.vrjassc.symbol.ScopeSymbol;
Expand Down Expand Up @@ -129,6 +132,10 @@ public Expression visitInit(InitContext ctx) {

Statement structHashtable = new VariableStatement(symbol, new RawExpression("InitHashtable()", null));
this.container.addGlobal(structHashtable);

Symbol vtype = new VariableSymbol("vtype", null, null);
vtype.setType(new BuiltInTypeSymbol("integer", null, null));
this.container.addGlobal(new VariableStatement(vtype, new RawExpression("-1")));
}

return this.container;
Expand Down Expand Up @@ -477,6 +484,24 @@ public Expression visitReturnStatement(ReturnStatementContext ctx) {
return new ReturnStatement(value);
}

@Override
public Expression visitInterfaceDefinition(InterfaceDefinitionContext ctx) {
InterfaceSymbol _interface = (InterfaceSymbol) this.symbols.get(ctx);

for (Symbol method : _interface.getChilds().values()) {
if (method instanceof FunctionSymbol == false) continue;

this.container.add(
InterfaceMethodDefinition.build(
_interface,
(FunctionSymbol) method
)
);
}

return null;
}

@Override
public Expression visitStructDefinition(StructDefinitionContext ctx) {
Statement statement;
Expand Down

0 comments on commit 91a13fe

Please sign in to comment.