YJS语法
=======

--------------

概述
----

YJS源文件包括任意数量的\ **import声明**\ 和一个\ **contract定义**\ 。

--------------

import声明
----------

与JavaScript（ES6）类似，YJS也支持import声明语句，在全局层面，开发者可以使用如下import声明来导入其他文件。

::

   import "filename";

内容
~~~~

import声明语句将包含在“filename”文件中的所有全局符号（单元）导入到当前文件，且全局范围内有效。

路径
~~~~

**filename**\ 通常用\ **/**\ 做目录分隔符来表示文件的路径，例如，从同一目录下导入\ **x.yjs**\ 文件到当前文件，可以使用\ **import
“x.yjs”**\ 语句；从其他目录下导入\ **x.yjs**\ 使用\ **import
“lib/x.yjs”**\ 语句。

--------------

Contract定义
------------

示例
~~~~

以下是一个合约示例，用于JSON处理，此YJS源文件以合约名称命名。

::

   contract ScoreAdder{
       //arg =  {"action":"main","arg":"[{\"score\":20},{\"score\":20}]"}
       export function main(arg){
           //JSON is a build-in object.
           var point = JSON.parse(arg);
           var s = 0;
           print(point[0].score);
           print(point.length);
           for (var i=0;i<point.length;i++){
               s+=point[i].score/1.0;
           }
           print("total score= "+s);
           return s;
       }
   }

注释
~~~~

YJS源文件支持以（\ **//**\ ）表示的单行注释和以（\ **/*…*/**\ ）表示的多行注释，如下所示：

::

   // 这是一个单行注释
   /*
    * 这是一个
    * 多行注释
    */

注解
~~~~

与Java类似，YJS也支持注解声明合约和函数。

在YJS中，有几种内建注解：LogType、LogLocation、Access、Permission。
当然，可以自定义注解。
内建注解的详细使用方式可以通过YJS内置API文档查看。
开发者可以使用如下注解来声明合约和函数。

::

   @LogType("Arg","Result","Branch")
   @SelfDefinedAnntation("dad",1)
   @Access
   function xxx(){}

结构
~~~~

YJS中的合约类似于Java中的类。每个合约都定义了一定数量的\ **变量**\ 、\ **函数**\ 和\ **事件**\ 。

变量
^^^^

YJS中的变量类似于JavaScript（ES6）中的变量，分为\ **全局变量**\ 和\ **局部变量**\ 。

全局变量:

::

   judge =  true;

局部变量:

::

   var vs = "This is a string";

所有的变量都是\ **动态类型**\ ，因为变量的具体类型是根据变量值来决定的。如上示例中，全局变量judge是bool类型，局部变量vs是字符串类型。

函数
^^^^

函数是合约中的可执行单元。YJS中有两种类型的函数：普通函数和用\ **export**\ 关键字修饰的exported函数。

以下是exported函数和普通函数的区别：

1. 只有exported函数能被其他合约调用。
2. exported函数只能有一个参数且参数类型必须为String。
3. exported函数的返回类型必须是String。
4. 内置对象requester（请求者的公钥）只能存在于exported函数或onCreate函数，因为onCreate()虽然没被\ **export**\ 关键字修饰，但它自带requester对象且该函数可以自动执行。

事件
^^^^

YJS中的事件类似于Solidity中的事件。

**发布者**\ 定义一个包含事件发布函数的事件，然后通过调用事件发布函数发布事件。

**订阅者**\ 订阅并处理事件。

事件示例如下：

EventPuber.yjs

::

   contract EventPuber{
       event abcEvent;
       export function pub(arg){
           abcEvent(arg);
           return "done!";
       }
   }

EventSuber.yjs

::

   contract EventSuber{
       export function init(arg){
           YancloudUtil.subscribe("EventPuber","abcEvent",handler);
           print("Handler:"+handler);
       }
       function handler(e){
           var ret = "ReceiveEvent:"+(e.type)+" "+(e.content);
           print(ret);
       }
   }

--------------

YJS项目
-------

除了只包含一个contract定义的YJS源文件，YJS引擎还支持\ **YJS项目**\ 。

每个YJS
project包含了合约执行过程中需用到的各种文件，包括yjs源文件\ **“.yjs”**\ 和其他资源文件，如\ **“mainfest.json”**,
**“.js”**, **“.txt”**,\ **“.jar”**, …

Manifest.json
~~~~~~~~~~~~~

每个YJS项目在项目的根目录下必须有一个\ **mainfest.json**\ 文件，此文件描述了合约对于YJS的编译工具（YJS引擎）所需的必要信息。

Manifest结构
^^^^^^^^^^^^

manifest文件需包含以下信息：

1. **main**: 项目中将要被执行的合约文件。
2. **type**: 合约的类型，如数据合约/算法合约…
3. **builder**: 构建YJS项目的开发者姓名。
4. **insnLimit**: 运行合约需要消耗的值。
5. **pyDependences**: 项目所需的Python依赖。

Manifest示例
^^^^^^^^^^^^

::

   {
       "main": "contract.js",
       "type": "Data",
       "builder": "caihq",
       "permissions": 0L,
       "pyDependences": [
           {
               "name": "yjsexample",
               "modules": [
                   {
                       "name": "sample"
                   }
               ]
           }
       ]
   }

YJS-Java
~~~~~~~~

Jar文件实现了YJS与其他编程语言间的\ **跨语言调用**\ ，如YJS-Java,
YJS-Python, …
通过将Java文件包成jar包的方式，使得合约可直接调用Java中的方法。

Java class:

.. code:: java

   package your.own.pkg;
   public class HelloWorld {
    public static int fun(String arg){
     return arg.length;
    }
    public int fun2(String arg){
     return arg.length;
    }
   }

InvokeJava.yjs

.. code:: javascript

   contract InvokeJava{
    export function main(arg){
     var Hello = Java.type("your.own.package.HelloWorld");
     var hello = new Hello();
     return Hello.fun(arg)+hello.fun2(arg);
    }
   }

YJS-前端
~~~~~~~~

使用数瑞客户端来访问智能合约支持从智能合约中获取html/js/css等资源文件，
并在\ `BDWareWebClient <./_static/BDWareWebClient.zip>`__\ 中渲染。
首先在合约中import以下模块。

.. code:: javascript

   module Viewable{
     export function loadResource(arg){
       return Global.Resources.loadAsString(arg);
     }
     export function needRender(arg){
       return true;
     }
   }

同时，import以后，定义一个getMainFrame方法，以便数瑞客户端识别主页：

.. code:: javascript

   export function getMainFrame(arg){
     return "/html/main.html";
   }

该方法的返回结果为一个资源文件的路径。
示例的资源文件“/html/main.html”如下：

.. code:: html

   <div>
   <button onclick="queryDataFromContract()">Hello,</button> Data from contract:
   <span id="resultText"></span>
   <script fromContract="/html/hello.js"></script>
   <link fromContract="/html/hello.css"/>
   </div>

示例的资源文件“/html/hello.js”如下：

.. code:: javascript

   var queryDataFromContract = function(){
       //第一个参数为函数名，第二个为参数，第三个参数为回调。
       var data = executeCurrentContract("query","abc",function(argg){
           $("#resultText")[0].innerHTML = argg.result;
       });
   }

参考示例：

YJS-Python
~~~~~~~~~~

TODO
