Skip to content

Instantly share code, notes, and snippets.

@sinfu
Created October 25, 2010 09:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sinfu/644666 to your computer and use it in GitHub Desktop.
Save sinfu/644666 to your computer and use it in GitHub Desktop.
[hack] writeln() and dump_istate() for CTFE
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