Skip to content
/ Acraga Public

An interpreter designed for Acraga language, which is a super simple, strong-type, c-like programming language.

Notifications You must be signed in to change notification settings

LLipter/Acraga

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Welcome to Acraga!

An interpreter designed for Acraga language, which is a super simple, strong-type, c-like programming language.

Be open to any suggestions that can make Acraga better

Star⭐️ Acraga, fork it and pull request is well received

Acraga 语言概述

Acraga是一种简单的强类型编程语言,支持整数、实数、布尔值、字符串类型的变量。每行Acraga代码都需要以;作为结尾标识。Acraga对此外的格式没有任何要求,所有冗余的空白字符都会被解释器忽略。

Lexical Rules

  • Integer:

    digit ::= 0|1|2|3|4|5|6|7|8|9

    hex ::= digit|A|B|C|D|E|F

    integer ::= decimal | hexadecimal

    decimal ::= (+|-)? digit+

    hexadecimal ::= (0x|0X)hex+

  • Real:

    real ::= decimal.digit+(T)?

    T ::= eF | EF

    F ::= integer

  • Boolean:

    boolean ::= true|false

  • String:

    alphabet ::= ASCII码能表示的所有字符

    literal ::= "alphabet*"

  • Identifier:

    alphabet_english ::= [a-zA-Z]

    alphabet_id ::= alphabet_english | _ | digits

    alphabet_id_first ::= alphabet_english | _

    identifier ::= alphabet_id_first alphabet_id*

  • Keywords/Reserved words:

    • if
    • else
    • while
    • for
    • void
    • int
    • double
    • bool
    • string
    • void
    • return
  • Comment:

    //this is a comment. /*this is also a comment */

  • Operator:

    operator ::= '+' | '-' | '*' | '/' | '=' | '%' | '==' | '!=' | '>' | '<' | '>=' | '<='

  • Delimiter:

    delimiter ::= '(' | ')' | '[' | ']' | '{' | '}' | ';' | ','

Grammar Rules

  • Statements

    statement ::= declare_statement | assign_statement | output_statement | if_statement | while statement | for statement

    statements ::= statement+

  • Declaration statement

    type ::= integer | real | bool | string

    declare_statement ::= type identifier;

  • Assignment statement

    immediate_value ::= integer | real | boolean | literal

    value ::= immediate_value | identifier

    assign_statement ::= identifier = (value | expression);

  • Output

    output_statement ::= print(value)

  • Expression

    expression ::= T

    T ::= T==F | T!=F | F

    F ::= F>G | F<G | F>=G | F<=G | G

    G ::= G+H | G-H | H

    H ::= H*I | H/I | H%I | J

    ......

    J ::= value | (T)

    value ::= integer | real | boolean | string

  • if statement

    if_statement ::= if(expression){statements}(else{statements})?

  • while statememt

    while_statement ::= while(expression){statements}

  • for statement

    for_statement ::= for(assign_statement; boolean expression; control variable){statements}

How to use Acraga

Acraga variables

Acraga supports: local variables and global variables

Note that: we recommend name the identifiers in Camel-Case, and the names of them should be concise. Of course they are case sensitive.

Acraga array

Acraga supports more than one type of arrays, concluding int, double and string.

int arr[2] = {1,2};
println(arr[0]);//output: 1

Acraga data Type

int:

  • maximum:
  • minimum: -∞
  • default: 0
  • support hexadecimal and character integer 'A'

double:

  • maximum:
  • minimum: -∞
  • default: 0.0
  • support scientific notation

boolean:

  • true or false
  • default: false

string:

  • can store string of any length
  • enclosed by '' or ""
  • default: ''

Examples will be displayed afterwards

Acraga escape character

Escape characters are properly recognized and organized. At this point, acraga only supports the escape characters in the following table.

Escape Character Logical Meaning
\n new line
\t horizontal tab
\' single quotation marks
\" double quotation marks
\\ backslash

Type cast

  • Implicit casting

    Acraga supports assigning an integer to an identifier of type double, for example: double d=1;

    Other expressions like int i="aaa" will be recognized as a syntax error.

  • Explicit casting

    Acraga supports using () operator to explicitly cast a type to another:

    Expression Meaning
    int i = (int) doubleValue i will be the integer part of the double value
    int i = (int) boolValue i=1 if boolValue is true; i=0 if boolValue is false
    int i = (int) stringValue if the content of stringValue is integer like "123", i will be the value
    double d = (double) intValue d will be the value of intValue
    double d = (double) boolValue d=1 if boolValue is true; d=0 if boolValue is false
    double d = (double) stringValue if the content of stringValue is integer or double, d will be the value
    bool b = (bool) intValue b=true if intValue!=0; b=false if intValue=0
    bool b = (bool) doubleValue b=true if doubleValue!=0; b=false if doubleValue=0
    bool b= (bool) stringValue b=true if the length of stingValue!=0; else b= false
    string s = (string) intValue the content of s will be the intValue
    string s = (string) doubleValue the content of s will be the doubleValue
    string s = (string) boolValue s="true" if boolValue is true; s="false" if boolValue is false

Cast a type to the same type will get the same result.

Arithmetic statement

Acraga supports operation of int, double, bool, string and hexadecimal number, including add +, subtract-, multiple*, divide/, module% etc. For more operators see the priority list below.

P.S.For string, only '+' operation is allowed

Priority of Operations(smaller number stands for higher priority):

  • (, ) and [,] has the highest priority

  • Operator Explanation type Priority
    - negative sign unary 2
    + positive sign unary 2
    ! logical NOT unary 2
    ~ bitwise NOT unary 2
    ++ self Increment(prefix) unary 2
    -- self Decrement(prefix) unary 2
    * multiplication binary 3
    / division binary 3
    % reminder binary 3
    + addition binary 4
    - subtraction binary 4
    << left shift binary 5
    >> right shift binary 5
    < less than binary 6
    <= less than or equal binary 6
    > greater than binary 6
    >= greater than or equal binary 6
    == equal binary 7
    != not equal binary 7
    & bitwise AND binary 8
    ^ bitwise XOR binary 9
    | bitwise OR binary 10
    && logical AND binary 11
    || logical OR binary 12
    = assign binary 14
    += compound assignment by sum binary 14
    -= compound assignment by difference binary 14
    *= compound assignment by product binary 14
    /= compound assignment by quotient binary 14
    %= compound assignment by remainder binary 14
    &= compound assignment by bitwise AND binary 14
    ^= compound assignment by bitwise XOR binary 14
    |= compound assignment by bitwise OR binary 14
    <<= compound assignment by left shift binary 14
    >>= compound assignment by right shift binary 14

So that we can do something like these:

  • (1 + 2) * (3 * (4 + 5) - 6) = 63
  • 1 + 2 * 3 * 4 + 5 - 6 =24
  • 1 + 3 % 2 = 2
  • 1.3323 + 3.14 - 5.1 = -0.6277
  • 0x0001 + 0x0A02 = 2563

In Java:

String str1 = "abc";
System.out.print(str1 + "d");// output:abcd
String str2 = "1";
String str3 = "2";
System.out.print(str2 + str3);// output:12
  • a + b = ab
  • Moreover, scientific notation is valid: 1.23e2 = $$1.23\times10^2$$

Function

Main function

int main(){
  //do something
  return 0;
}
void main(){
  //do something
}

Both are supported in Acraga.

Note that if you use 'int main', whatever the result is, append 'return 0' at the end of the function.

User-define functions

int foo(){
  //do something
}

double foo(int a){
  //do something
}

These are two different methods via override.

int foo(){
  //do something
}

double foo(){
  //do something
}

Warning: these two functions have the same function signature, which will throw exception.

Predefined functions

void testPrint(){
  print(Any type except void is supported);
  println(Whatever you like, even with no parameter);
}
void testRead(){
  string str1 = read();// read until meets a whitespace
  string str2 = readLine();// read until you press enter
  int a = readInt();// read the first integer number which can be identified as a BigInteger
  double b = readDecimal();// read the first real number which can be identified as a BigDecimal
  bool c = readBool();// read the first boolean variable which can be identified as a Boolean
  // read input from keyboard
}
void testMath(){
  int a = 1;
  int b = -3;
  int c = max(a, abs(b));
  int d = min(a++, b);
  println(c);// output: 3
  println(d);// output: -3
}
void main(){
  print("Hello World!")// output: Hello World!
}

TODO

  • 整数支持十六进制数字 eg. 0xF4A1 (直接显示对应十进制数字62625) ——(✔️)
  • 实数支持科学计数法表示 eg. 3.14e5 ——(✔️)
  • 支持布尔运算 eg. true & false ——(✔️)
  • 支持数组 eg. test[10] ——(✔️)
  • 支持声明与赋值同时完成 ——(✔️)
  • 支持更复杂的输出语句 eg. print(x + y) ——(✔️)
  • 支持格式化输出语句 eg. printf("hello %s", your_name)
  • 支持输入语句 eg. int x = scanf() ——(✔️)
  • 支持for循环语句 ——(✔️)
  • 支持+=、-=、/=、*= ——(✔️)
  • 修改表达式部分的定义,加入括号,并且使之可以提现运算符优先级的区别,可以参考上学期ppt ——(✔️)

  1. test&debug ——(✔️)
  2. 能够在全局区执行一些语句 ——(✔️)
  3. 让for语句可以执行初始化 ——(✔️)
  4. 引入多行注释的语法 ——(✔️)
  5. 引入显示类型转换的概念,在函数参数传递的过程中允许隐式类型转换 ——(✔️)
  6. 重构精简代码
  7. ** 引入类的概念
  8. ** 用C++复刻项目,比较Java与C++版本性能上的区别
  9. 支持在函数参数中传递数组类型的变量
  10. 支持逗号运算符的操作 (int a=1, b=2;)
  11. 支持++,-- 两种运算符,考虑同时支持前置后置形式 ——(✔️)
  12. 实现必要的库函数,例如提供函数输出方式的print()方法 ——(✔️)
  13. ** 实现类的概念后可以定义一些标准库数据结构,比如scanf,比如max,min等数学函数库 ——(✔️)
  14. 测试,争取没有逻辑错误以及运行时崩溃的情况
  15. 用Acraga编写一些简单的小程序, 检查解释器在更真实的场景下的正确性,同时检查设计的语法是否符合交互性 ——(✔️)
  16. 编写全面的文档,讲解解释器的整体构架以及具体细节并介绍如何编写合法的Acraga程序 ——(✔️)
  17. 支持增强的for循环
  18. 检测函数签名,如果相同,报错 ——(✔️)
  19. 支持代码块
  20. ** 支持函数指针以及lambda表达式
  21. 考虑如何定义参数可变的函数,这点和传递数组类型的变量共同是实现类似printf函数的基础
  22. 在detectExpression中做更加细致的判断,判断哪种和哪种token是不可能连在一起的,以此抛出潜在的缺乏分号的错误。
  23. 加入break, continue语法 ——(✔️)
  24. 加入switch case语法
  25. 静态多个报错
  26. 报错位置不准确 ——(✔️)

About

An interpreter designed for Acraga language, which is a super simple, strong-type, c-like programming language.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages