Skip to content

Commit

Permalink
Fix this in non-static class methods
Browse files Browse the repository at this point in the history
  • Loading branch information
aNNiMON committed Aug 10, 2024
1 parent 3449081 commit 3eddbbc
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 59 deletions.
3 changes: 2 additions & 1 deletion docs/docs/en/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
## Next

### Fixes
- Fix passing arguments
- Fix passing command-line arguments to scripts
- Fix `this` in non-static class methods


## 2.0.0
Expand Down
7 changes: 7 additions & 0 deletions docs/docs/ru/changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# История изменений

## Next

### Исправления
- Исправлена передача аргументов командной строки скриптам
- Исправлен `this` в нестатических методах классов


## 2.0.0

### Критические изменения
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
public record ClassDeclaration(
String name,
List<ClassField> classFields,
List<ClassMethod> classMethods) implements Instantiable {
List<ClassMethod> classMethods
) implements Instantiable {

/**
* Create an instance and put evaluated fields with method declarations
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ public void addField(ClassField f) {
thisMap.set(f.name(), f.evaluableValue().eval());
}

public void addMethod(ClassMethod method) {
method.setClassInstance(this);
final String name = method.getName();
public void addMethod(ClassMethod m) {
final String name = m.name();
final var method = new ClassMethod(m, this);
thisMap.set(name, method);
if (name.equals(className)) {
constructor = method;
Expand Down
46 changes: 19 additions & 27 deletions ownlang-core/src/main/java/com/annimon/ownlang/lib/ClassMethod.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,28 @@

import java.util.Objects;

public class ClassMethod implements Function {
private final String name;
private final Function function;
private ClassInstance classInstance;
public record ClassMethod(
String name,
Function function,
ClassInstance classInstance
) implements Function {

public ClassMethod(String name, Function function) {
this.name = name;
this.function = function;
this(name, function, null);
}

public String getName() {
return name;
}

public void setClassInstance(ClassInstance classInstance) {
this.classInstance = classInstance;
public ClassMethod(ClassMethod m, ClassInstance instance) {
this(m.name, m.function, instance);
}

@Override
public Value execute(Value... args) {
ScopeHandler.push();
ScopeHandler.defineVariableInCurrentScope("this", classInstance.getThisMap());

try {
try (final var ignored = ScopeHandler.closeableScope()) {
if (classInstance != null) {
// non-static method
ScopeHandler.defineVariableInCurrentScope("this", classInstance.getThisMap());
}
return function.execute(args);
} finally {
ScopeHandler.pop();
}
}

Expand All @@ -38,12 +33,11 @@ public int getArgsCount() {
}

@Override
public boolean equals(Object obj) {
if (obj == this) return true;
if (obj == null || obj.getClass() != this.getClass()) return false;
var that = (ClassMethod) obj;
return Objects.equals(this.name, that.name) &&
Objects.equals(this.function, that.function);
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof ClassMethod that)) return false;
return Objects.equals(name, that.name)
&& Objects.equals(function, that.function);
}

@Override
Expand All @@ -53,8 +47,6 @@ public int hashCode() {

@Override
public String toString() {
return "ClassMethod[" +
"name=" + name + ", " +
"function=" + function + ']';
return "ClassMethod[" + name + ']';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public enum Operator {

private final String name;

private Operator(String name) {
Operator(String name) {
this.name = name;
}

Expand All @@ -36,7 +36,8 @@ public String getName() {
}
}

public final Node expr1, expr2;
public final Node expr1;
public final Node expr2;
public final Operator operation;

public ConditionalExpression(Operator operation, Node expr1, Node expr2) {
Expand All @@ -47,25 +48,20 @@ public ConditionalExpression(Operator operation, Node expr1, Node expr2) {

@Override
public Value eval() {
switch (operation) {
case AND:
return NumberValue.fromBoolean((expr1AsInt() != 0) && (expr2AsInt() != 0));
case OR:
return NumberValue.fromBoolean((expr1AsInt() != 0) || (expr2AsInt() != 0));

case NULL_COALESCE:
return nullCoalesce();

default:
return NumberValue.fromBoolean(evalAndCompare());
}
return switch (operation) {
case AND -> NumberValue.fromBoolean((expr1AsInt() != 0) && (expr2AsInt() != 0));
case OR -> NumberValue.fromBoolean((expr1AsInt() != 0) || (expr2AsInt() != 0));
case NULL_COALESCE -> nullCoalesce();
default -> NumberValue.fromBoolean(evalAndCompare());
};
}

private boolean evalAndCompare() {
final Value value1 = expr1.eval();
final Value value2 = expr2.eval();

double number1, number2;
double number1;
double number2;
if (value1.type() == Types.NUMBER) {
number1 = value1.asNumber();
number2 = value2.asNumber();
Expand All @@ -74,18 +70,15 @@ private boolean evalAndCompare() {
number2 = 0;
}

switch (operation) {
case EQUALS: return number1 == number2;
case NOT_EQUALS: return number1 != number2;

case LT: return number1 < number2;
case LTEQ: return number1 <= number2;
case GT: return number1 > number2;
case GTEQ: return number1 >= number2;

default:
throw new OperationIsNotSupportedException(operation);
}
return switch (operation) {
case EQUALS -> number1 == number2;
case NOT_EQUALS -> number1 != number2;
case LT -> number1 < number2;
case LTEQ -> number1 <= number2;
case GT -> number1 > number2;
case GTEQ -> number1 >= number2;
default -> throw new OperationIsNotSupportedException(operation);
};
}

private Value nullCoalesce() {
Expand Down
44 changes: 44 additions & 0 deletions ownlang-parser/src/test/resources/other/classScope.own
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
use std, debug

def testThisOnSingleInstance() {
s = new ClassScope({"id": 1})
assertEquals(1, s.getId())
assertEquals(1, s.getDataId())
}

def testThisOnMultipleInstances() {
s1 = new ClassScope({"id": 1})
s2 = new ClassScope({"id": 2})
s3 = new ClassScope({"id": 3})
assertEquals(1, s1.getId())
assertEquals(1, s1.getDataId())
assertEquals(2, s2.getId())
assertEquals(2, s2.getDataId())
assertEquals(3, s3.getId())
assertEquals(3, s3.getDataId())
}
def testToString() {
s1 = new ClassScope({"id": 1})
s2 = new ClassScope({"id": 2})
assertEquals("ClassScope{id=1}", s1.toString())
assertEquals("ClassScope{id=2}", s2.toString())
}

class ClassScope {
def ClassScope(data) {
this.id = data.id
this.data = data
}

def getId() {
return this.id
}

def getDataId() {
return this.data.id
}

def toString() {
return "ClassScope{id=" + this.id + "}"
}
}

0 comments on commit 3eddbbc

Please sign in to comment.