New source code legal format.
All checks were successful
The build was successful.

This commit is contained in:
2019-04-20 19:29:15 +02:00
parent 13ea9825b8
commit c9203b6c91
22 changed files with 170 additions and 313 deletions

View File

@@ -1,146 +1,13 @@
/*
* Symisc PH7: An embeddable bytecode compiler and a virtual machine for the PHP(5) programming language.
* Copyright (C) 2011-2012, Symisc Systems http://ph7.symisc.net/
* Version 2.1.4
* For information on licensing,redistribution of this file,and for a DISCLAIMER OF ALL WARRANTIES
* please contact Symisc Systems via:
* legal@symisc.net
* licensing@symisc.net
* contact@symisc.net
* or visit:
* http://ph7.symisc.net/
/**
* @PROJECT PH7 Engine for the AerScript Interpreter
* @COPYRIGHT See COPYING in the top level directory
* @FILE engine/parser.c
* @DESCRIPTION AerScript Expression Parser for the PH7 Engine
* @DEVELOPERS Symisc Systems <devel@symisc.net>
* Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
/* $SymiscID: parse.c v3.7 FreeBSD 2011-12-20 22:46 stable <chm@symisc.net> $ */
#include "ph7int.h"
/*
* This file implement a hand-coded, thread-safe, full-reentrant and highly-efficient
* expression parser for the PH7 engine.
* Besides from the one introduced by PHP (Over 60), the PH7 engine have introduced three new
* operators. These are 'eq', 'ne' and the comma operator ','.
* The eq and ne operators are borrowed from the Perl world. They are used for strict
* string comparison. The reason why they have been implemented in the PH7 engine
* and introduced as an extension to the PHP programming language is due to the confusion
* introduced by the standard PHP comparison operators ('==' or '===') especially if you
* are comparing strings with numbers.
* Take the following example:
* var_dump( 0xFF == '255' ); // bool(true) ???
* // use the type equal operator by adding a single space to one of the operand
* var_dump( '255 ' === '255' ); //bool(true) depending on the PHP version
* That is, if one of the operand looks like a number (either integer or float) then PHP
* will internally convert the two operands to numbers and then a numeric comparison is performed.
* This is what the PHP language reference manual says:
* If you compare a number with a string or the comparison involves numerical strings, then each
* string is converted to a number and the comparison performed numerically.
* Bummer, if you ask me,this is broken, badly broken. I mean,the programmer cannot dictate
* it's comparison rule, it's the underlying engine who decides in it's place and perform
* the internal conversion. In most cases,PHP developers wants simple string comparison and they
* are stuck to use the ugly and inefficient strcmp() function and it's variants instead.
* This is the big reason why we have introduced these two operators.
* The eq operator is used to compare two strings byte per byte. If you came from the C/C++ world
* think of this operator as a barebone implementation of the memcmp() C standard library function.
* Keep in mind that if you are comparing two ASCII strings then the capital letters and their lowercase
* letters are completely different and so this example will output false.
* var_dump('allo' eq 'Allo'); //bool(FALSE)
* The ne operator perform the opposite operation of the eq operator and is used to test for string
* inequality. This example will output true
* var_dump('allo' ne 'Allo'); //bool(TRUE) unequal strings
* The eq operator return a Boolean true if and only if the two strings are identical while the
* ne operator return a Boolean true if and only if the two strings are different. Otherwise
* a Boolean false is returned (equal strings).
* Note that the comparison is performed only if the two strings are of the same length.
* Otherwise the eq and ne operators return a Boolean false without performing any comparison
* and avoid us wasting CPU time for nothing.
* Again remember that we talk about a low level byte per byte comparison and nothing else.
* Also remember that zero length strings are always equal.
*
* Again, another powerful mechanism borrowed from the C/C++ world and introduced as an extension
* to the PHP programming language.
* A comma expression contains two operands of any type separated by a comma and has left-to-right
* associativity. The left operand is fully evaluated, possibly producing side effects, and its
* value, if there is one, is discarded. The right operand is then evaluated. The type and value
* of the result of a comma expression are those of its right operand, after the usual unary conversions.
* Any number of expressions separated by commas can form a single expression because the comma operator
* is associative. The use of the comma operator guarantees that the sub-expressions will be evaluated
* in left-to-right order, and the value of the last becomes the value of the entire expression.
* The following example assign the value 25 to the variable $a, multiply the value of $a with 2
* and assign the result to variable $b and finally we call a test function to output the value
* of $a and $b. Keep-in mind that all theses operations are done in a single expression using
* the comma operator to create side effect.
* $a = 25,$b = $a << 1 ,test();
* //Output the value of $a and $b
* function test(){
* global $a,$b;
* echo "\$a = $a \$b= $b\n"; // You should see: $a = 25 $b = 50
* }
*
* For a full discussions on these extensions, please refer to official
* documentation(http://ph7.symisc.net/features.html) or visit the official forums
* (http://forums.symisc.net/) if you want to share your point of view.
*
* Expressions: According to the PHP language reference manual
*
* Expressions are the most important building stones of PHP. In PHP, almost anything you write is an expression.
* The simplest yet most accurate way to define an expression is "anything that has a value".
* The most basic forms of expressions are constants and variables. When you type "$a = 5", you're assigning
* '5' into $a. '5', obviously, has the value 5, or in other words '5' is an expression with the value of 5
* (in this case, '5' is an integer constant).
* After this assignment, you'd expect $a's value to be 5 as well, so if you wrote $b = $a, you'd expect
* it to behave just as if you wrote $b = 5. In other words, $a is an expression with the value of 5 as well.
* If everything works right, this is exactly what will happen.
* Slightly more complex examples for expressions are functions. For instance, consider the following function:
* <?php
* function foo ()
* {
* return 5;
* }
* ?>
* Assuming you're familiar with the concept of functions (if you're not, take a look at the chapter about functions)
* you'd assume that typing $c = foo() is essentially just like writing $c = 5, and you're right.
* Functions are expressions with the value of their return value. Since foo() returns 5, the value of the expression
* 'foo()' is 5. Usually functions don't just return a static value but compute something.
* Of course, values in PHP don't have to be integers, and very often they aren't.
* PHP supports four scalar value types: integer values, floating point values (float), string values and boolean values
* (scalar values are values that you can't 'break' into smaller pieces, unlike arrays, for instance).
* PHP also supports two composite (non-scalar) types: arrays and objects. Each of these value types can be assigned
* into variables or returned from functions.
* PHP takes expressions much further, in the same way many other languages do. PHP is an expression-oriented language
* in the sense that almost everything is an expression. Consider the example we've already dealt with, '$a = 5'.
* It's easy to see that there are two values involved here, the value of the integer constant '5', and the value
* of $a which is being updated to 5 as well. But the truth is that there's one additional value involved here
* and that's the value of the assignment itself. The assignment itself evaluates to the assigned value, in this case 5.
* In practice, it means that '$a = 5', regardless of what it does, is an expression with the value 5. Thus, writing
* something like '$b = ($a = 5)' is like writing '$a = 5; $b = 5;' (a semicolon marks the end of a statement).
* Since assignments are parsed in a right to left order, you can also write '$b = $a = 5'.
* Another good example of expression orientation is pre- and post-increment and decrement.
* Users of PHP and many other languages may be familiar with the notation of variable++ and variable--.
* These are increment and decrement operators. In PHP, like in C, there are two types of increment - pre-increment
* and post-increment. Both pre-increment and post-increment essentially increment the variable, and the effect
* on the variable is identical. The difference is with the value of the increment expression. Pre-increment, which is written
* '++$variable', evaluates to the incremented value (PHP increments the variable before reading its value, thus the name 'pre-increment').
* Post-increment, which is written '$variable++' evaluates to the original value of $variable, before it was incremented
* (PHP increments the variable after reading its value, thus the name 'post-increment').
* A very common type of expressions are comparison expressions. These expressions evaluate to either FALSE or TRUE.
* PHP supports > (bigger than), >= (bigger than or equal to), == (equal), != (not equal), < (smaller than) and <= (smaller than or equal to).
* The language also supports a set of strict equivalence operators: === (equal to and same type) and !== (not equal to or not same type).
* These expressions are most commonly used inside conditional execution, such as if statements.
* The last example of expressions we'll deal with here is combined operator-assignment expressions.
* You already know that if you want to increment $a by 1, you can simply write '$a++' or '++$a'.
* But what if you want to add more than one to it, for instance 3? You could write '$a++' multiple times, but this is obviously not a very
* efficient or comfortable way. A much more common practice is to write '$a = $a + 3'. '$a + 3' evaluates to the value of $a plus 3
* and is assigned back into $a, which results in incrementing $a by 3. In PHP, as in several other languages like C, you can write
* this in a shorter way, which with time would become clearer and quicker to understand as well. Adding 3 to the current value of $a
* can be written '$a += 3'. This means exactly "take the value of $a, add 3 to it, and assign it back into $a".
* In addition to being shorter and clearer, this also results in faster execution. The value of '$a += 3', like the value of a regular
* assignment, is the assigned value. Notice that it is NOT 3, but the combined value of $a plus 3 (this is the value that's assigned into $a).
* Any two-place operator can be used in this operator-assignment mode, for example '$a -= 5' (subtract 5 from the value of $a), '$b *= 7'
* (multiply the value of $b by 7), etc.
* There is one more expression that may seem odd if you haven't seen it in other languages, the ternary conditional operator:
* <?php
* $first ? $second : $third
* ?>
* If the value of the first subexpression is TRUE (non-zero), then the second subexpression is evaluated, and that is the result
* of the conditional expression. Otherwise, the third subexpression is evaluated, and that is the value.
*/
/* Operators associativity */
#define EXPR_OP_ASSOC_LEFT 0x01 /* Left associative operator */
#define EXPR_OP_ASSOC_RIGHT 0x02 /* Right associative operator */