Interpeter (Simplified JavaScript)
Easy JS (Simplified JavaScript)
  1. Alphabet
    • Keywords: bool, const, false, float, else, if, int, print, true, string, while
    • Identificators: [A-Za-z_]+[A-Za-z0-9_]*
    • Integer type: -?([1-9][0-9]*|0)
    • Real type: -?[0-9]*\.[0-9]*
    • String type: [^"\n\r\t]*
    • Meaningful separators: '{', '}', '(', ')', '.', ',', ';', '−', '+', '*', '/', '%', '^', '!', '!=', '==', '&&', '||', '>=', '<=', '>', '<', '='
    • Minor separators: space, tab, line break
    • Comments: same as in JS
  2. Syntax
    • program = { declaration | statement | block }
    • declaration = ( typeSpec id [ "=" expression ] ) | ( "const" typeSpec id "=" expression ) ";"
    • typeSpec = "bool" | "int" | "float" | "string"
    • expression = logic1 { "||" logic1 }
    • logic1 = logic2 { "&&" logic2 }
    • logic2 = logic3 [ ( "==" | "!=" ) logic3 ]
    • logic3 = term [ ( "<" | ">" | "<=" | "=>" ) term ]
    • term = factor { ( "+" | "-" ) factor }
    • factor = power { ( "*" | "" | "%" ) power }
    • power = operand { "^" operand }
    • operand = [ "-" | "!" ] ( id | literal | "(" expression ")" )
    • literal = "true" | "false" | float | int | string
    • statement = selStmt | iterStmt | printStmt | exprStmt
    • selStmt = "if" "(" expression ")" block [ "else" block ]
    • block = "{" program "}"
    • iterStmt = "while" "(" expression ")" block
    • printStmt = "print" expression ";"
    • exprStmt = id "=" expression ";"
  3. Semantics
    1. Constants
      They can be either boolean (“false”, “true") or integers. (“-1”, “203”, ...) and floating point numbers (“-1030.02”, “0.0”, ...), so are the strings (“abc", “V1a", ...).
    2. Expressions
      They are made up of brackets, variables, constants, and algebraic operations.
    3. Algebraic operations
      "+" – addition
      "−" – subtraction
      "*" – multiplication
      "" – division (the result can be decimal)
      "%" – remainder of division
      "^" – exponentiation
    4. Operators
      1. Assignment operator
        The assignment operator is used to assign a value to a variable. It has the form subject = object. The operator can assign the result of evaluating an expression to a variable.
        Example:
        float fS = f1 + f2;
        
      2. Logical operators
        "!" – logical NOT
        "&&" – logical AND
        "||" – logical OR
        "!=" – not equal
        "==" – equal
        "<=" – less or equal
        ">=" – greater or equal
        "<" – less
        ">" – greater
      3. The output operator
        The output operator outputs the value of a variable from a new line.
        Example:
        print num;
        print "output";
        
      4. The loop operator
        Organizes the repetition of the execution of a sequence of program statements.
        Example:
        while (sum != 10)
        {
            sum = sum + 2;
        }
        
    5. Priority of operations
      Priority Operations
      1 (, )
      2 ^
      3 !, –a
      4 *, /, %
      5 a + b, a – b
      6 <, >, <=, =>
      7 ==, !=
      8 &&
      9 ||
      10 print
  4. Usage example
    // Declarations
    bool finish = false;
    float sum = 5.0;
    const float FACTOR = 2.;
    string str = "Abcdef";
    int count;
    count = 0;
    int d = 5;
    
    if (d % 2 == 0)
    {
    }
    else
    {
        sum=0.0;
    }
    
    /*
    Loop
    */
    while (finish == false)
    {
        sum = 5.0+(sum+10.0) * -FACTOR^1.5;
        count = count + 1;
        finish = !(count > 100 || sum <= 1.0 && sum >= 0.0);	
    }
    
    {
    print "Result";
    print sum;
    }
    
The Interpeter
  1. Lexer
    Reads the file character by character and searches for suitable tokens. If an unexpected character or an unclosed multi-line comment is found, it returns an error.
  2. Parser
    Finds syntactic constructions and generates a token tree for the Shell (interpretation tree). When an unexpected token is detected, it returns an error.
  3. Shell
    It moves through the interpretation tree and performs the corresponding operations.
    Features of the work:
    1. For each scope, there is a list of variables that is destroyed when closed; each calculated expression automatically uses a new temporary scope.
    2. There is no recursion; nested expressions are transformed into a single one, and then this expression is evaluated.
    3. An expression consisting of more than one token is converted to the Reverse Polish Notation format, and then calculated.
    It issues errors in the following cases:
    1. Incompatibility of variable types, including an attempt to re-assign a value to a constant variable.
    2. Unsupported operation for the data type.
    3. Re-declaring a variable.
Demonstration