TapiocaScript / TVM Objective

TapiocaScript与TVM的目标

This note is not stable and may be changed at any time.

本文作为YRFC2的补充,更详细地描述了TapiocaScript和TVM的目标。 本文是一个宪章性质的文档,在TapiocaScript和TVM的设计中应当遵守本文所述的原则。

  • TapiocaVM应当成为一个程序虚拟机而非系统虚拟机。
    • 提供基于程序控制流的抽象,而非提供虚拟处理器或操作系统。
    • 类似于JVM,YARV,LVM和ZendEngine,但拒绝成为QEMU或者Docker
  • TapiocaVM应当成为一个轻量化嵌入式虚拟机。
    • 不同于JVM通常以独立程序虚拟机的形式出现,TapiocaVM希望成为如同V8和Lua那样的嵌入式程序虚拟机。
  • TapiocaVM应当有相对稳定的字节码。
    • 不同于Lua和V8面向特定语言提供不稳定的字节码,为了保证可以通过二进制字节码发布程序,TapiocaVM希望能如同JVM那样提供稳定的字节码。
    • TapiocaVM鼓励基于二进制字节码的程序发布,但应当保留以REPL形式运行程序的能力。
  • TapiocaVM只提供最基本的数据结构和运行时抽象。
    • TVM不在字节码层面提供对于任何并发模型的抽象。
    • 在字节码层面提供GC相关内容,但不对行为进行强制性规定。
  • TapiocaVM标准实现相关
    • TapiocaVM应当提供与其他编程语言的良好整合性。
    • TapiocaVM应当注重执行效率。
      • 注重解释执行效率
      • 在可能的情况下应当在不破坏字节码的前提下实现AOT或JIT功能。
    • 命令行参数
      • 指定AOT缓存目录
      • 指定需要加载的字节码
      • 指定需要加载的原生接口模块
  • TapiocaScript是运行在TapiocaVM上的编程语言

  • TapiocaScript会尽量避免在语法上提供过多的特殊地位
    • TapiocaScript应当极力避免为任何形式的并行处理在语法层面提供特殊地位。(async之于JavaScript,go之于Golang)
  • TapiocaScript中不会支持自增(++)自减(–)单目运算符
  • TapiocaScript中应当避免隐含的类型转换(以JavaScript为反例)
  • TapiocaScript / TapiocaVM 应用案例
    • 大型计算程序库中的嵌入式脚本语言
    • 游戏引擎中的嵌入式脚本语言
    • 几乎一切可以但不必用JavaScript来完成任务的场合

TapiocaScript旨在成为一门可以对标Lua和JavaScript的嵌入式编程语言。

  • A Program Virtual Machine, rather than a System Virtual Machine. An abstract of program, not an operating system or processor.
    • Similar with JVM, YARV, LVM and ZendEngine, offers a managed runtime for high-level programming language.
    • Do not simulate any existing hardware (not to be a QEMU), nor simulate a operation system (not to be a Docker)
  • Intended to be used both as a powerful, lightweight, embeddable program virtual machine for any program that needs one, and as a powerful but lightweight (compare with JVM or V8 engine) and efficient stand-alone program virtual machine.
  • Works embedded in a host program. (Frequently, this host is the stand-alone program.) The host program can invoke functions to execute a piece of TVM byte-code, can write and read TVM statements, and can register C functions to be called by TVM byte-code. Through the use of C functions, TVM can be augmented to cope with a wide range of different domains, thus creating customized programming languages sharing a syntactical framework. Request host program to registe native interface to TVM. TVM will not tring to load the native interface itself. (No require method in TVM, but the host program can implement it as a native interface)
  • Optimise for program execution speed. Encourage the implementation of hardware-independent algorithms within virtual machines.
  • Compare with other language and its VMs

Basic Design

  • { and } are used for block scope.
  • ; is used for statement separator.
  • = is used for assignment.

  • var for variable declaration.
  • functions are first-class objects.
  1. Declarative programming with top-level imperative programming supported
  2. No macro avail in the source code. Alternatively, using compiler parameter to pass a macro defination file.
  3. Block requires to bi quoted by { and }

Variable

In TapiocaScript, variable does not contain the type information. Who contains the type information is the value.

var a;

a = false    /* boolean */
a = "hello"  /* string */
a = 314      /* double */
a = i32:314  /* signed 32bit integer */

In TapiocaScript, variable can be decleared implicitly or expicitly.

a = 3.14

foo = func i32:() {
  a; /* a is float64:3.14 (global variable) */

  let a = "3.14"; /* a will be assigned to string:"3.14" */
  /*
    Should we give some warning here?
    Some one likes "Warning: assignment changed the value's type"
  */

  var a; /* another variable is decleared (local variable) */

  a = i32:314; /* a will be 32bit signed integer 314 */

  a + "12" /* error: string cannot be add to integer */
}

/* a is float64:3.14 here */

foo();

/* a will be string:"3.14" here */
variable-declear ::= "var" identifier [ "=" variable-initlizer ] [ { "," identifier [ "=" variable-initilizer ] } ]

assignment ::= [ "let" ] identifier "=" statement

Function

/* Complete function decleartion */
/*
 * Function type identifier:
 * func <return> : <param-list>
 */
/*
 * Functional block:
 * [ <capture-list> ] { <statements> }
var main = func (i32:argc, const ref ref u8: argv ) => i32:
[const ref ref u8: envs] /* Can be omitted */
{
  stdout.print("hello world\n"); 
  return 0;
}

Code Example


# import the runtime module and give the module an alias name runt
# import is an dummy function, it will be replaced by the compiler
const runt = import("runtime")

# import the runt module to global namespace
import("stdio")

runt.load("./math.class")

# assign PI as an const value, the type was infered as float64
const PI = 3.1415926

const e = f32( 2.718281828 )

# declear int_tmpl as a template type which can be instanced as i8, i16, i32, i64
let int_tmpl = template( i8, i16, i32, i64 )




var main = func (argc :int, argv: []string) int {
  stdout.print("hello world\n");
  return 0;
}

export main

BNF


program ::= { statement }

assignment-statement ::= [ "let" ] identifier "="

if-statement ::= "if" "(" expression ")" statement [ "else" statement ]

block-begin ::= "{"
block-end ::= "}"

block-statement ::= block-begin { statement } block-end