コード例 #1
0
ファイル: ejparse.c プロジェクト: PolBadWolf/wive-ng-web
static int parse(ej_t *ep, int state, int flags)
{
	a_assert(ep);

	switch (state) {
/*
 *	Any statement, function arguments or conditional expressions
 */
	case STATE_STMT:
		if ((state = parseStmt(ep, state, flags)) != STATE_STMT_DONE &&
			state != STATE_EOF && state != STATE_STMT_BLOCK_DONE &&
			state != STATE_RET) {
			state = STATE_ERR;
		}
		break;

	case STATE_DEC:
		if ((state = parseStmt(ep, state, flags)) != STATE_DEC_DONE &&
			state != STATE_EOF) {
			state = STATE_ERR;
		}
		break;

	case STATE_EXPR:
		if ((state = parseStmt(ep, state, flags)) != STATE_EXPR_DONE &&
			state != STATE_EOF) {
			state = STATE_ERR;
		}
		break;

/*
 *	Variable declaration list
 */
	case STATE_DEC_LIST:
		state = parseDeclaration(ep, state, flags);
		break;

/*
 *	Function argument string
 */
	case STATE_ARG_LIST:
		state = parseArgs(ep, state, flags);
		break;

/*
 *	Logical condition list (relational operations separated by &&, ||)
 */
	case STATE_COND:
		state = parseCond(ep, state, flags);
		break;

/*
 *	Expression list
 */
	case STATE_RELEXP:
		state = parseExpr(ep, state, flags);
		break;
	}

	if (state == STATE_ERR && ep->error == NULL) {
		ejError(ep, T("Syntax error"));
	}
	return state;
}
コード例 #2
0
ファイル: parser.c プロジェクト: dario23/tush
/**
 * Atom =   ( "(" [ Expr [{ "," Expr }] ] ")" )
 *        | ( "[" [{ Expr }] "]" )
 *        | FnLit | Path | <Str> | <Symbol>
 */
static ast* parseAtom (parserCtx* ctx) {
    ast* node;

    if (try_match(ctx, "(")) {
        /*Empty brackets => unit literal*/
        if (see(ctx, ")"))
            node = astCreateUnitLit();

        else {
            node = parseExpr(ctx);

            /*Tuple literal*/
            if (see(ctx, ",")) {
                vector(ast*) nodes = vectorInit(3, malloc);
                vectorPush(&nodes, node);

                while (try_match(ctx, ","))
                    vectorPush(&nodes, parseExpr(ctx));

                node = astCreateTupleLit(nodes);
            }
        }

        match(ctx, ")");

    /*List literal*/
    } else if (try_match(ctx, "[")) {
        vector(ast*) nodes = vectorInit(4, malloc);

        if (waiting_for(ctx, "]")) do {
            vectorPush(&nodes, parseExpr(ctx));
        } while (try_match(ctx, ","));

        node = astCreateListLit(nodes);

        match(ctx, "]");

    } else if (see(ctx, "\\")) {
        node = parseFnLit(ctx);

    } else if (see(ctx, "true") || see(ctx, "false")) {
        node = astCreateBoolLit(see(ctx, "true"));
        accept(ctx);

    } else if (see_kind(ctx, tokenIntLit)) {
        node = astCreateIntLit(atoi(ctx->current.buffer));
        accept(ctx);

    } else if (see_kind(ctx, tokenStrLit)) {
        node = astCreateStrLit(ctx->current.buffer);
        accept(ctx);

    } else if (see_kind(ctx, tokenNormal)) {
        sym* symbol;

        if (isPathToken(ctx->current.buffer))
            node = parsePath(ctx);

        else if ((symbol = symLookup(ctx->scope, ctx->current.buffer)))
            node = astCreateSymbol(symbol);

        else
            node = astCreateFileLit(ctx->current.buffer);

        accept(ctx);

    } else {
        expected(ctx, "expression");
        node = astCreateInvalid();
    }

    return node;
}
コード例 #3
0
ファイル: said.cpp プロジェクト: michailBs/scummvm
static bool parseSpec(ParseTreeNode* parentNode)
{
	// Store current state for rolling back if we fail
	int curToken = said_token;
	int curTreePos = said_tree_pos;
	ParseTreeNode* curRightChild = parentNode->right;

	ParseTreeNode* newNode = said_branch_node(said_next_node(), 0, 0);

	bool ret = false;

	bool found;

	ParseTreeNode* newParent = parentNode;

	found = parseExpr(newNode);

	if (found) {
		// Sentence part 1 found
		said_attach_subtree(newParent, 0x141, 0x149, newNode);

		newParent = newParent->right;

		ret = true;
	}

	bool nonempty;

	found = parsePart2(newParent, nonempty);

	if (found) {

		ret = true;

		if (nonempty) // non-empty part found
			newParent = newParent->right;


		found = parsePart3(newParent, nonempty);

		if (found) {

			if (nonempty)
				newParent = newParent->right;
		}
	}

	if (said_tokens[said_token] == TOKEN_GT) {
		said_token++;

		newNode = said_branch_node(said_next_node(), 0,
						said_leaf_node(said_next_node(), TOKEN_GT));

		said_attach_subtree(newParent, 0x14B, TOKEN_GT, newNode);

	}


	if (ret)
		return true;

	// Rollback
	said_token = curToken;
	said_tree_pos = curTreePos;
	parentNode->right = curRightChild;
	return false;
}
コード例 #4
0
// Load a value according to the operation
void Expression::loadValue(byte operation, uint32 varBase, const StackFrame &stackFrame) {
	int16 dimCount;
	uint16 temp;
	int16 temp2;
	int16 offset;
	int16 dim;
	byte *arrDescPtr;
	int32 prevPrevVal;
	int32 prevVal;
	int32 curVal;

	switch (operation) {
	case OP_ARRAY_INT8:
	case OP_ARRAY_INT32:
	case OP_ARRAY_INT16:
	case OP_ARRAY_STR:
		*stackFrame.opers = (operation == OP_ARRAY_STR) ? OP_LOAD_IMM_STR : OP_LOAD_IMM_INT16;
		temp = _vm->_game->_script->readInt16();
		dimCount = _vm->_game->_script->readByte();
		arrDescPtr = _vm->_game->_script->getData() + _vm->_game->_script->pos();
		_vm->_game->_script->skip(dimCount);
		offset = 0;
		for (dim = 0; dim < dimCount; dim++) {
			temp2 = parseValExpr(OP_END_MARKER);
			offset = offset * arrDescPtr[dim] + temp2;
		}
		if (operation == OP_ARRAY_INT8)
			*stackFrame.values = (int8) READ_VARO_UINT8(varBase + temp + offset);
		else if (operation == OP_ARRAY_INT32)
			*stackFrame.values = READ_VARO_UINT32(varBase + temp * 4 + offset * 4);
		else if (operation == OP_ARRAY_INT16)
			*stackFrame.values = (int16) READ_VARO_UINT16(varBase + temp * 2 + offset * 2);
		else if (operation == OP_ARRAY_STR) {
			*stackFrame.values = encodePtr(_vm->_inter->_variables->getAddressOff8(
						varBase + temp * 4 + offset * _vm->_global->_inter_animDataSize * 4),
					kInterVar);
			if (_vm->_game->_script->peekByte() == 13) {
				_vm->_game->_script->skip(1);
				temp2 = parseValExpr(OP_END_MARKER);
				*stackFrame.opers = OP_LOAD_IMM_INT16;
				*stackFrame.values = READ_VARO_UINT8(varBase + temp * 4 +
						offset * 4 * _vm->_global->_inter_animDataSize + temp2);
			}
		}
		break;

	case OP_LOAD_VAR_INT16:
		*stackFrame.opers = OP_LOAD_IMM_INT16;
		*stackFrame.values = (int16) READ_VARO_UINT16(varBase + _vm->_game->_script->readUint16() * 2);
		break;

	case OP_LOAD_VAR_INT8:
		*stackFrame.opers = OP_LOAD_IMM_INT16;
		*stackFrame.values = (int8) READ_VARO_UINT8(varBase + _vm->_game->_script->readUint16());
		break;

	case OP_LOAD_IMM_INT32:
		*stackFrame.opers = OP_LOAD_IMM_INT16;
		*stackFrame.values = _vm->_game->_script->readInt32();
		break;

	case OP_LOAD_IMM_INT16:
		*stackFrame.opers = OP_LOAD_IMM_INT16;
		*stackFrame.values = _vm->_game->_script->readInt16();
		break;

	case OP_LOAD_IMM_INT8:
		*stackFrame.opers = OP_LOAD_IMM_INT16;
		*stackFrame.values = _vm->_game->_script->readInt8();
		break;

	case OP_LOAD_IMM_STR:
		*stackFrame.opers = OP_LOAD_IMM_STR;
		*stackFrame.values = encodePtr((byte *)_vm->_game->_script->readString(), kExecPtr);
		break;

	case OP_LOAD_VAR_INT32:
		*stackFrame.opers = OP_LOAD_IMM_INT16;
		*stackFrame.values = READ_VARO_UINT32(varBase + _vm->_game->_script->readUint16() * 4);
		break;

	case OP_LOAD_VAR_INT32_AS_INT16:
		*stackFrame.opers = OP_LOAD_IMM_INT16;
		*stackFrame.values = (int16) READ_VARO_UINT16(varBase + _vm->_game->_script->readUint16() * 4);
		break;

	case OP_LOAD_VAR_STR:
		*stackFrame.opers = OP_LOAD_IMM_STR;
		temp = _vm->_game->_script->readUint16() * 4;
		*stackFrame.values = encodePtr(_vm->_inter->_variables->getAddressOff8(varBase + temp), kInterVar);
		if (_vm->_game->_script->peekByte() == 13) {
			_vm->_game->_script->skip(1);
			temp += parseValExpr(OP_END_MARKER);
			*stackFrame.opers = OP_LOAD_IMM_INT16;
			*stackFrame.values = READ_VARO_UINT8(varBase + temp);
		}
		break;

	case OP_FUNC:
		operation = _vm->_game->_script->readByte();
		parseExpr(OP_END_EXPR, 0);

		switch (operation) {
		case FUNC_SQRT1:
		case FUNC_SQRT2:
		case FUNC_SQRT3:
			curVal = 1;
			prevVal = 1;

			do {
				prevPrevVal = prevVal;
				prevVal = curVal;
				curVal = (curVal + _resultInt / curVal) / 2;
			} while ((curVal != prevVal) && (curVal != prevPrevVal));
			_resultInt = curVal;
			break;

		case FUNC_SQR:
			_resultInt =
				_resultInt * _resultInt;
			break;

		case FUNC_ABS:
			if (_resultInt < 0)
				_resultInt = -_resultInt;
			break;

		case FUNC_RAND:
			_resultInt =
				_vm->_util->getRandom(_resultInt);
			break;
		}

		*stackFrame.opers = OP_LOAD_IMM_INT16;
		*stackFrame.values = _resultInt;
		break;
	}
}
コード例 #5
0
int16 Expression::parseValExpr(byte stopToken) {
	parseExpr(stopToken, 0);

	return _resultInt;
}
コード例 #6
0
ファイル: macrocompiler.cpp プロジェクト: shmuz/Spring
//- AN ----------------------------------------------
//  Компиляция строки BufPtr в байткод CurMacroBuffer
//- AN ----------------------------------------------
int __parseMacroString(DWORD *&CurMacroBuffer, int &CurMacroBufferSize, const wchar_t *BufPtr)
{
	_KEYMACRO(CleverSysLog Clev(L"parseMacroString"));
	//_KEYMACRO(SysLog(L"BufPtr[%p]='%s'", BufPtr,BufPtr));
	_macro_nErr = 0;
	_macro_nLine= 0;
	_macro_nPos = 0;
	pSrcString = emptyString;
	inloop = 0;
	/*pSrcString = */oSrcString = sSrcString = emptyString;

	if (!BufPtr || !*BufPtr)
	{
		keyMacroParseError(err_ZeroLengthMacro);
		return FALSE;
	}

	bool useUDL=true;
	const wchar_t *NewBufPtr;

	UserDefinedList MacroSrcList(ULF_NOTRIM|ULF_NOUNQUOTE, L"\r\n");
	if(!MacroSrcList.Set(BufPtr))
		useUDL=false; // все в одну строку
	//{
	//	_SVS(SysLog(L"MacroSrcList.GetTotal()=%d",MacroSrcList.GetTotal()));
	//	while((NewBufPtr=MacroSrcList.GetNext()) )
	//		_SVS(SysLog(L"[%s]",NewBufPtr));
	//	MacroSrcList.Reset();
	//}

	size_t SizeCurKeyText = (StrLength(BufPtr)*2)*sizeof(wchar_t);
	string strCurrKeyText;
	//- AN ----------------------------------------------
	//  Буфер под парсинг выражений
	//- AN ----------------------------------------------
	DWORD *dwExprBuff = (DWORD*)xf_malloc(SizeCurKeyText*sizeof(DWORD));

	if (!dwExprBuff)
		return FALSE;

	TExec exec;
	wchar_t varName[256];
	DWORD KeyCode, *CurMacro_Buffer = nullptr;

	if(useUDL)
		BufPtr=MacroSrcList.GetNext();

	pSrcString=BufPtr;

	for (;;)
	{
		int Size = 1;
		int SizeVarName = 0;
		const wchar_t *oldBufPtr = BufPtr;

		if (!(BufPtr = __GetNextWord(BufPtr, strCurrKeyText, _macro_nLine)))
		{
			if(!useUDL)
				break;
			NewBufPtr=MacroSrcList.GetNext();
			if(!NewBufPtr)
				break;
			_macro_nLine++;
			pSrcString=BufPtr=NewBufPtr;
			continue;
		}
		_SVS(SysLog(L"_macro_nLine   = [%d]",_macro_nLine));
		_SVS(SysLog(L"BufPtr         = [%s]",BufPtr));
		_SVS(SysLog(L"pSrcString     = [%s]",pSrcString));
		_SVS(SysLog(L"strCurrKeyText = [%s]",strCurrKeyText.CPtr()));

		//- AN ----------------------------------------------
		//  Проверка на строковый литерал
		//  Сделаем $Text опциональным
		//- AN ----------------------------------------------
		if (strCurrKeyText.At(0) == L'\"' && strCurrKeyText.At(1))
		{
			KeyCode = MCODE_OP_PLAINTEXT;
			BufPtr = oldBufPtr;
		}
		else if ((KeyCode = KeyNameMacroToKey(strCurrKeyText)) == (DWORD)-1 && (KeyCode = KeyNameToKey(strCurrKeyText)) == (DWORD)-1)
		{
			int ProcError=0;

			if (strCurrKeyText.At(0) == L'%' &&
			        (
			            (IsAlphaNum(strCurrKeyText.At(1)) || strCurrKeyText.At(1) == L'_') ||
			            (
			                strCurrKeyText.At(1) == L'%' &&
			                (IsAlphaNum(strCurrKeyText.At(2)) || strCurrKeyText.At(2)==L'_')
			            )
			        )
			   )
			{
				BufPtr = oldBufPtr;

				while (*BufPtr && (IsSpace(*BufPtr) || IsEol(*BufPtr)))
				{
					if (IsEol(*BufPtr))
					{
						_macro_nLine++;//TODO!!!
					}
					BufPtr++;
				}

				ClearArray(varName);
				KeyCode = MCODE_OP_SAVE;
				wchar_t* p = varName;
				const wchar_t* s = strCurrKeyText.CPtr()+1;

				if (*s == L'%')
					*p++ = *s++;

				wchar_t ch;
				*p++ = *s++;

				while ((iswalnum(ch = *s++) || (ch == L'_')))
					*p++ = ch;

				*p = 0;
				size_t Length = (StrLength(varName)+1)*sizeof(wchar_t);
				// строка должна быть выровнена на 4
				SizeVarName = static_cast<int>(Length/sizeof(DWORD));

				if (Length == sizeof(wchar_t) || (Length % sizeof(DWORD)) )    // дополнение до sizeof(DWORD) нулями.
					SizeVarName++;

				_SVS(SysLog(L"BufPtr=%s",BufPtr));
				BufPtr += Length/sizeof(wchar_t);
				_SVS(SysLog(L"BufPtr=%s",BufPtr));
				Size += parseExpr(BufPtr, dwExprBuff, L'=', L';');

				if (_macro_nErr)
				{
					ProcError++;
				}
			}
			else
			{
				// проверим вариант, когда вызвали функцию, но результат не присвоили,
				// например, вызвали MsgBox(), но результат неважен
				// тогда SizeVarName=1 и varName=""
				wchar_t *lpwszCurrKeyText = strCurrKeyText.GetBuffer();
				wchar_t *Brack=(wchar_t *)wcspbrk(lpwszCurrKeyText,L"( "), Chr=0;

				if (Brack)
				{
					Chr=*Brack;
					*Brack=0;
				}

				if (funcLook(lpwszCurrKeyText) != MCODE_F_NOFUNC)
				{
					if (Brack) *Brack=Chr;

					BufPtr = oldBufPtr;

					while (*BufPtr && (IsSpace(*BufPtr) || IsEol(*BufPtr)))
					{
						if (IsEol(*BufPtr))
						{
							_macro_nLine++;//TODO!!!
						}
						BufPtr++;
					}

					Size += parseExpr(BufPtr, dwExprBuff, 0, 0);

					/*
					// этого пока ненадо, считаем, что ';' идет сразу за функцией, иначе это отдельный символ ';', который нужно поместить в поток
					while ( *BufPtr && (IsSpace(*BufPtr) || IsEol(*BufPtr)) )
					{
						if (IsEol(*BufPtr))
						{
							_macro_nLine++;//TODO!!!
						}
						BufPtr++;
					}
					*/
					if (*BufPtr == L';')
						BufPtr++; // здесь Size не увеличиваем, т.к. мы прокидываем символ ';'

					//Size--; //???
					if (_macro_nErr)
					{
						ProcError++;
					}
					else
					{
						KeyCode=MCODE_OP_SAVE;
						SizeVarName=1;
						ClearArray(varName);
					}
				}
				else
				{
					if (Brack) *Brack=Chr;

					ProcError++;
				}

				strCurrKeyText.ReleaseBuffer();
			}

			if (ProcError)
			{
				if (!_macro_nErr)
					//keyMacroParseError(err_Unrecognized_keyword, strCurrKeyText, strCurrKeyText,strCurrKeyText);
					keyMacroParseError(err_Unrecognized_keyword, oldBufPtr, pSrcString, strCurrKeyText);

				if (CurMacro_Buffer )
				{
					xf_free(CurMacro_Buffer);
					CurMacroBuffer = nullptr;
				}

				CurMacroBufferSize = 0;
				xf_free(dwExprBuff);
				return FALSE;
			}
		}
		else if (!(strCurrKeyText.At(0) == L'$' && strCurrKeyText.At(1)))
		{
			Size=3;
			KeyCode=MCODE_OP_KEYS;
		}

		switch (KeyCode)
		{
			// $Text
			// -------------------------------------
			//            MCODE_OP_PLAINTEXT
			//            <expr>
			case MCODE_OP_PLAINTEXT:
			{
				Size += parseExpr(BufPtr, dwExprBuff, 0, 0);
				break;
			}
			// $If (expr) ... $End
			// -------------------------------------
			//            <expr>
			//            MCODE_OP_JZ                     p1=*+0
			//            addr1        ------------+
			//            ...                      |
			//            MCODE_OP_JMP             |
			// +--------- addr2                    |
			// |          ...          <-----------+
			// +--------> MCODE_OP_END
			// или
			//            <expr>
			//            MCODE_OP_JZ                     p1=*+0
			//            addr1        ------------+
			//            ...                      |
			//            MCODE_OP_END <-----------+
			case MCODE_OP_IF:
			{
				Size += parseExpr(BufPtr, dwExprBuff, L'(', L')');

				if (!exec.add(emmThen, CurMacroBufferSize+Size))
				{
					if (CurMacro_Buffer )
					{
						xf_free(CurMacro_Buffer);
						CurMacroBuffer = nullptr;
					}

					CurMacroBufferSize = 0;
					xf_free(dwExprBuff);
					return FALSE;
				}

				Size++;
				break;
			}
			case MCODE_OP_ELSE:
			{
				Size++;
				break;
			}
			// $Rep (expr) ... $End
			// -------------------------------------
			//            <expr>
			//            MCODE_OP_SAVEREPCOUNT       1
			// +--------> MCODE_OP_REP                    p1=*
			// |          <counter>                   3
			// |          <counter>                   4
			// |          MCODE_OP_JZ                 5   p2=*+2
			// |          addr1        ------------+
			// |          ...                      |
			// |          MCODE_OP_JMP             |
			// +--------- addr2                    |
			//            MCODE_OP_END <-----------+
			case MCODE_OP_REP:
			{
				inloop++;
				Size += parseExpr(BufPtr, dwExprBuff, L'(', L')');

				if (!exec.add(emmRep, CurMacroBufferSize+Size, CurMacroBufferSize+Size+4))   //??? 3
				{
					if (CurMacro_Buffer )
					{
						xf_free(CurMacro_Buffer);
						CurMacroBuffer = nullptr;
					}

					CurMacroBufferSize = 0;
					xf_free(dwExprBuff);
					return FALSE;
				}

				Size += 5;  // естественно, размер будет больше = 4
				break;
			}
			// $While (expr) ... $End
			// -------------------------------------
			// +--------> <expr>
			// |          MCODE_OP_JZ                    CurMacroBufferSize + Size - 2
			// |          addr1        ------------+     CurMacroBufferSize + Size - 1
			// |          ...                      |     ...
			// |          MCODE_OP_JMP             |     CurMacroBufferSize + Size - 3
			// +--------- addr2                    |     CurMacroBufferSize + Size - 2
			//            MCODE_OP_END <-----------+     CurMacroBufferSize + Size - 1
			//                                           CurMacroBufferSize + Size
			case MCODE_OP_WHILE:
			{
				inloop++;
				Size += parseExpr(BufPtr, dwExprBuff, L'(', L')');

				if (!exec.add(emmWhile, CurMacroBufferSize, CurMacroBufferSize+Size))
				{
					if (CurMacro_Buffer )
					{
						xf_free(CurMacro_Buffer);
						CurMacroBuffer = nullptr;
					}

					CurMacroBufferSize = 0;
					xf_free(dwExprBuff);
					return FALSE;
				}

				Size++;
				break;
			}
			// $continue
			// -------------------------------------
			// ^          MCODE_OP_CONTINUE
			// |          MCODE_OP_JMP
			// +--------- addr
			case MCODE_OP_CONTINUE:
			{
				Size++; // Место под адрес
				break;
			}
			// $break
			// -------------------------------------
			//            MCODE_OP_BREAK
			//            MCODE_OP_JMP
			//            addr -->
			case MCODE_OP_BREAK:
			{
				Size++; // Место под адрес
				break;
			}
			case MCODE_OP_END:
			{
				switch (exec().state)
				{
					case emmRep:
					case emmWhile:
						Size += 2; // Место под дополнительный JMP
						break;
					default:
						break;
				}

				break;
			}
		}

		if (_macro_nErr)
		{
			if (CurMacro_Buffer )
			{
				xf_free(CurMacro_Buffer);
				CurMacroBuffer = nullptr;
			}

			CurMacroBufferSize = 0;
			xf_free(dwExprBuff);
			return FALSE;
		}

		if (!BufPtr)   // ???
			break;

		// код найден, добавим этот код в буфер последовательности.
		CurMacro_Buffer = (DWORD *)xf_realloc(CurMacro_Buffer,sizeof(*CurMacro_Buffer)*(CurMacroBufferSize+Size+SizeVarName));

		if (!CurMacro_Buffer)
		{
			CurMacroBuffer = nullptr;
			CurMacroBufferSize = 0;
			xf_free(dwExprBuff);
			return FALSE;
		}

		switch (KeyCode)
		{
			case MCODE_OP_PLAINTEXT:
			{
				_SVS(SysLog(L"[%d] Size=%u",__LINE__,Size));
				memcpy(CurMacro_Buffer+CurMacroBufferSize, dwExprBuff, Size*sizeof(DWORD));
				CurMacro_Buffer[CurMacroBufferSize+Size-1] = KeyCode;
				break;
			}
			case MCODE_OP_SAVE:
			{
				memcpy(CurMacro_Buffer+CurMacroBufferSize, dwExprBuff, Size*sizeof(DWORD));
				CurMacro_Buffer[CurMacroBufferSize+Size-1] = KeyCode;
				memcpy(CurMacro_Buffer+CurMacroBufferSize+Size, varName, SizeVarName*sizeof(DWORD));
				break;
			}
			case MCODE_OP_IF:
			{
				memcpy(CurMacro_Buffer+CurMacroBufferSize, dwExprBuff, Size*sizeof(DWORD));
				CurMacro_Buffer[CurMacroBufferSize+Size-2] = MCODE_OP_JZ;
				break;
			}
			case MCODE_OP_REP:
			{
				memcpy(CurMacro_Buffer+CurMacroBufferSize, dwExprBuff, Size*sizeof(DWORD));
				CurMacro_Buffer[CurMacroBufferSize+Size-6] = MCODE_OP_SAVEREPCOUNT;
				CurMacro_Buffer[CurMacroBufferSize+Size-5] = KeyCode;
				CurMacro_Buffer[CurMacroBufferSize+Size-4] = 0; // Initilize 0
				CurMacro_Buffer[CurMacroBufferSize+Size-3] = 0;
				CurMacro_Buffer[CurMacroBufferSize+Size-2] = MCODE_OP_JZ;
				break;
			}
			case MCODE_OP_WHILE:
			{
				memcpy(CurMacro_Buffer+CurMacroBufferSize, dwExprBuff, Size*sizeof(DWORD));
				CurMacro_Buffer[CurMacroBufferSize+Size-2] = MCODE_OP_JZ;
				break;
			}
			case MCODE_OP_ELSE:
			{
				if (exec().state == emmThen)
				{
					exec().state = emmElse;
					CurMacro_Buffer[exec().pos1] = CurMacroBufferSize+2;
					exec().pos1 = CurMacroBufferSize;
					CurMacro_Buffer[CurMacroBufferSize] = 0;
				}
				else // тут $else и не предвиделось :-/
				{
					keyMacroParseError(err_Not_expected_ELSE, BufPtr, pSrcString); // strCurrKeyText

					if (CurMacro_Buffer )
					{
						xf_free(CurMacro_Buffer);
						CurMacroBuffer = nullptr;
					}

					CurMacroBufferSize = 0;
					xf_free(dwExprBuff);
					return FALSE;
				}

				break;
			}
			case MCODE_OP_BREAK:
			case MCODE_OP_CONTINUE:
			{
				TExecItem *ei=nullptr;
				if (!inloop || (KeyCode==MCODE_OP_CONTINUE && exec.findnearloop(&ei) == -1))
				{
					keyMacroParseError(KeyCode==MCODE_OP_CONTINUE?err_Continue_Outside_The_Loop:err_Break_Outside_The_Loop, oldBufPtr, pSrcString);//BufPtr, pSrcString); // strCurrKeyText

					if (CurMacro_Buffer )
					{
						xf_free(CurMacro_Buffer);
						CurMacroBuffer = nullptr;
					}

					CurMacroBufferSize = 0;
					xf_free(dwExprBuff);
					return FALSE;
				}
				CurMacro_Buffer[CurMacroBufferSize+Size-2] = KeyCode==MCODE_OP_CONTINUE?MCODE_OP_JMP:MCODE_OP_BREAK;
				CurMacro_Buffer[CurMacroBufferSize+Size-1] = KeyCode==MCODE_OP_CONTINUE?ei->pos1:0;
				break;
			}
			case MCODE_OP_END:
			{
				switch (exec().state)
				{
					case emmMain:
						// тут $end и не предвиделось :-/
						keyMacroParseError(err_Not_expected_END, BufPtr, pSrcString); // strCurrKeyText

						if (CurMacro_Buffer )
						{
							xf_free(CurMacro_Buffer);
							CurMacroBuffer = nullptr;
						}

						CurMacroBufferSize = 0;
						xf_free(dwExprBuff);
						return FALSE;
					case emmThen:
						CurMacro_Buffer[exec().pos1-1] = MCODE_OP_JZ;
						CurMacro_Buffer[exec().pos1+0] = CurMacroBufferSize+Size-1;
						CurMacro_Buffer[CurMacroBufferSize+Size-1] = KeyCode;
						break;
					case emmElse:
						CurMacro_Buffer[exec().pos1-0] = MCODE_OP_JMP;
						CurMacro_Buffer[exec().pos1+1] = CurMacroBufferSize+Size-1;
						CurMacro_Buffer[CurMacroBufferSize+Size-1] = KeyCode;
						break;
					case emmRep:
					case emmWhile:
						inloop--;
						CurMacro_Buffer[exec().pos2] = CurMacroBufferSize+Size-1;
						CurMacro_Buffer[CurMacroBufferSize+Size-3] = MCODE_OP_JMP;
						CurMacro_Buffer[CurMacroBufferSize+Size-2] = exec().pos1;
						CurMacro_Buffer[CurMacroBufferSize+Size-1] = KeyCode;
						CorrectBreakCode(CurMacro_Buffer,CurMacro_Buffer+exec().pos1,CurMacro_Buffer+(CurMacroBufferSize+Size-1));
						break;
				}

				if (!exec.del())    // Вообще-то этого быть не должно,  но подстрахуемся
				{
					if (CurMacro_Buffer )
					{
						xf_free(CurMacro_Buffer);
						CurMacroBuffer = nullptr;
					}

					CurMacroBufferSize = 0;
					xf_free(dwExprBuff);
					return FALSE;
				}

				break;
			}
			case MCODE_OP_KEYS:
			{
				CurMacro_Buffer[CurMacroBufferSize+Size-3]=MCODE_OP_KEYS;
				CurMacro_Buffer[CurMacroBufferSize+Size-2]=KeyNameToKey(strCurrKeyText);
				CurMacro_Buffer[CurMacroBufferSize+Size-1]=MCODE_OP_ENDKEYS;
				break;
			}
			default:
				CurMacro_Buffer[CurMacroBufferSize]=KeyCode;
		} // end switch(KeyCode)

		CurMacroBufferSize += Size+SizeVarName;
	} // END for (;;)

	if (CurMacroBufferSize == 1)
	{
		CurMacro_Buffer = (DWORD *)xf_realloc(CurMacro_Buffer,sizeof(*CurMacro_Buffer)*(CurMacroBufferSize+1));

		if (!CurMacro_Buffer)
		{
			CurMacroBuffer = nullptr;
			CurMacroBufferSize = 0;
			xf_free(dwExprBuff);
			return FALSE;
		}

		CurMacro_Buffer[CurMacroBufferSize]=MCODE_OP_NOP;
		CurMacroBufferSize++;
	}

#ifdef _DEBUG
#ifdef SYSLOG_KEYMACRO
	SysLogDump(L"Macro Buffer",0,(LPBYTE)CurMacro_Buffer,CurMacroBufferSize*sizeof(DWORD),nullptr);
	SysLog(L"<ByteCode>{");

	if (CurMacro_Buffer)
	{
		int ii;

		for (ii = 0 ; ii < CurMacroBufferSize ; ii++)
			printKeyValue(CurMacro_Buffer, ii);
	}
	else
		SysLog(L"??? is nullptr");

	SysLog(L"}</ByteCode>");
#endif
#endif

	if (CurMacroBufferSize > 1)
		CurMacroBuffer = CurMacro_Buffer;
	else if (CurMacro_Buffer)
	{
		CurMacroBuffer = reinterpret_cast<DWORD*>((intptr_t)(*CurMacro_Buffer));
		xf_free(CurMacro_Buffer);
	}

	xf_free(dwExprBuff);

	if (exec().state != emmMain)
	{
		keyMacroParseError(err_Unexpected_EOS, strCurrKeyText, strCurrKeyText);
		return FALSE;
	}

	if (_macro_nErr)
	{
		return FALSE;
	}

	return TRUE;
}
コード例 #7
0
ファイル: parser.cpp プロジェクト: maximecb/bjrn
/**
Parse a function expression
fun (x,y,z) <body_expr>
*/
Tuple parseFunExpr(Input* input)
{
    // Optional function name
    Tuple name;

    // Try to parse parse the optional function name
    try
    {
        input->eatWS();
        name = parseIdentStr(input);
    }
    catch (ParseError e)
    {
        name = Tuple("");
    }

    // If there is no parameter list
    input->eatWS();
    if (!input->matchCh('('))
    {
        throw ParseError(
            input,
            "expected parameter list in function expression"
        );
    }

    // Allocate an array for the parameter declarations
    std::vector<Value> params;

    // Until the end of the list
    for (;;)
    {
        // Read whitespace
        input->eatWS();

        // If this is the end of the list
        if (input->matchCh(')'))
            break;

        // Parse an identifier
        params.push_back(parseIdentStr(input));

        // Read whitespace
        input->eatWS();

        // If this is the end of the list
        if (input->matchCh(')'))
            break;

        // If this is not the first element, there must be a separator
        if (!input->matchCh(','))
        {
            throw ParseError(input, "expected comma separator in parameter list");
        }
    }

    // Parse the function body
    auto bodyExpr = parseExpr(input);

    return Tuple{
        Tuple("fun"),
        name,
        Tuple(params),
        bodyExpr
    };
}
コード例 #8
0
ファイル: expression.c プロジェクト: zhuowei/SuperCalc
Expression* Expression_parse(const char** expr) {
	Expression* ret = NULL;
	Variable* var;
	Value* val;
	
	const char* equals = strchr(*expr, '=');
	
	if(equals == NULL) {
		/* No assignment, just a plain expression. */
		return parseExpr(expr);
	}
	
	/* There is an assignment */
	/* First, parse the right side of the assignment */
	equals++;
	val = Value_parse(&equals, 0, 0);
	
	if(val->type == VAL_ERR) {
		/* A parse error occurred */
		var = VarErr(Error_copy(val->err));
		Value_free(val);
		return Expression_new(var);
	}
	
	if(val->type == VAL_END) {
		/* Empty input */
		Value_free(val);
		var = VarErr(earlyEnd());
		return Expression_new(var);
	}
	
	/* Now parse the left side */
	char* name = nextToken(expr);
	if(name == NULL) {
		Value_free(val);
		var = VarErr(syntaxError("No variable to assign to."));
		return Expression_new(var);
	}
	
	trimSpaces(expr);
	
	if(**expr == '(') {
		/* Defining a function */
		(*expr)++;
		
		/* Array of argument names */
		unsigned size = 2;
		char** args = fmalloc(size * sizeof(*args));
		unsigned len = 0;
		
		/* Add each argument name to the array */
		char* arg = nextToken(expr);
		
		if(arg == NULL && **expr != ')') {
			/* Invalid character */
			Value_free(val);
			free(args);
			free(name);
			
			var = VarErr(badChar(**expr));
			return Expression_new(var);
		}
		
		trimSpaces(expr);
		
		if(arg == NULL) {
			/* Empty parameter list means function with no args */
			free(args);
			args = NULL;
			len = 0;
		}
		else {
			/* Loop through each argument in the list */
			while(**expr == ',' || **expr == ')') {
				args[len++] = arg;
				
				if(**expr == ')')
					break;
				
				(*expr)++;
				
				/* Expand argument array if it's too small */
				if(len >= size) {
					size *= 2;
					args = frealloc(args, size * sizeof(*args));
				}
				
				arg = nextToken(expr);
				if(arg == NULL) {
					/* Invalid character */
					Value_free(val);
					free(name);
					/* Free argument names and return */
					unsigned i;
					for(i = 0; i < len; i++) {
						free(args[i]);
					}
					free(args);
					
					var = VarErr(badChar(**expr));
					return Expression_new(var);
				}
				
				trimSpaces(expr);
			}
		}
		
		if(**expr != ')') {
			/* Invalid character inside argument name list */
			Value_free(val);
			free(name);
			
			/* Free argument names and return */
			unsigned i;
			for(i = 0; i < len; i++) {
				free(args[i]);
			}
			free(args);
			
			var = VarErr(badChar(**expr));
			return Expression_new(var);
		}
		
		/* Skip closing parenthesis */
		(*expr)++;
		trimSpaces(expr);
		
		if(**expr != '=') {
			Value_free(val);
			free(name);
			
			unsigned i;
			for(i = 0; i < len; i++) {
				free(args[i]);
			}
			free(args);
			
			var = VarErr(badChar(**expr));
			return Expression_new(var);
		}
		
		/* Construct function and return it */
		Function* func = Function_new(len, args, val);
		var = VarFunc(name, func);
		free(name);
		
		ret = Expression_new(var);
	}
	else {
		/* Defining a variable */
		if(**expr != '=') {
			/* In-place manipulation */
			BINTYPE bin = BinOp_nextType(expr, 0, 0);
			
			/* Still not an equals sign means invalid character */
			if(**expr != '=') {
				Value_free(val);
				free(name);
				
				var = VarErr(badChar(**expr));
				return Expression_new(var);
			}
			
			val = ValExpr(BinOp_new(bin, ValVar(name), val));
		}
		
		var = VarValue(name, val);
		free(name);
		
		ret = Expression_new(var);
	}
	
	return ret;
}