Represent operators and operands as tree nodes
Expression as Tree

This notional machine represents a source code expression in the form of a tree. This makes the structure of the expression explicit, and it allows visualizing the various steps of expression evaluation. It also allows annotating the various subexpressions with their types.
An expression tree is essentially an abstract syntax tree (AST), focused on just an expression.
Here is an example Java expression:
1 + 2 + "AAA" + 3 + 4The corresponding expression tree shows not only the expression’s structure but also the types and values of all subexpressions:
78 Misconceptions Expressible in this Notional Machine
A notional machine focuses on a subset of the syntax and semantics of a programming language. The following misconceptions are related to the language features expressible in this notional machine.
ArithmeticPlusPrecedes
Addition has higher precedence than string concatenationArrayAccessWithParentheses
Parentheses are used to access an element in an arrayArrayAllocationWithoutNew
Arrays are created without the new keywordArrayBracketCountIsLength
The number of brackets in an array type or an array initializer corresponds to the length of the arrayArrayElementTypeRepeats
The type of a multi-dimensional array is written as T[] T[] T[]ArrayHasLengthMethod
To get the length of an array, one needs to call its length methodArrayInitializerContentsInBrackets
Array initializers list the elements in square bracketsArrayRankIsLength
Array rank and array length are the same thingAssignCompares
= compares two valuesAssignmentNotExpression
An assignment a=b is not an expressionCallOnPrimitive
One can invoke a method on primitive valuesCallRequiresVariable
One needs a variable to invoke a methodCannotChainMemberAccesses
Member accesses cannot be chained togetherCannotChainMemberToConstructor
Method calls or field accesses cannot be chained to a constructor invocationChainedMethodsNotCalledFromOutside
Chained methods are all called on the object at the beginning of the chainCharNotNumeric
Char is not a numeric typeComparisonWithBooleanLiteral
To test whether an expression is true or false, one must compare it to true or to falseCompositeExpressionsUntyped
Expressions that consist of multiple parts have no typeConstructorWithoutNew
One can write the constructor name, without new, to instantiate a classEvaluationResultsArePrinted
Evaluating an expression means outputting its resultExpressionAssigns
An expression that reads a variable also updates its value after the evaluationExpressionsDynamicallyTyped
One has to evaluate an expression to determine its typeIntegerDivisionToRational
Dividing two integers can produce a rational numberLiteralNoExpression
A literal is not an expressionLiteralString
When passing a literal string as argument to a method, no quotes are neededMapToBooleanWithConditionalOperator
To map a boolean expression to a boolean, a conditional operator is necessaryMultiReferenceVariable
A reference variable can point to multiple objectsMultiValueVariable
A variable can contain more than one valueMultidimensionalArray
A multi-dimensional array is one single array objectNoAtomicExpression
Expressions must consist of more than one pieceNoCallOnStringLiteral
One cannot invoke methods on String literalsNoCastIfSameSize
If a variable is at least as big (bit-width) as a value, then no cast is needed to a assign the value to the variableNoFieldInheritance
An object contains only the fields declared in its classNoFloatLiterals
There are no float literalsNoImplicitWidening
Smaller types are never automatically converted into bigger ones without an explicit castNoJaggedArrays
Multi-dimensional arrays have a rectangular shapeNoLongLiterals
There are no long literalsNoMethodInheritance
Subclasses inherit fields but not methodsNoShortCircuit
&& and || always evaluate both operandsNoSingleLogicAnd
& is only a bitwise ANDNoStringToString
One cannot invoke toString() on a StringNullPointerExceptionCompileTime
NullPointerExceptions are detected at compile timeNumericToBooleanCoercion
Numeric types can be coerced to booleanObjectsMustBeNamed
A variable is needed to instantiate an objectOnlyInnermostArrayElements
Only the elements of the innermost array of a multi-dimensional array are accessibleOutOfBoundsElementsAreNull
Out-of-bounds array elements are nullOutsideInMethodNesting
Nested method calls are invoked outside inParenthesesOnlyIfArgument
() are optional for method calls without argumentsPrimitiveVariablesDynamicallyTyped
The type of a primitive variable depends on its valuePrivateAccessibleInSubclass
Private members of a superclass are accessible from a subclassRationalLiterals
Rational fractions are literalsReferenceToBooleanCoercion
Every reference type can be coerced to booleanReferenceToIntegerConversion
One can cast between references and intsRightToLeftChaining
Chained accesses are invoked from right to leftSingleQuoteString
String literals can be in single quotesStringLengthField
One can know the length of a String object by accessing its length fieldStringLiteralNoObject
One needs to call the String constructor to get a String object from a literalStringPlusStringifiesExpression
String concatenation stringifies non-String operand expressionsStringRepetitionOperator
The multiplication operator can repeat a String a number of timesSuperAlwaysHasParentheses
To call a method on a superclass, parentheses are needed after the keyword superTargetTyping
The type of a numerical expression depends on the type expected by the surrounding contextThisAssignable
One can assign to thisThisCanBeNull
this can be nullThisInConstructorIsNull
In a constructor, this is nullThisNoExpression
The name this is not an expressionToStringPrints
Invoking toString() prints somethingVariablesHoldExpressions
= stores an expression in a variableCannotChainAttributeAccesses
Attribute accesses cannot be chained togetherComparisonWithBoolLiteral
To test whether an expression is True or False, one must compare it to True or to FalseMapToBooleanWithTernaryOperator
To map a boolean expression to a bool, a ternary conditional operator is necessaryNoShortCircuit
and/or always evaluate both operandsNoSingleLogicAnd
& is only a bitwise ANDOutsideInFunctionNesting
Nested function calls are invoked outside inParenthesesOnlyIfArgument
() are optional for function calls without argumentsSelfAssignable
Reassigning self changes the object on which a method is calledSelfNoExpression
The name self is not an expressionStringLiteralNoObject
One needs to call str to instantiate a str object from a string literalCompareBooleanToConstant
To test whether an expression evaluates to true or false, one must compare it to a constant