mirror of https://github.com/tbklang/tlang.git
Parsing
- 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:
parent
ade5f39173
commit
d6dfa38356
Binary file not shown.
After Width: | Height: | Size: 428 KiB |
Binary file not shown.
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
module simple_meta_replace;
|
||||
|
||||
void function()
|
||||
{
|
||||
discard repr;
|
||||
}
|
Loading…
Reference in New Issue