- Added the ability to parse a `Repr` statement

Check

- Added `GENERIC_TYPE_DECLARE` and `REPR` as new `SymbolType`(s)

Data

- `DiscardStatement` now implements the `bool replace(Statement, Statement)` method

MetaProcessor

- Added the ability to replace statements that occur within any _other_ statements which implement `MStatementSearchable` and `MStatementReplaceable`

Test cases

- Added `meta/simple_meta_replace.t` to test all of this

Diagrams

- Added diagram on how the meta system works
This commit is contained in:
Tristan B. Velloza Kildaire 2023-05-15 09:09:51 +02:00
parent ade5f39173
commit d6dfa38356
7 changed files with 93 additions and 3 deletions

BIN
macro_ast_replacemenet.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 428 KiB

BIN
macro_ast_replacemenet.xcf Normal file

Binary file not shown.

View File

@ -1359,6 +1359,15 @@ public final class Parser
ArrayIndex arrayIndexExpr = new ArrayIndex(indexTo, index);
addRetExp(arrayIndexExpr);
}
/* TODO: For `🧠 Feature: Meta-programming engine` (testing replaceability) */
else if(symbol == SymbolType.REPR)
{
import tlang.compiler.symbols.mcro : Repr;
Repr repr = new Repr();
addRetExp(repr);
nextToken();
}
/* If it is an identifier */
else if (symbol == SymbolType.IDENT_TYPE)
{

View File

@ -64,6 +64,17 @@ public enum SymbolType
EXTERN,
EXTERN_EFUNC,
EXTERN_EVAR,
/**
* `generic`
*/
GENERIC_TYPE_DECLARE,
/**
* REPR for `🧠 Feature: Meta-programming engine` testing
*/
REPR,
UNKNOWN
}
@ -380,6 +391,16 @@ public SymbolType getSymbolType(Token tokenIn)
{
return SymbolType.DISCARD;
}
/* generic keyword */
else if(cmp(token, "generic") == 0)
{
return SymbolType.GENERIC_TYPE_DECLARE;
}
/* generic keyword (for `🧠 Feature: Meta-programming engine` testing) */
else if(cmp(token, "repr") == 0)
{
return SymbolType.REPR;
}
/* An identifier/type (of some sorts) - further inspection in parser is needed */
else if(isPathIdentifier(token) || isIdentifier(token))
{

View File

@ -1007,9 +1007,28 @@ public final class DiscardStatement : Statement, MStatementSearchable, MStatemen
return matches;
}
public override void replace(Statement thiz, Statement that)
public override bool replace(Statement thiz, Statement that)
{
import std.stdio;
writeln("Replace() enter discard");
/* Check if our `Expression` matches, then replace */
if(expression == thiz)
{
expression = cast(Expression)that;
return true;
}
/* If not direct match, then recurse and replace (if possible) */
else if(cast(MStatementReplaceable)expression)
{
MStatementReplaceable replStmt = cast(MStatementReplaceable)expression;
return replStmt.replace(thiz, that);
}
/* If not direct match and not replaceable */
else
{
return false;
}
}
}

View File

@ -20,6 +20,8 @@ public class MetaProcessor
this(TypeChecker tc)
{
this.tc = tc;
// TODO: Extract the `CompilerConfig` from the `TypeChecker` (which in turn must take it in)
}
/**
@ -38,8 +40,6 @@ public class MetaProcessor
/**
* Apply type-rewriting to any `MTypeRewritable` AST node
* (a.k.a. a node which contains a type and can have it set)
*
* TODO: Add support for `sizeof` statement too
*/
if(cast(MTypeRewritable)curStmt)
{
@ -47,6 +47,36 @@ public class MetaProcessor
}
// TODO: Add sizeof number set here
/**
* TODO: Add support for `sizeof` statement too
*
* To do this we must consider where `Expression` can occur:
* Function arguments, Variable assignments
*
* Such that we can apply fixups there
*/
// expressionSearch();
if(cast(MStatementSearchable)curStmt && cast(MStatementReplaceable)curStmt)
{
// TOOD: Add replacement here
gprintln("Found a searchable and replaceable '"~curStmt.toString()~"'");
/**
* Searching for AST nodes of a given type
*/
MStatementSearchable searchableStmt = cast(MStatementSearchable)curStmt;
Statement[] foundStmts = searchableStmt.search(Repr.classinfo);
gprintln("Repr Search: "~to!(string)(foundStmts));
gprintln("isRepr?: "~to!(string)(cast(Repr)foundStmts[0] !is null));
/**
* Replacing an AST node with another
*/
MStatementReplaceable replStmt = cast(MStatementReplaceable)curStmt;
import tlang.compiler.symbols.expressions : IntegerLiteral, IntegerLiteralEncoding;
bool replStatus = replStmt.replace(foundStmts[0], new IntegerLiteral("69420", IntegerLiteralEncoding.SIGNED_INTEGER));
gprintln("Replacement worked?: "~to!(string)(replStatus));
}
/**
* If the current statement is a Container then recurse
@ -87,6 +117,11 @@ public class MetaProcessor
}
}
private void replace(MStatementSearchable from, TypeInfo_Class searchType, Statement replaceWith)
{
}
private void sizeOf_Literalize(Sizeof sizeofNumber)
{
// TODO: Via typechecker determine size with a lookup

View File

@ -0,0 +1,6 @@
module simple_meta_replace;
void function()
{
discard repr;
}