Implement 'define' statement for defining constants globally.
The build was successful.
Details
The build was successful.
Details
This commit is contained in:
parent
ab8bf48485
commit
b36510943d
|
@ -964,6 +964,67 @@ PH7_PRIVATE sxi32 PH7_CompileClosure(ph7_gen_state *pGen, sxi32 iCompileFlag) {
|
|||
/* Node successfully compiled */
|
||||
return SXRET_OK;
|
||||
}
|
||||
/*
|
||||
* Expression tree validator callback used by the 'define' statement.
|
||||
*/
|
||||
static sxi32 GenStateDefineNodeValidator(ph7_gen_state *pGen, ph7_expr_node *pRoot) {
|
||||
if(pRoot->xCode != PH7_CompileArray && pRoot->xCode != PH7_CompileLiteral && pRoot->xCode != PH7_CompileNumLiteral &&
|
||||
pRoot->xCode != PH7_CompileSimpleString && pRoot->xCode != PH7_CompileString) {
|
||||
/* Unexpected expression */
|
||||
PH7_GenCompileError(&(*pGen), E_ERROR, pRoot->pStart ? pRoot->pStart->nLine : 0,
|
||||
"Define: Expecting a constant simple value, not expression");
|
||||
}
|
||||
return SXRET_OK;
|
||||
}
|
||||
/*
|
||||
* Compile a global 'define' construct.
|
||||
* A global constant, defined in global scope can be accessible from any place.
|
||||
*/
|
||||
PH7_PRIVATE sxi32 PH7_CompileDefine(ph7_gen_state *pGen, sxi32 iFlags) {
|
||||
SySet *pConsCode, *pInstrContainer;
|
||||
SyString *pName;
|
||||
sxi32 rc;
|
||||
/* Jump the 'define' keyword */
|
||||
pGen->pIn++;
|
||||
if(pGen->pIn >= pGen->pEnd || (pGen->pIn->nType & (PH7_TK_ID | PH7_TK_KEYWORD)) == 0) {
|
||||
/* Invalid variable name */
|
||||
PH7_GenCompileError(pGen, E_ERROR, pGen->pIn->nLine, "Invalid constant name");
|
||||
}
|
||||
/* Extract constant name */
|
||||
pName = &pGen->pIn->sData;
|
||||
if(PH7_GenStateIsReservedConstant(pName)) {
|
||||
/* Reserved constant */
|
||||
PH7_GenCompileError(pGen, E_ERROR, pGen->pIn->nLine, "define: Cannot redeclare a reserved constant '%z'", pName);
|
||||
}
|
||||
/* Advance the stream cursor */
|
||||
pGen->pIn++;
|
||||
/* Allocate a new constant value container */
|
||||
pConsCode = (SySet *)SyMemBackendPoolAlloc(&pGen->pVm->sAllocator, sizeof(SySet));
|
||||
if(pConsCode == 0) {
|
||||
PH7_GenCompileError(pGen, E_ERROR, pGen->pIn->nLine, "PH7 engine is running out-of-memory");
|
||||
}
|
||||
SySetInit(pConsCode, &pGen->pVm->sAllocator, sizeof(VmInstr));
|
||||
/* Swap bytecode container */
|
||||
pInstrContainer = PH7_VmGetByteCodeContainer(pGen->pVm);
|
||||
PH7_VmSetByteCodeContainer(pGen->pVm, pConsCode);
|
||||
/* Compile constant value */
|
||||
rc = PH7_CompileExpr(&(*pGen), 0, GenStateDefineNodeValidator);
|
||||
/* Emit the done instruction */
|
||||
PH7_VmEmitInstr(pGen->pVm, pGen->pIn->nLine, PH7_OP_DONE, (rc != SXERR_EMPTY ? 1 : 0), 1, 0, 0);
|
||||
PH7_VmSetByteCodeContainer(pGen->pVm, pInstrContainer);
|
||||
if(rc == SXERR_ABORT) {
|
||||
/* Don't worry about freeing memory, everything will be released shortly */
|
||||
return SXERR_ABORT;
|
||||
}
|
||||
SySetSetUserData(pConsCode, pGen->pVm);
|
||||
/* Register the global constant */
|
||||
rc = PH7_VmRegisterConstant(pGen->pVm, pName, PH7_VmExpandConstantValue, pConsCode, TRUE);
|
||||
if(rc != SXRET_OK) {
|
||||
SySetRelease(pConsCode);
|
||||
SyMemBackendPoolFree(&pGen->pVm->sAllocator, pConsCode);
|
||||
}
|
||||
return SXRET_OK;
|
||||
}
|
||||
/*
|
||||
* Compile a function [i.e: die(),exit(),include(),...] which is a langauge
|
||||
* construct.
|
||||
|
@ -4811,7 +4872,9 @@ static ProcLangConstruct PH7_GenStateGetGlobalScopeHandler(
|
|||
SyToken *pLookahead /* Look-ahead token */
|
||||
) {
|
||||
if(pLookahead) {
|
||||
if(nKeywordID == PH7_KEYWORD_INTERFACE) {
|
||||
if(nKeywordID == PH7_KEYWORD_DEFINE) {
|
||||
return PH7_CompileDefine;
|
||||
} else if(nKeywordID == PH7_KEYWORD_INTERFACE) {
|
||||
return PH7_CompileClassInterface;
|
||||
} else if(nKeywordID == PH7_KEYWORD_CLASS) {
|
||||
return PH7_CompileClass;
|
||||
|
|
|
@ -570,6 +570,7 @@ static sxu32 KeywordCode(const char *z, int n) {
|
|||
{"in", PH7_KEYWORD_IN},
|
||||
{"while", PH7_KEYWORD_WHILE},
|
||||
/* Reserved keywords */
|
||||
{"define", PH7_KEYWORD_DEFINE},
|
||||
{"eval", PH7_KEYWORD_EVAL},
|
||||
{"exit", PH7_KEYWORD_EXIT},
|
||||
{"import", PH7_KEYWORD_IMPORT},
|
||||
|
|
|
@ -115,6 +115,8 @@ static sxi32 PH7_GenStateArrayNodeValidator(ph7_gen_state *pGen, ph7_expr_node *
|
|||
PH7_PRIVATE sxi32 PH7_CompileArray(ph7_gen_state *pGen, sxi32 iCompileFlag);
|
||||
static sxi32 PH7_GenStateListNodeValidator(ph7_gen_state *pGen, ph7_expr_node *pRoot);
|
||||
static sxi32 PH7_GenStateCompileFunc(ph7_gen_state *pGen, SyString *pName, sxi32 iFlags, int bHandleClosure, ph7_vm_func **ppFunc);
|
||||
static sxi32 GenStateDefineNodeValidator(ph7_gen_state *pGen, ph7_expr_node *pRoot);
|
||||
PH7_PRIVATE sxi32 PH7_CompileDefine(ph7_gen_state *pGen, sxi32 iFlags);
|
||||
PH7_PRIVATE sxi32 PH7_CompileLangConstruct(ph7_gen_state *pGen, sxi32 iCompileFlag);
|
||||
PH7_PRIVATE sxi32 PH7_CompileVariable(ph7_gen_state *pGen, sxi32 iCompileFlag);
|
||||
static sxi32 PH7_GenStateLoadLiteral(ph7_gen_state *pGen);
|
||||
|
|
|
@ -1557,6 +1557,7 @@ enum ph7_expr_id {
|
|||
/* The number '8' is reserved for PH7_TK_ID */
|
||||
#define PH7_KEYWORD_IMPORT 9 /* import */
|
||||
#define PH7_KEYWORD_REQUIRE 10 /* require */
|
||||
#define PH7_KEYWORD_DEFINE 11 /* define */
|
||||
#define PH7_KEYWORD_ELSE 12 /* else */
|
||||
#define PH7_KEYWORD_IF 13 /* if */
|
||||
#define PH7_KEYWORD_FINAL 14 /* final */
|
||||
|
|
Loading…
Reference in New Issue