From 78c416c6b86a37a370c3000328957fc09e80364a Mon Sep 17 00:00:00 2001 From: belliash Date: Sat, 8 Jun 2019 12:55:57 +0200 Subject: [PATCH] Implement the implicit 'auto' type. An implicitly typed local variable is strongly typed just as if it had been declared the type, but the compiler determines the type. The following two declarations of $i are functionally equivalent: int $i = 10; // Explicitly typed. auto $i = 10; // Implicitly typed. --- engine/compiler.c | 6 +++++- engine/vm.c | 24 +++++++++++++----------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/engine/compiler.c b/engine/compiler.c index 0f270c3..ff48381 100644 --- a/engine/compiler.c +++ b/engine/compiler.c @@ -2466,6 +2466,8 @@ static sxi32 PH7_CompileVar(ph7_gen_state *pGen) { PH7_VmEmitInstr(pGen->pVm, pGen->pIn->nLine, PH7_OP_DONE, (rc != SXERR_EMPTY ? 1 : 0), 1, 0, 0); /* Restore default bytecode container */ PH7_VmSetByteCodeContainer(pGen->pVm, pInstrContainer); + } else if(nType == MEMOBJ_NULL) { + PH7_GenCompileError(&(*pGen), E_ERROR, pGen->pIn->nLine, "Implicitly-typed variable '$%z' must be initialized", pName); } /* Set static variable type */ sStatic.iFlags = nType; @@ -2492,6 +2494,8 @@ static sxi32 PH7_CompileVar(ph7_gen_state *pGen) { } else { PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_POP, 1, 0, 0, 0); } + } else if(nType == MEMOBJ_NULL) { + PH7_GenCompileError(&(*pGen), E_ERROR, pGen->pIn->nLine, "Implicitly-typed variable '$%z' must be initialized", pName); } else { pGen->pIn += 2; /* Jump the dollar '$' sign and variable name */ } @@ -4926,7 +4930,7 @@ static ProcLangConstruct PH7_GenStateGetStatementHandler( SyToken *pLookahead /* Look-ahead token */ ) { sxu32 n = 0; - if((nKeywordID & PH7_KEYWORD_TYPEDEF) != 0 || nKeywordID == PH7_KEYWORD_STATIC) { + if((nKeywordID & PH7_KEYWORD_AUTO) != 0 || (nKeywordID & PH7_KEYWORD_TYPEDEF) != 0 || nKeywordID == PH7_KEYWORD_STATIC) { if(nKeywordID == PH7_KEYWORD_STATIC && pLookahead && (pLookahead->nType & PH7_TK_OP)) { const ph7_expr_op *pOp = (const ph7_expr_op *)pLookahead->pUserData; if(pOp && pOp->iOp == EXPR_OP_DC /*::*/) { diff --git a/engine/vm.c b/engine/vm.c index f24c250..24af4f4 100644 --- a/engine/vm.c +++ b/engine/vm.c @@ -2421,20 +2421,22 @@ static sxi32 VmByteCodeExec( PH7_VmThrowError(&(*pVm), PH7_CTX_ERR, "Redeclaration of ā€˜$%zā€™ variable", &sName); } - if(pInstr->iP2 & MEMOBJ_MIXED && (pInstr->iP2 & MEMOBJ_HASHMAP) == 0) { - pObj->nType = MEMOBJ_MIXED | MEMOBJ_VOID; - } else { - if(pInstr->iP2 & MEMOBJ_HASHMAP) { - ph7_hashmap *pMap; - pMap = PH7_NewHashmap(&(*pVm), 0, 0); - if(pMap == 0) { - PH7_VmMemoryError(&(*pVm)); + if(pInstr->iP2 != MEMOBJ_NULL) { + if(pInstr->iP2 & MEMOBJ_MIXED && (pInstr->iP2 & MEMOBJ_HASHMAP) == 0) { + pObj->nType = MEMOBJ_MIXED | MEMOBJ_VOID; + } else { + if(pInstr->iP2 & MEMOBJ_HASHMAP) { + ph7_hashmap *pMap; + pMap = PH7_NewHashmap(&(*pVm), 0, 0); + if(pMap == 0) { + PH7_VmMemoryError(&(*pVm)); + } + pObj->x.pOther = pMap; } - pObj->x.pOther = pMap; + MemObjSetType(pObj, pInstr->iP2); } - MemObjSetType(pObj, pInstr->iP2); + pTos->nIdx = SXU32_HIGH; /* Mark as constant */ } - pTos->nIdx = SXU32_HIGH; /* Mark as constant */ } break; }