From 830671c2210191f69ddc403cc12f5454bb55b0f0 Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Fri, 21 Feb 2020 10:39:05 -0800 Subject: Add surface syntax for "this type" (#1236) Within the context of an aggregate type (or an `extension` of one), the programmer can use `this` to refer to the "current" instance of the surrounding type, but there is no easy way to utter the name of the type itself. This is especially relevant inside of an `interface`, where the type of `this` isn't actually the `interface` type, but rather a placeholder for the as-yet-unknown concrete type that will implement the interface. This change adds a keyword `This` that works similarly to `this`, but names the current *type* instead of the current instance. It can be used to declare things like binary methods or factory functions in an interface: ``` interface IBasicMathType { This absoluteValue(); This sumWith(This left); } T doSomeMath(T value) { return value.sumWith(value.absoluteValue()); } ``` The `This` type is consistent with the type named `Self` in Rust and Swift (where Rust/Swift use `self` instead of `this`). Other names could be considered (e.g., `ThisType`) if we find that users don't like the name in this change. --- source/slang/slang-parser.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'source/slang/slang-parser.cpp') diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp index e5a1ad576..288962cd8 100644 --- a/source/slang/slang-parser.cpp +++ b/source/slang/slang-parser.cpp @@ -1794,6 +1794,19 @@ namespace Slang return parseTaggedUnionType(parser); } + /// Parse a `This` type expression + static RefPtr parseThisTypeExpr(Parser* parser) + { + RefPtr expr = new ThisTypeExpr(); + expr->scope = parser->currentScope; + return expr; + } + + static RefPtr parseThisTypeExpr(Parser* parser, void* /*userData*/) + { + return parseThisTypeExpr(parser); + } + static TypeSpec parseTypeSpec(Parser* parser) { TypeSpec typeSpec; @@ -1848,6 +1861,11 @@ namespace Slang typeSpec.expr = parseTaggedUnionType(parser); return typeSpec; } + else if(AdvanceIf(parser, "This")) + { + typeSpec.expr = parseThisTypeExpr(parser); + return typeSpec; + } Token typeName = parser->ReadToken(TokenType::Identifier); @@ -4995,6 +5013,7 @@ namespace Slang addBuiltinSyntax(session, scope, #KEYWORD, &CALLBACK) EXPR(this, parseThisExpr); + EXPR(This, parseThisTypeExpr); EXPR(true, parseTrueExpr); EXPR(false, parseFalseExpr); EXPR(__TaggedUnion, parseTaggedUnionType); -- cgit v1.2.3