Implementasi VendisScript di Python

100
Implementasi VendisScript di Python Oleh: Irsyad Asyhari Lubis

description

VendisScript's emulator implementation in Python. Describes how to implement a simple scripting language such as VendisScript in Python.

Transcript of Implementasi VendisScript di Python

Page 1: Implementasi VendisScript di Python

Implementasi VendisScriptdi Python

Oleh: Irsyad Asyhari Lubis

Page 2: Implementasi VendisScript di Python

Apa itu VendisScript?

Page 3: Implementasi VendisScript di Python

is a scripting language

Page 4: Implementasi VendisScript di Python

A scripting language or script language is a programming language that supports the writing of scripts, programs written for a special runtime environment that can interpret and automate the execution of tasks which could alternatively be

executed one-by-one by a human operator.

Sumber: http://en.wikipedia.org/wiki/Scripting_language

Page 5: Implementasi VendisScript di Python

Typically, a scripting language is characterized by the following properties:

● Ease of use. ● OS facilities - especially filesystem and related,

built in with easy interfaces. ● Interpreted from source code - to give the

fastest turnaround from script to execution. ● Relatively loose structure.

Sumber: http://en.wikipedia.org/wiki/Scripting_language

Page 6: Implementasi VendisScript di Python

Typically, a scripting language is characterized by the following properties:

● Ease of use. ● OS facilities - especially filesystem and related,

built in with easy interfaces. ● Interpreted from source code - to give the

fastest turnaround from script to execution. ● Relatively loose structure.

Sumber: http://en.wikipedia.org/wiki/Scripting_language

Page 7: Implementasi VendisScript di Python

is interpreted scripting language

Page 8: Implementasi VendisScript di Python

An interpreted language is a programming language that avoids explicit program compilation. The interpreter executes the program source code directly, statement by statement, as a processor or scripting engine does. This can be contrasted

with compiled language programs, which the user must explicitly translate into a lower-level machine

language executable.

Sumber: http://en.wikipedia.org/wiki/Interpreted_language

Page 9: Implementasi VendisScript di Python

is embedded, interpreted scripting language

Page 10: Implementasi VendisScript di Python

sorry, no reference this time...

Page 11: Implementasi VendisScript di Python

used in Android based mobile sales and distribution software

Page 12: Implementasi VendisScript di Python

why not Python?

Page 13: Implementasi VendisScript di Python

compared to Python, VendisScript is...

Page 14: Implementasi VendisScript di Python

simple

Page 15: Implementasi VendisScript di Python

in term of implementation

Page 16: Implementasi VendisScript di Python

too simple...

Page 17: Implementasi VendisScript di Python

no optimization

Page 18: Implementasi VendisScript di Python

no optimization (yet)

Page 19: Implementasi VendisScript di Python

but, there is one reason to rule them all

Page 20: Implementasi VendisScript di Python

size

Page 21: Implementasi VendisScript di Python

it does matter!

Page 22: Implementasi VendisScript di Python

less why...

more how...

Page 23: Implementasi VendisScript di Python

now we are talking about implementation

Page 24: Implementasi VendisScript di Python

in Python

Page 25: Implementasi VendisScript di Python

note that...

Page 26: Implementasi VendisScript di Python

scripting language on top of Python is generally not necessary

Page 27: Implementasi VendisScript di Python

unless it is DSL

Page 28: Implementasi VendisScript di Python

since this is only emulator...

Page 29: Implementasi VendisScript di Python

Apa itu VendisScript?

Page 30: Implementasi VendisScript di Python

JSON + Lisp

Page 31: Implementasi VendisScript di Python

JSON

Page 32: Implementasi VendisScript di Python

{    "firstName": "John",    "lastName": "Smith",    "age": 25,    "address": {        "streetAddress": "21 2nd Street",        "city": "New York",        "state": "NY",        "postalCode": 10021    },    "phoneNumbers": [        {            "type": "home",            "number": "212 555­1234"        },        {            "type": "fax",            "number": "646 555­4567"        }    ]}

Sumber: http://en.wikipedia.org/wiki/JSON

Page 33: Implementasi VendisScript di Python

Lisp

Page 34: Implementasi VendisScript di Python

(defun factorial (n)   (if (<= n 1)       1       (* n (factorial (­ n 1)))))

Sumber: https://en.wikipedia.org/wiki/Lisp_(programming_language)

Page 35: Implementasi VendisScript di Python

Basic syntax

Page 36: Implementasi VendisScript di Python

[

{

  "d": "Gratis 5 produk A untuk setiap pembelian 100 produk A.",

  "i": ["and",

         ["has", "11112313", "@products"],

         [">=", 

           ["bulk­qty", ["take", "11112313", "@products"]], 

           100.0]],

  "o": ["setq", "bonuses",

         ["add­bonus",

           ["bonus­new", "11112313",

             ["floatp", ["*", ["intp", 

               ["/", ["bulk­qty", ["take", "11112313", "@products"]], 100.0]], 5]], 

             "PCS"], 

             "@bonuses"]]

}]

Page 37: Implementasi VendisScript di Python

[

{

  "d": "Gratis 5 produk A untuk setiap pembelian 100 produk A.",

  "i": ["and",

         ["has", "11112313", "@products"],

         [">=", 

           ["bulk­qty", ["take", "11112313", "@products"]], 

           100.0]],

  "o": ["setq", "bonuses",

         ["add­bonus",

           ["bonus­new", "11112313",

             ["floatp", ["*", ["intp", 

               ["/", ["bulk­qty", ["take", "11112313", "@products"]], 100.0]], 5]], 

             "PCS"], 

             "@bonuses"]]

}]

Page 38: Implementasi VendisScript di Python

{

"d": "Test factorial.",

"i": true,

"o": ["prog",

["setq", "fac", 

["lambda", ["x"],

["cond",

["<=", "@x", 1], 1,

true, ["*", ["fac", ["­", "@x", 1]], "@x"]]]],

["fac", 3]]}

Page 39: Implementasi VendisScript di Python

{

"d": "Test factorial.",

"i": true,

"o": ["prog",

["setq", "fac", 

["lambda", ["x"],

["cond",

["<=", "@x", 1], 1,

true, ["*", ["fac", ["­", "@x", 1]], "@x"]]]],

["fac", 3]]}

Page 40: Implementasi VendisScript di Python

def fac(x):if x <= 1:

return 1else:

return x * fac(x ­ 1) 

Page 41: Implementasi VendisScript di Python

[{

“d”: @description(str),“i”: @input(JSON),“o”: @output(JSON)

},...

]

Page 42: Implementasi VendisScript di Python

Demo

Page 43: Implementasi VendisScript di Python

Compiler Stack

Page 44: Implementasi VendisScript di Python

SourceCode Lexer Parser AST

TargetCode

Page 45: Implementasi VendisScript di Python

Grammar

Page 46: Implementasi VendisScript di Python

prog : ('[' item (',' item)* ']' | '[' ']') EOF;

item : '{' '"d"' ':' QUOTED_IDENTIFIER ',' '"i"' ':' expr ',' '"o"' ':' expr '}';

expr :     | lambda_expr     | let_expr     | setq_expr     | prog_expr     | cond_expr     | apply_expr     | QUOTED_IDENTIFIER     | VAR_ACCESS     | '#nil'     | INT     | FLOAT     | 'true'     | 'false'     ;

lambda_expr : '[' '"lambda"' ',' '[' params ']' ',' body ']';

params : QUOTED_IDENTIFIER (',' QUOTED_IDENTIFIER)*;

body : expr ;

Page 47: Implementasi VendisScript di Python

let_expr : '[' '"let"' ',' '[' init_list* ']' ',' body ']';

setq_expr : '[' '"setq"' ',' QUOTED_IDENTIFIER ',' expr ']';

init_list : '[' QUOTED_IDENTIFIER ',' expr ']';

prog_expr : '[' '"prog"' (',' expr)+ ']';

cond_expr : '[' '"cond"' (',' cond_and_expr)+ ']';

cond_and_expr : expr ',' expr;

apply_expr : '[' QUOTED_IDENTIFIER (',' expr)* ']';

Page 48: Implementasi VendisScript di Python

VAR_ACCESS : '"@' IDENTIFIER '"';

QUOTED_IDENTIFIER : '"' IDENTIFIER '"';

INT : '­'? INT_WITHOUT_PREFIX;FLOAT : '­'? INT_WITHOUT_PREFIX '.' [0­9]* EXP?;

WS : [ \t\n\r]+ ­> skip;

fragmentIDENTIFIER : (ESC | ~('"'|'\\'))*;

fragmentINT_WITHOUT_PREFIX : '0'|[1­9][0­9]*;

fragmentEXP : [Ee][+|­]? INT_WITHOUT_PREFIX;

fragmentESC : '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\\'|UNICODE);

fragmentUNICODE : 'u' HEX HEX HEX HEX;

fragmentHEX : [0­9a­fA­F];

Page 49: Implementasi VendisScript di Python

Lexer

Page 50: Implementasi VendisScript di Python

JSON's lexer + parser

Page 51: Implementasi VendisScript di Python

Parser

Page 52: Implementasi VendisScript di Python
Page 53: Implementasi VendisScript di Python
Page 54: Implementasi VendisScript di Python

AST

Page 55: Implementasi VendisScript di Python

1 + (2 * 3)

Page 56: Implementasi VendisScript di Python

["+", 1, ["*", 2, 3]]

Page 57: Implementasi VendisScript di Python

+

1 *

2 3

Page 58: Implementasi VendisScript di Python

class Expression(object):def __init__(self, args=None):

self.args = args if args else []

def evaluate(self, env):pass

Page 59: Implementasi VendisScript di Python

+

1 *

2 3

AddExpression

MulExpressionIntExpression

IntExpression IntExpression

Page 60: Implementasi VendisScript di Python

class IntExpression(Expression):    def __init__(self, value):        self.value = value

    def evaluate(self, env):        return self.value

Page 61: Implementasi VendisScript di Python

class AddExpression(BasicMathExpression):    def evaluate(self, env):        return self._evaluate(env, 'Add', lambda x, y: x + y)

Page 62: Implementasi VendisScript di Python

class MulExpression(BasicMathExpression):    def evaluate(self, env):        return self._evaluate(env, 'Mul', lambda x, y: x * y)

Page 63: Implementasi VendisScript di Python
Page 64: Implementasi VendisScript di Python

Tipe data

Page 65: Implementasi VendisScript di Python

✔ Integer → ­1 0 1 2✔ Float → ­2.0 1.2 2.3✔ String → "This is a string"✔ List → ["list", 1, 2, 3.0, 

 "This is a string", ["list", 2, 3]]

✔ Empty list → "#nil"✔ Boolean → true false✔ Function✔ Product

Page 66: Implementasi VendisScript di Python

Cons

Page 67: Implementasi VendisScript di Python

["cons", 1, ["cons", 2, ["cons", 3, "#nil"]]]

Page 68: Implementasi VendisScript di Python

["list", 1, 2, 3]

Page 69: Implementasi VendisScript di Python

( head tail )

Page 70: Implementasi VendisScript di Python

( head ( head tail ) )

Page 71: Implementasi VendisScript di Python

( head ( head ( head tail ) ) )

Page 72: Implementasi VendisScript di Python

( head ( head ( head nil ) ) )

Page 73: Implementasi VendisScript di Python

class Cons(object):    def __init__(self, head=None, tail=None):        self._head = head        self._tail = tail

    @property    def head(self):        return self._head

    @property    def tail(self):        return self._tail

Page 74: Implementasi VendisScript di Python

    @staticmethod    def from_seq(seq):        if not seq:            return None

        head = Cons(seq[0])        current = head

        for item in seq[1:]:            next_cons = Cons(item)            current._tail = next_cons            current = next_cons

        return head

    def to_list(self):        result = []

        self.each(result.append)

        return result

Page 75: Implementasi VendisScript di Python

    def each(self, f):        f(self.head)

        tail = self.tail        while tail != None:            if isinstance(tail, Cons):                f(tail.head)                tail = tail.tail            else:                f(tail)                tail = None

Page 76: Implementasi VendisScript di Python

def map(self, f):pass

def filter(self, f):pass

def reduce(self, f, *args):pass

Page 77: Implementasi VendisScript di Python

Scope

Page 78: Implementasi VendisScript di Python

Dynamic Scope vs Lexical Scope

Page 79: Implementasi VendisScript di Python

Dynamic Scope vs Lexical Scope

Page 80: Implementasi VendisScript di Python

two constructs to introduce a variable

Page 81: Implementasi VendisScript di Python

["setq", "variable1", 100]

Page 82: Implementasi VendisScript di Python

["let", [["variable1", 100]]["print", "@variable1"]]

Page 83: Implementasi VendisScript di Python

function's paramenters also introduce local variables

Page 84: Implementasi VendisScript di Python

{

"d": "Test factorial.",

"i": true,

"o": ["prog",

["setq", "fac", 

["lambda", ["x"],

["cond",

["<=", "@x", 1], 1,

true, ["*", ["fac", ["­", "@x", 1]], "@x"]]]],

["fac", 3]]}

Page 85: Implementasi VendisScript di Python

class BonusEnvironment(dict):    def __init__(self, parent=None):        self._parent = parent

    def __getitem__(self, key):        if key not in self and self._parent:            return self._parent[key]        else:            return super(BonusEnvironment, self).__getitem__(key)

    def set_global(self, key, value):        # by convention, global environment is whose parent         # is None.        if not self._parent:            self[key] = value        else:            self._parent.set_global(key, value)

Page 86: Implementasi VendisScript di Python

class GetValExpression(Expression):    def evaluate(self, env):        name = self._evaluated_args(env,                                     'GetVal', ((str, unicode),))        try:            return env[name]        except KeyError:            # search in builtin functions            try:                builtin_class_name = builtin_expressions[name]                builtin_class = globals()[builtin_class_name]                builtin_instance = builtin_class()                return BuiltInFunction(body=builtin_instance)            except KeyError:                return None

Page 87: Implementasi VendisScript di Python

Functions

Page 88: Implementasi VendisScript di Python

63 builtin functions

Page 89: Implementasi VendisScript di Python

["setq", "fib",["lambda", ["n"],

["cond",["<", "@n", 2], 1,true, ["+", ["fib", ["­", "@n", 1]],

["fib", ["­", "@n", 2]]]]]]

Page 90: Implementasi VendisScript di Python

class LambdaExpression(Expression):    def __init__(self, params, body):        self.params = params        self.body = body

    def evaluate(self, env):        return Function(self.params, self.body)

Page 91: Implementasi VendisScript di Python
Page 92: Implementasi VendisScript di Python

class ApplyExpression(Expression):    def __init__(self, funcName, args):        self.funcName = funcName        self.args = args

    def evaluate(self, env):        func = env[self.funcName]        if isinstance(func, Function):            return func.apply(env, self.args)        else:            raise ExpressionException('Apply: Cannot find function with name {0}'.format(self.funcName))

Page 93: Implementasi VendisScript di Python

how to add new builtin function?

Page 94: Implementasi VendisScript di Python

it should be easy, right?

Page 95: Implementasi VendisScript di Python

Demo

Page 96: Implementasi VendisScript di Python

Regrets

Page 97: Implementasi VendisScript di Python

should not use None as value

Page 98: Implementasi VendisScript di Python

class NilType(object):def __nonzero__(self):return False

Page 99: Implementasi VendisScript di Python

Nil = NilType()

Page 100: Implementasi VendisScript di Python

Thank you!!!