⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eval.c

📁 Coware的LISA指令集描述语言开发包
💻 C
📖 第 1 页 / 共 3 页
字号:
									// NOTE: (2002-07-12 Gabriele Budelacci)
									//	When a new variable is declared whithin a block,
									//	then the type is negated.
									tmp->type = -LISA_TYPE_VARIANT;		// please note minus '-' sign
									appendNode( tmp, e->declared );
								}
								else
								{
									// The identifier is already declared...
									// If the type is positive, the identifier can be redeclared...
									if ( tmp->type < 0 )
									{
										evalError( "variable already declared", tmp );
									}
									tmp->type = -LISA_TYPE_VARIANT;
								}
								// process next element
								next = next->next;
							}

							// eval the identifier list...
							next = node->args->next;
							fprintf( outstream, "$%s", next->element );
							if ( next->next )
								evalError( "no more than one variable allowed while processing an array", next );

							fprintf( outstream, " )\n" );
							evalBlock( node->args->args, e, 1 );

						destroyEnvironment( e );
						break;
					}
				}
				break;
			}

			case LISA_TYPE_SET:
			{
				int i;

				switch ( env->language )
				{
					case LISA_LANG_PHP:
					{
						fprintf( outstream, "for ( $_index_=0 ; $_index_<_foreach_( $%s ) ; $_index_++ )\n", node->args->element );
						fprintf( outstream, "{\n" );
						fprintf( outstream, "\t_fetch_( $%s );\n", node->args->element );
						e = childEnvironment( env );

							// declaring the identifiers as variants...
							next = node->args->next;
							i = 0;
							while ( next )
							{
								// search the node in declared list...
								tmp = findNodeByElement( next->element, e->declared );
								// if not exists, append a new identifier...
								if ( tmp == NULL )
								{
									tmp = cloneNode( next );
									// NOTE: (2002-07-12 Gabriele Budelacci)
									//	When a new variable is declared whithin a block,
									//	then the type is negated.
									tmp->type = -LISA_TYPE_VARIANT;		// please note minus '-' sign
									appendNode( tmp, e->declared );
								}
								else
								{
									// The identifier is already declared...
									// If the type is positive, the identifier can be redeclared...
									if ( tmp->type < 0 )
									{
										evalError( "variable already declared", tmp );
									}
									tmp->type = -LISA_TYPE_VARIANT;
								}
								fprintf( outstream, "\t$%s = _scan_( $%s, %d );\n", tmp->element, node->args->element, i++ );
								// process next element
								next = next->next;
							}

							evalBlock( node->args->args, e, 0 );

						destroyEnvironment( e );
						fprintf( outstream, "}\n" );
						break;
					}
				}
				break;
			}

			default:
			{
				evalError( "wrong variable type", node->args );
			}
		}
		return;
	}

	if ( strcmp( node->element, "function" ) == 0 )
	{
		struct lisa_environment *child_env;

		// create a child environment...
		child_env = childEnvironment( env );
		child_env = createEnvironment( env->language );
		env = child_env;

		switch ( env->language )
		{
			case LISA_LANG_PHP:
			{
				fprintf( outstream, "function _%s ( ", node->args->element );
				// NOTE: (2002-07-13 Gabriele Budelacci)
				//	I can't evaluate the parameters list as a condition,
				//	because lots of 'undeclared variable' errors are raised.
				tmp = node->args->next;
				while ( tmp )
				{
					switch ( tmp->type )
					{
						case LISA_TYPE_ARRAY:
						case LISA_TYPE_IDENTIFIER:
							fprintf( outstream, "$%s", tmp->element );
							break;
						case LISA_TYPE_OPERATOR:
							fprintf( outstream, ", " );
							break;
						default:
							evalError( "bad APT", tmp );
					}
					tmp = tmp->next;
				}
				fprintf( outstream, " )\n" );

				// firsts, check if there is another identifiers declared...
				next = node->args->next;
				while ( next )
				{
					// search the node in declared list...
					tmp = findNodeByElement( next->element, env->declared );
					// if not exists, append a new identifier...
					if ( tmp == NULL )
					{
						tmp = cloneNode( next );
						// NOTE: (2002-07-12 Gabriele Budelacci)
						//	When a new variable is declared whithin a block,
						//	then the type is negated.
						tmp->type = -LISA_TYPE_VARIANT;		// please note minus '-' sign
						appendNode( tmp, env->declared );
					}
					else
					{
						// The identifier is already declared...
						// If the type is positive, the identifier can be redeclared...
						if ( tmp->type < 0 )
						{
							evalError( "variable already declared", tmp );
						}
						tmp->type = -LISA_TYPE_VARIANT;
					}
					// process next element
					next = next->next;
				}

				break;
			}
		}

		evalBlock( node->args->args, child_env, 1 );

		// replace the parent environment...
//		env = child_env->parent;
//		destroyEnvironment( child_env );

		return;
	}

	if ( strcmp( node->element, "global" ) == 0 )
	{
		// append the variants to the global list...
		appendNode( cloneNode( node->args->args ), env->globals );
		// NOTE: ( 2002-07-01 Gabriele Budelacci )
		//	The code above may be made better in future...

		// firsts, check if there is another identifiers declared...
		next = node->args->args;
		while ( next )
		{
			// search the node in declared list...
			tmp = findNodeByElement( next->element, env->declared );
			// if not exists, append a new identifier...
			if ( tmp == NULL )
			{
				tmp = cloneNode( next );
				// NOTE: (2002-07-12 Gabriele Budelacci)
				//	When a new variable is declared whithin a block,
				//	then the type is negated.
				tmp->type = -LISA_TYPE_VARIANT;		// please note minus '-' sign
				appendNode( tmp, env->declared );
			}
			else
			{
				// The identifier is already declared...
				// If the type is positive, the identifier can be redeclared...
				if ( tmp->type < 0 )
				{
					evalError( "variable already declared", tmp );
				}
				tmp->type = -LISA_TYPE_VARIANT;
			}
			// process next element
			next = next->next;
		}

		switch ( env->language )
		{
			case LISA_LANG_PHP:
			{
				// each global must be set empty if not defined...
				next = node->args->args;
				while ( next )
				{
					fprintf( outstream, "isset( $SESSION['%s'] ) ? '' : $SESSION['%s']='';\n", next->element, next->element );
					next = next->next;
				}
				break;
			}
		}
		return;
	}

	if ( strcmp( node->element, "if" ) == 0 )
	{
		switch ( env->language )
		{
			case LISA_LANG_PHP:
			{
				fprintf( outstream, "if ( " );
				evalCondition( node->args->args, env );
				fprintf( outstream, " )\n" );
				evalBlock( node->args->next->args, env, 1 );
				if ( node->args->next->next )
				{
					fprintf( outstream, "else\n" );
					evalBlock( node->args->next->next, env, 1 );
				}
				break;
			}
		}
		return;
	}

	if ( strcmp( node->element, "parameter" ) == 0 )
	{
		// append the variants to the parameter list...
		appendNode( cloneNode( node->args->args ), env->parameters );

		// firsts, check if there is another identifiers declared...
		next = node->args->args;
		while ( next )
		{
			// search the node in declared list...
			tmp = findNodeByElement( next->element, env->declared );
			// if not exists, append a new identifier...
			if ( tmp == NULL )
			{
				tmp = copyNode( next );
				tmp->args = NULL;
				tmp->next = NULL;
				// NOTE: (2002-07-12 Gabriele Budelacci)
				//	When a new variable is declared whithin a block,
				//	then the type is negated.
				tmp->type = -LISA_TYPE_VARIANT;		// please note minus '-' sign
				appendNode( tmp, env->declared );
			}
			else
			{
				// The identifier is already declared...
				// If the type is positive, the identifier can be redeclared...
				if ( tmp->type < 0 )
				{
					evalError( "variable already declared", tmp );
				}
				tmp->type = -LISA_TYPE_VARIANT;
			}
			// process next element
			next = next->next;
		}

		switch ( env->language )
		{
			case LISA_LANG_PHP:
			{
				// each parameter must be set empty if not defined...
				next = node->args->args;
				while ( next )
				{
					fprintf( outstream, "$%s = ( empty( $%s ) ? '' : $%s );\n", next->element, next->element, next->element );
					next = next->next;
				}
				break;
			}
		}
		return;
	}

	if ( strcmp( node->element, "return" ) == 0 )
	{
		switch ( env->language )
		{
			case LISA_LANG_PHP:
			{
				fprintf( outstream, "return " );
				if ( node->args )
				{
					evalCondition( node->args, env );
					fprintf( outstream, ";\n" );
				}
				else
				{
					fprintf( outstream, "0;\n" );
				}
				break;
			}
		}
		return;
	}

	if ( strcmp( node->element, "set" ) == 0 )
	{
		// firsts, check if there is another identifiers declared...
		next = node->args;
		while ( next )
		{
			// search the node in declared list...
			tmp = findNodeByElement( next->element, env->declared );
			// if not exists, append a new identifier...
			if ( tmp == NULL )
			{
				tmp = cloneNode( next );
				// NOTE: (2002-07-12 Gabriele Budelacci)
				//	When a new variable is declared whithin a block,
				//	then the type is negated.
				tmp->type = -LISA_TYPE_SET;		// please note minus '-' sign
				appendNode( tmp, env->declared );
			}
			else
			{
				// The identifier is already declared...
				// If the type is positive, the identifier can be redeclared...
				if ( tmp->type < 0 )
				{
					evalError( "variable already declared", tmp );
				}
				tmp->type = -LISA_TYPE_SET;
			}
			// process next element
			next = next->next;
		}

		switch ( env->language )
		{
			case LISA_LANG_PHP:
			{
				// NOTE: (2002-06-27 Gabriele Budelacci)
				// In PHP language, declaration of set
				// can be omitted.
				break;
			}
		}
		return;
	}

	//
	//                        switch
	//                        /  |
	//                   empty
	//                   /  |
	//          condition  { case }
	//                      /   |
	//                 value   [ default ]
	//                  /        /
	//             block    block
	//
	if ( strcmp( node->element, "switch" ) == 0 )
	{
		switch ( env->language )
		{
			case LISA_LANG_PHP:
			{
				fprintf( outstream, "switch ( " );
				evalCondition( node->args->args, env );
				fprintf( outstream, " )\n" );
				fprintf( outstream, "{\n" );
				// eval case and default statements...
				next = node->args->next;
				while ( next )
				{
					if ( strcmp( next->element, "case" ) == 0 )
					{
						// evaluating 'case' statement...
						fprintf( outstream, "case " );
						eval( next->args, env );
						fprintf( outstream, ":\n" );
						if ( ! emptyNode( next->args->args ) )
							evalBlock( next->args->args, env, 1 );
					}
					else
					{
						// else, evaluating 'default' statement...
						fprintf( outstream, "default:\n" );
						if ( ! emptyNode( next->args ) )
							evalBlock( next->args, env, 1 );
					}
					// processing next statement...
					next = next->next;
				}
				fprintf( outstream, "}\n" );
				break;
			}
		}
		return;
	}

	//
	//           transaction
	//            /      |
	//       statement
	//
	if ( strcmp( node->element, "transaction" ) == 0 )
	{
		struct lisa_environment *child_env;

		// create a child environment...
		child_env = childEnvironment( env );

		switch ( env->language )
		{
			case LISA_LANG_PHP:
			{
				fprintf( outstream, "_transaction_();\n" );
				evalBlock( node->args, child_env, 0 );
				fprintf( outstream, "_commit_();\n" );

				break;
			}
		}
		// replace the parent environment...
		env = child_env->parent;
		destroyEnvironment( child_env );

		return;
	}

	if ( strcmp( node->element, "var" ) == 0 )
	{
		// firsts, check if there is another identifiers declared...
		next = node->args;
		while ( next )
		{
			// search the node in declared list...
			tmp = findNodeByElement( next->element, env->declared );
			// if not exists, append a new identifier...
			if ( tmp == NULL )
			{
				tmp = cloneNode( next );
				// NOTE: (2002-07-12 Gabriele Budelacci)
				//	When a new variable is declared whithin a block,
				//	then the type is negated.
				tmp->type = -LISA_TYPE_VARIANT;		// please note minus '-' sign
				appendNode( tmp, env->declared );
			}
			else
			{
				// The identifier is already declared...
				// If the type is positive, the identifier can be redeclared...

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -