0

Preface

I am trying to write an interpreter/compiler for the first time. Tokenization and parsing are already a thing, that I seem to have figured out. I still find myself struggling because there are some language constructs that are hard to model. Please see the example code that I am trying to transform into an abstract syntax tree.

class Class1 {
  var someVariable = true;
}

class Class2 {
  var instanceOf1 = new Class1();
  func getSomething(): Class1 {
    return instanceOf1;
  }
}

class Class3 {
  func assignFromChainedExpressions() {
    var result = new Class2().getSomething().someVariable;
                 -----------1 -------------2 -----------3
  }

  func assignToChainedExpressions() {
    new Class2().getSomething().someVariable = false;
    -----------4 -------------5 -----------6
  }
}

The underlined expressions are modeled in the AST as:

1,4: ClassInstantiation
2,5: MethodCall
4,6: VariableAccess

Questions:

A. Should chained Expressions be modeled as an array should they be nested into each other? What is the most practical model for later evaluation and traversal?

B. In the func assignToChainedExpressions, does it make sense to assign a value to a chain, where the first Expression is a ClassInstantiation? The instance itself will be thrown away during runtime, I suppose.

C. Most examples use a very simple model for an Assignment operation. See:

class Assignment { string Identifier { get; } Expression Expression { get; } }

How should a more complex assignment be modeled, if the left side of the operation is an Expression as well?


Edit1:

Would it be a good idea to model assignFromChainedExpressions like this:

AnonymousVariableDeclaration(value: new Class2())          // anon1
AnonymousVariableDeclaration(value: anon1.getSomeThing())  // anon2
VariableDeclaration(name: "result", value: anon2.someVariable);

Would it be a good idea to model assignToChainedExpressions like this:

AnonymousVariableDeclaration(value: new Class2())          // anon1
AnonymousVariableDeclaration(value: anon1.getSomeThing())  // anon2
Assign(anon2.someVariable, false)
Hamed
  • 5,867
  • 4
  • 32
  • 56
Sebastian Krogull
  • 1,468
  • 1
  • 15
  • 31
  • 1
    A. The nested version seems more common. B. Does the code make sense? Not really, but that doesn't mean that you shouldn't allow it. Code like this is legal in any language I know (except the one that don't have objects or assignments, of course). C. The common solution would be to make the left operand an expression as well and then reject any expressions that can't be assigned to during semantic analysis. You could also define an `LValue` class that represents only expressions that can be assigned to and then reject the expressions that aren't l-values directly in a parser action. – sepp2k Feb 18 '20 at 10:19
  • @sepp2k Your help is really appreciated and valued! Good points made. Please take a look at `Edit1` – Sebastian Krogull Feb 18 '20 at 11:38
  • 1
    I'm not really sure which purpose `AnonymousVariableDeclaration` serves in your edit. The AST for `new Class2().getSomething().someVariable` should look something like this: https://pastebin.com/NNUd01Qp And then you'd use that AST as the value in the `VariableDeclaration` or the left operand in the `Assign` respectively. – sepp2k Feb 18 '20 at 12:36
  • @sepp2k The picture gets clearer. You should probably create an answer for that. One remaining question: Would you treat `FieldAccess` and scoped `VariableAccess` as the same thing? – Sebastian Krogull Feb 18 '20 at 13:43
  • 1
    I'd have one type of Expression for expressions of the form `.` (i.e. "explicit" field accesses) and another for expressions of the form `` (i.e. accesses of a variable in local or global scope or implicit field accesses on `this`). For the latter kind of variable access, it'd be up to the semantic analysis to determine which scope the accessed variable belongs to. – sepp2k Feb 18 '20 at 14:32
  • 1
    By the way, something that's helpful for questions like these is to look at the ASTs generated by real compilers and look what they do. For C# there's the Roslyn Syntax Visualizer for Visual Studio and also an [online version available here](https://sharplab.io/#v2:C4LghgzsA0AmIGoA+ABATARgLACgUGYACdQgYUIG9dCbCBLAO2EIA8Bua2zmg4gFkIBZABQBKSt1o0GAUwDuZMQDoAYgHs1yloQC8hPmg44pAX0mTe5dZvE6AfIWAALOhCMmgA==). – sepp2k Feb 18 '20 at 18:59
  • @sepp2k You‘ve given me a lot of helpful information. This will definitely help me dive deeper! I might open source the compiler/interpreter. If you’d be interested in it, even if you just want to take a look, just let me know :) – Sebastian Krogull Feb 18 '20 at 20:17

0 Answers0