private Expr parseTermExpression(EnclosingScope scope, boolean terminated) {
		checkNotEof();

		int start = index;
		Token token = tokens.get(index);

		switch (token.kind) {
		case LeftBrace:
			return parseBracketedOrCastExpression(scope, terminated);
		case New:
		case This:
			return parseNewExpression(scope, terminated);
		case Identifier: {
			Identifier name = parseIdentifier();
			Expr term;
			if (tryAndMatch(terminated, LeftBrace) != null) {
				return parseInvokeExpression(scope, start, name, terminated, new Tuple<>());
			} else if (lookaheadSequence(terminated, Colon, New)) {
				// Identifier is lifetime name in "new" expression
				index = start;
				return parseNewExpression(scope, terminated);
			} else if (lookaheadSequence(terminated, LeftAngle)) {
				int tStart = index;
				// NOTE: need to check right brance after right angle to avoid strange
				// expressions (e.g. [ x < T,S > 1 ])
				if(skipTemplate(scope) && lookaheadSequence(terminated, LeftBrace)) {
					index = tStart;
					// This one is a little tricky, as we need some lookahead
					// effort. We want to see whether it is a method invocation with
					// lifetime arguments. But "Identifier < ..." can also be a
					// boolean expression!
					Tuple<? extends SyntacticItem> template = parseTemplateArguments(scope,terminated);
					match(LeftBrace);
					return parseInvokeExpression(scope, start, name, terminated, template);
				} else {
					// backtrack
					index = tStart;
				}
			} else if (lookaheadSequence(terminated, LeftCurly)) {
				// This indicates a named record initialiser which consists of a
				// name followed by a record initialiser.
				return parseRecordInitialiser(name, scope, terminated);
			} // no else if, in case the former one didn't return
			if (scope.isVariable(name)) {
				// Signals a local variable access
				Decl.Variable decl = scope.getVariableDeclaration(name);
				Expr var = new Expr.VariableAccess(Type.Void, scope.getVariableDeclaration(name));
				return annotateSourceLocation(var, start);
			} else if (scope.isFieldAlias(name)) {
				// Signals a field alias
				Decl.Variable var = scope.getVariableDeclaration(new Identifier("$"));
				Expr access = new Expr.RecordAccess(Type.Void, new Expr.VariableAccess(Type.Void, var), name);
				return annotateSourceLocation(access,start);
			} else {
				// Otherwise, this must be a static access of some kind.
				// Observe that, at this point, we cannot determine whether or
				// not this is a constant-access or a package-access which marks
				// the beginning of a constant-access.
				Decl.Link<Decl.StaticVariable> link = new Decl.Link(new Name(name));
				Expr var = new Expr.StaticVariableAccess(Type.Void, link);
				return annotateSourceLocation(var, start);
			}
		}
		case Null:
			return annotateSourceLocation(new Expr.Constant(Type.Void, new Value.Null()), index++);
		case True:
			return annotateSourceLocation(new Expr.Constant(Type.Void, new Value.Bool(true)), index++);
		case False:
			return annotateSourceLocation(new Expr.Constant(Type.Void, new Value.Bool(false)), index++);
		case BinaryLiteral: {
			byte val = parseBinaryLiteral(token);
			return annotateSourceLocation(new Expr.Constant(Type.Void, new Value.Byte(val)), index++);
		}
		case CharLiteral: {
			BigInteger val = parseCharacter(token.text);
			return annotateSourceLocation(new Expr.Constant(Type.Void, new Value.Int(val)), index++);
		}
		case IntegerLiteral: {
			BigInteger val = parseIntegerLiteral(token);
			return annotateSourceLocation(new Expr.Constant(Type.Void, new Value.Int(val)), index++);
		}
		case HexLiteral: {
			BigInteger val = parseHexLiteral(token);
			return annotateSourceLocation(new Expr.Constant(Type.Void, new Value.Int(val)), index++);
		}
		case StringLiteral: {
			byte[] val = parseUnicodeString(token);
			return annotateSourceLocation(new Expr.Constant(Type.Void, new Value.UTF8(val)), index++);
		}
		case Minus:
			return parseNegationExpression(scope, terminated);
		case VerticalBar:
			return parseLengthOfExpression(scope, terminated);
		case LeftSquare:
			return parseArrayInitialiserOrGeneratorExpression(scope, terminated);
		case LeftCurly:
			return parseRecordInitialiser(null, scope, terminated);
		case Shreak:
			return parseLogicalNotExpression(scope, terminated);
		case Star:
			if (lookaheadSequence(terminated, Star, Colon, New)) {
				// Star is default lifetime
				return parseNewExpression(scope, terminated);
			}
			return parseDereferenceExpression(scope, terminated);
		case Tilde:
			return parseBitwiseComplementExpression(scope, terminated);
		case Ampersand:
			return parseLambdaExpression(scope, terminated);
		}

		syntaxError("unrecognised term", token);
		return null;
	}
private Expr parseTermExpression ( EnclosingScope scope , boolean terminated ) { checkNotEof ( ) ; int start = index ; Token token = tokens . get ( index ) ; switch ( token . kind ) { case LeftBrace : return parseBracketedOrCastExpression ( scope , terminated ) ; case New : case This : return parseNewExpression ( scope , terminated ) ; case Identifier : { Identifier name = parseIdentifier ( ) ; Expr term ; if ( tryAndMatch ( terminated , LeftBrace ) != null ) { return parseInvokeExpression ( scope , start , name , terminated , new Tuple < > ( ) ) ; } else if ( lookaheadSequence ( terminated , Colon , New ) ) { index = start ; return parseNewExpression ( scope , terminated ) ; } else if ( lookaheadSequence ( terminated , LeftAngle ) ) { int tStart = index ; if ( skipTemplate ( scope ) && lookaheadSequence ( terminated , LeftBrace ) ) { index = tStart ; Tuple < ? extends SyntacticItem > template = parseTemplateArguments ( scope , terminated ) ; match ( LeftBrace ) ; return parseInvokeExpression ( scope , start , name , terminated , template ) ; } else { index = tStart ; } } else if ( lookaheadSequence ( terminated , LeftCurly ) ) { return parseRecordInitialiser ( name , scope , terminated ) ; } if ( scope . isVariable ( name ) ) { Decl . Variable decl = scope . getVariableDeclaration ( name ) ; Expr var = new Expr . VariableAccess ( Type . Void , scope . getVariableDeclaration ( name ) ) ; return annotateSourceLocation ( var , start ) ; } else if ( scope . isFieldAlias ( name ) ) { Decl . Variable var = scope . getVariableDeclaration ( new Identifier ( "$" ) ) ; Expr access = new Expr . RecordAccess ( Type . Void , new Expr . VariableAccess ( Type . Void , var ) , name ) ; return annotateSourceLocation ( access , start ) ; } else { Decl . Link < Decl . StaticVariable > link = new Decl . Link ( new Name ( name ) ) ; Expr var = new Expr . StaticVariableAccess ( Type . Void , link ) ; return annotateSourceLocation ( var , start ) ; } } case Null : return annotateSourceLocation ( new Expr . Constant ( Type . Void , new Value . Null ( ) ) , index ++ ) ; case True : return annotateSourceLocation ( new Expr . Constant ( Type . Void , new Value . Bool ( true ) ) , index ++ ) ; case False : return annotateSourceLocation ( new Expr . Constant ( Type . Void , new Value . Bool ( false ) ) , index ++ ) ; case BinaryLiteral : { byte val = parseBinaryLiteral ( token ) ; return annotateSourceLocation ( new Expr . Constant ( Type . Void , new Value . Byte ( val ) ) , index ++ ) ; } case CharLiteral : { BigInteger val = parseCharacter ( token . text ) ; return annotateSourceLocation ( new Expr . Constant ( Type . Void , new Value . Int ( val ) ) , index ++ ) ; } case IntegerLiteral : { BigInteger val = parseIntegerLiteral ( token ) ; return annotateSourceLocation ( new Expr . Constant ( Type . Void , new Value . Int ( val ) ) , index ++ ) ; } case HexLiteral : { BigInteger val = parseHexLiteral ( token ) ; return annotateSourceLocation ( new Expr . Constant ( Type . Void , new Value . Int ( val ) ) , index ++ ) ; } case StringLiteral : { byte [ ] val = parseUnicodeString ( token ) ; return annotateSourceLocation ( new Expr . Constant ( Type . Void , new Value . UTF8 ( val ) ) , index ++ ) ; } case Minus : return parseNegationExpression ( scope , terminated ) ; case VerticalBar : return parseLengthOfExpression ( scope , terminated ) ; case LeftSquare : return parseArrayInitialiserOrGeneratorExpression ( scope , terminated ) ; case LeftCurly : return parseRecordInitialiser ( null , scope , terminated ) ; case Shreak : return parseLogicalNotExpression ( scope , terminated ) ; case Star : if ( lookaheadSequence ( terminated , Star , Colon , New ) ) { return parseNewExpression ( scope , terminated ) ; } return parseDereferenceExpression ( scope , terminated ) ; case Tilde : return parseBitwiseComplementExpression ( scope , terminated ) ; case Ampersand : return parseLambdaExpression ( scope , terminated ) ; } syntaxError ( "unrecognised term" , token ) ; return null ; }
@param scope
The enclosing scope for this statement, which determines the
set of visible (i.e. declared) variables and also the current
indentation level.
@param terminated
This indicates that the expression is known to be terminated
(or not). An expression that's known to be terminated is one
which is guaranteed to be followed by something. This is
important because it means that we can ignore any newline
characters encountered in parsing this expression, and that
we'll never overrun the end of the expression (i.e. because
there's guaranteed to be something which terminates this
expression). A classic situation where terminated is true is
when parsing an expression surrounded in braces. In such case,
we know the right-brace will always terminate this expression.

@return