Created
October 25, 2010 09:28
-
-
Save sinfu/644666 to your computer and use it in GitHub Desktop.
[hack] writeln() and dump_istate() for CTFE
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git src/interpret.c src/interpret.c | |
index 5a6cf07..bed664f 100644 | |
--- src/interpret.c | |
+++ src/interpret.c | |
@@ -36,6 +36,7 @@ struct InterState | |
Expression *localThis; // value of 'this', or NULL if none | |
bool awaitingLvalueReturn; // Support for ref return values: | |
// Any return to this function should return an lvalue. | |
+ Loc loc; | |
InterState(); | |
}; | |
@@ -56,6 +57,74 @@ ArrayLiteralExp *createBlockDuplicatedArrayLiteral(Type *type, Expression *elem, | |
Expression * resolveReferences(Expression *e, Expression *thisval, bool *isReference = NULL); | |
Expression *getVarExp(Loc loc, InterState *istate, Declaration *d); | |
+ | |
+namespace rsinfu | |
+{ | |
+ Expression* interpret_writeln(InterState* istate, Expressions* arguments) | |
+ { | |
+ Expression* result = EXP_VOID_INTERPRET; | |
+ | |
+ if (arguments) | |
+ { | |
+ size_t const dim = arguments->dim; | |
+ | |
+ for (size_t i = 0; i < dim; ++i) | |
+ { | |
+ if (i > 0) | |
+ printf(", "); | |
+ | |
+ Expression* arg = static_cast<Expression*>(arguments->data[i]); | |
+ Expression* value = arg->interpret(istate); | |
+ | |
+ if (!value || value == EXP_CANT_INTERPRET) | |
+ { | |
+ result = EXP_CANT_INTERPRET; | |
+ break; | |
+ } | |
+ printf("%s", value->toChars()); | |
+ } | |
+ } | |
+ putchar('\n'); | |
+ return result; | |
+ } | |
+ | |
+ Expression* dump_variables(Dsymbols const* vars) | |
+ { | |
+ if (vars) | |
+ { | |
+ size_t const nvars = vars->dim; | |
+ | |
+ for (size_t i = 0; i < nvars; ++i) | |
+ { | |
+ VarDeclaration* var = static_cast<VarDeclaration*>(vars->data[i]); | |
+ printf("\t%s %s = %s\n", var->type->toChars(), | |
+ var->ident->toChars(), | |
+ var->value->toChars()); | |
+ } | |
+ } | |
+ return EXP_VOID_INTERPRET; | |
+ } | |
+ | |
+ Expression* dump_istate(InterState const* istate) | |
+ { | |
+ if (istate) | |
+ { | |
+ printf("@ %s(%u)\n", istate->loc.filename, | |
+ istate->loc.linnum); | |
+ | |
+ if (FuncDeclaration* fd = istate->fd) | |
+ { | |
+ printf("# %s %s\n", fd->type->toChars(), | |
+ fd->ident->toChars()); | |
+ dump_variables(fd->parameters); | |
+ } | |
+ dump_variables(&istate->vars); | |
+ puts("--------------------"); | |
+ } | |
+ return EXP_VOID_INTERPRET; | |
+ } | |
+} | |
+ | |
/************************************* | |
* Attempt to interpret a function given the arguments. | |
* Input: | |
@@ -90,6 +159,13 @@ Expression *FuncDeclaration::interpret(InterState *istate, Expressions *argument | |
if (cantInterpret || semanticRun == PASSsemantic3) | |
return NULL; | |
+#if 1 | |
+ if (strcmp(ident->string, "writeln") == 0) | |
+ return rsinfu::interpret_writeln(istate, arguments); | |
+ if (strcmp(ident->string, "dump_istate") == 0) | |
+ return rsinfu::dump_istate(istate); | |
+#endif | |
+ | |
if (!fbody) | |
{ cantInterpret = 1; | |
error("cannot be interpreted at compile time," | |
@@ -307,7 +383,30 @@ Expression *FuncDeclaration::interpret(InterState *istate, Expressions *argument | |
{ if (istate->start != this) \ | |
return NULL; \ | |
istate->start = NULL; \ | |
- } | |
+ } \ | |
+ rsinfu::location_keeper location_keeper_(this, istate); | |
+ | |
+namespace rsinfu | |
+{ | |
+ struct location_keeper | |
+ { | |
+ location_keeper(Statement const* stmt, InterState* istate) | |
+ : oldloc_(istate ? istate->loc : 0), | |
+ istate_(istate) | |
+ { | |
+ if (istate_) istate_->loc = stmt->loc; | |
+ } | |
+ | |
+ ~location_keeper() | |
+ { | |
+ if (istate_) istate_->loc = oldloc_; | |
+ } | |
+ | |
+ private: | |
+ Loc oldloc_; | |
+ InterState* istate_; | |
+ }; | |
+} | |
/*********************************** | |
* Interpret the statement. | |
@@ -2830,12 +2929,12 @@ Expression *CallExp::interpret(InterState *istate) | |
} | |
else | |
{ | |
- if (!fd->fbody) | |
- { | |
- error("%s cannot be interpreted at compile time," | |
- " because it has no available source code", fd->toChars()); | |
- return EXP_CANT_INTERPRET; | |
- } | |
+// if (!fd->fbody) | |
+// { | |
+// error("%s cannot be interpreted at compile time," | |
+// " because it has no available source code", fd->toChars()); | |
+// return EXP_CANT_INTERPRET; | |
+// } | |
Expression *eresult = fd->interpret(istate, arguments); | |
if (eresult) | |
e = eresult; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment