2.3. Semantics

This chapter specifies the semantics of Kink programs as transformation into KSM procedures. The transformation is comprised of the two steps “normalization” and “translation.”

Normalization

Normalization is a mapping from a program to another program.

When P is a program, the result of normalization of P is written as normalize(P).

Translation

Translation is a mapping from a program to a KSM procedure,

When P is a program, the result of translation of P is written as translate(P).

Syntax extension

This chapter uses extended syntax of Kink programs and KSM procedures. It accepts embedding of program fragments or procedure fragments by <<< and >>>.

For example, when P is an integer expression 42, the program fragment <<<P>>>.to_str is regarded as equivalent to 42.to_str.

For example of the procedure, when S is an instruction num 42, the procedure { <<<S>>>; dup; emptylist; flip; deref to_str; call } is regarded as equivalent to the procedure { num 42; dup; emptylist; flip; deref to_str; call }.

Within embedded fragments, series of expressions and instructions are represented with .... For example, if E1 is an integer expression 42, E2 is a decimal expression 3.14, and E3 is a string expression 'Hello world', foo(<<<E1 ... E3>>>) represents a call expression foo(42 3.14 'Hello world').

2.3.1. Program

program ::= chunk

Normalization

Let

When a program P matches a form on the first column of the table below, normalize(P) is defined as another program in the corresponding cell on the second column.

P: program normalize(P): program
<<<C>>> <<<nchunk(C)>>>

Translation

Let

  • C be a chunk.

When a program P matches a form on the first column of the table below, translate(P) is defined as a KSM procedure in the corresponding cell on the second column.

P: program translate(P): KSM procedure
<<<C>>> { <<<tchunk(C)>>> }

Examples

This is an example “hello world” program.

#!/usr/bin/env kink

print_line('Hello, world!')
print_line('Hello, Kink!')

2.3.2. Chunks

chunk ::= empty | expression chunk

A chunk is a series of zero or more expressions.

If the chunk consists of no expressions, it produces base. If the chunk consists of one or more expressions, it evaluates the expressions in the order they appears, and produces the result of the last expression.

Normalization

Let

  • n be a non-negative integer,
  • and Ei be an expression for each integer i between 1 and n.

When a chunk C matches a form on the first column of the table below, nchunk(C) is defined as another chunk in the corresponding cell on the second column.

C: chunk nchunk(C): chunk
<<<E1 ... En>>> <<<nexp(E1) ... nexp(En)>>>

Translation

Let

  • n be a non-negative integer,
  • and Ei be an expression for each integer i between 1 and n.

When a chunk C matches the form <<<E1 ... En>>>, and n is in the range on the first column of the table below, tchunk(C) is defined as an instruction series in the corresponding cell on the second column.

n: integer tchunk(C): instruction series
0 base
Greater than or equal to 1 <<<texp(E1)>>>; <<<tsucc(E2) ... tsucc(En)>>>

When E is an expression, tsucc(E) is defined as an instruction series as follows.

tsucc(E): instruction series
remove; <<<texp(E)>>>

Examples

If a chunk consists of no expressions, it produces base.

:Result_of_chunk = ()
print_line(Result_of_chunk.show)  # => base

If a chunk consists of one or more expressions, the expressions are evaluated sequentially, and the chunk produces the result of the last expression.

:Result_of_chunk = (1 2 3)
print_line(Result_of_chunk)  # => 3

2.3.3. Expressions

expression ::= assign_op

Normalization

When E is an expression, which always matches the assignment operator expression, nexp(E) is defined as another expression as follows.

nexp(E): expression
<<<nassign(E)>>>

Translation

When an expression E matches the nonterminal on the first column of the table below, texp(E) is defined as an instruction series in the corresponding cell on the second column.

Type of E texp(E): expression
Number expression <<<tnum(E)>>>
String expression <<<tstr(E)>>>
Context environment expression <<<tctxenv(E)>>>
Context receiver expression <<<tctxrecv(E)>>>
Context argument list expression <<<tctxargs(E)>>>
Context argument expression <<<tctxarg(E)>>>
Parentheses expression <<<tparen(E)>>>
List expression <<<tlist(E)>>>
Dotted function expression <<<tdfun(E)>>>
Attributional dereference expression <<<taderef(E)>>>
Attributional reference expression <<<taref(E)>>>
Attributional call expression <<<tacall(E)>>>

2.3.4. Primary expressions

primary ::= num
          | str
          | context_env
          | context_recv
          | context_args
          | context_arg
          | paren
          | list
          | local_fun
          | dotted_fun
          | local_deref
          | attr_deref
          | local_ref
          | attr_ref
          | local_call
          | attr_call

Primary expression is used as an alias for the nonterminal primary.

Normalization

When a primary expression E matches the nonterminal on the first column of the table below, nprimary(E) is defined as another primary expression in the corresponding cell on the second column.

Type of E nprimary(E): primary expression
Number expression <<<E>>>
String expression <<<E>>>
Context environment expression <<<E>>>
Context receiver expression <<<E>>>
Context argument list expression <<<E>>>
Context argument expression <<<E>>>
Parentheses expression <<<nparen(E)>>>
List expression <<<nlist(E)>>>
Local function expression <<<nlfun(E)>>>
Dotted function expression <<<ndfun(E)>>>
Local dereference expression <<<nlderef(E)>>>
Attributional dereference expression <<<naderef(E)>>>
Local reference expression <<<nlref(E)>>>
Attributional reference expression <<<naref(E)>>>
Local call expression <<<nlcall(E)>>>
Attributional call expression <<<nacall(E)>>>

2.3.5. Number expressions

num ::= INTEGER
      | DECIMAL

Number expression is used as an alias for the nonterminal num.

Number expressions produce number values.

Translation

Let

When a number expression E matches a form on the first column of the table below, tnum(E) is defined as a num instruction in the corresponding cell on the second column.

E: number expression tnum(E): instruction
<<<N>>> num <<<N>>>
<<<D>>> num <<<D>>>

2.3.6. String expressions

str ::= STRING

String expression is used as an alias for the nonterminal str.

String expressions produce string values.

Translation

Let

When a string expression E matches a form on the first column of the table below, tstr(E) is defined as a str instruction in the corresponding cell on the second column.

E: string expression tstr(E): instruction
<<<S>>> str <<<S>>>

2.3.7. Context environment expressions (\env)

context_env ::= '\' VERB('env')

Context environment expression is used as an alias for the nonterminal context_env.

The context environment expression produces the context environment.

Translation

When E is a context environment expression, tctxenv(E) is defined as an env instruction as follows.

tctxenv(E): instruction
env

2.3.8. Context receiver expressions (\recv)

context_recv ::= '\' VERB('recv')

Context receiver expression is used as an alias for the nonterminal context_recv.

The context receiver expression produces the context receiver.

Translation

When E is a context receiver expression, tctxrecv(E) is defined as a recv instruction as follows.

tctxrecv(E): instruction
recv

2.3.9. Context argument list expressions (\args)

context_args ::= '\' VERB('args')

Context argument list expression is used as an alias for the nonterminal context_args.

The context argument list expression produces the context argument list.

Translation

When E is a context argument list expression, tctxargs(E) is defined as an args instruction as follows

tctxargs(E): instruction
args

2.3.10. Context argument expressions (\0, \1, \2, ...)

context_arg ::= '\' INTEGER

Context argument expression is used as an alias for the nonterminal context_arg.

The context argument expression produces the context argument specified by the index.

Translation

Let

When a context argument expression E matches a form on the first column of the table below, tctxarg(E) is defined as an arg instruction in the corresponding cell on the second column.

E: context argument expression tctxarg(E): instruction
\<<<N>>> arg <<<N>>>

2.3.11. Parentheses expressions

paren ::= OPENPAREN `chunk` ')'
        | NL_OPENPAREN `chunk` ')'
        | WS_OPENPAREN `chunk` ')'

Parentheses expression is used as an alias for the nonterminal paren.

A parentheses expression groups a chunk so that it can be used as an expression, and produces the result of the chunk.

Normalization

Let

When a parentheses expression E matches a form on the first column of the table below, nparen(E) is defined as another parentheses expression in the corresponding cell on the second column.

E: parentheses expression nparen(E): parentheses expression
(<<<C>>>) (<<<nchunk(C)>>>)

Translation

Let

When a parentheses expression E matches a form on the first column of the table below, tparen(E) is defined as an instruction series in the corresponding cell on the second column.

E: parentheses expression tparen(E): instruction series
(<<<C>>>) <<<tchunk(C)>>>

2.3.12. Elements producers

elements_producer ::= expression | '[|' expression '|]'

Elements producer is used as an alias for the nonterminal elements_producer.

Elements producers are used as components of list bodies.

Normalization

Let

When an elements producer P matches a form on the first column of the table below, nelemprod(P) is defined as another elements producer in the corresponding cell on the second column.

P: elements producer nelemprod(P): elements producer
<<<E>>> <<<nexp(E)>>>
[|<<<E>>>|] [|<<<nexp(E)>>>|]

Translation

Let

When an elements producer P matches a form on the first column of the table below, telemprod(P) is defined as an instruction series in the corresponding cell on the second column.

P: elements producer telemprod(P): instruction series
<<<E>>> <<<texp(E)>>>; add
[|<<<E>>>|] <<<texp(E)>>>; concat

2.3.13. List bodies

list_body ::= empty | elements_producer list_body

List body is used as an alias for the nonterminal list_body.

A list body produces a list value. List bodies are not independent expressions, but used as components of list expressions, actual argument list, and formal arguments.

Normalization

Let

  • n be a non-negative integer,
  • and Pi be an elements producer for each integer i between 1 and n.

When a list body L matches a form on the first column of the table below, nlbody(L) is defined as another list body in the corresponding cell on the second column.

L: list body nlbody(L): list body
<<<P1 ... Pn>>> <<<nelemprod(P1) ... nelemprod(Pn)>>>

Translation

Let

  • n be a non-negative integer,
  • and Pi be an elements producer for each integer i between 1 and n.

When a list body L matches a form on the first column of the table below, tlbody(L) is defined as an instruction series in the corresponding cell on the second column.

L: list body tlbody(L): instruction series
<<<P1 ... Pn>>> emptylist; <<<telemprod(P1) ... telemprod(Pn)>>>

2.3.14. List expressions

list ::= '[' list_body ']'

List expression is used as an alias for the nonterminal list.

List expressions produce list values.

Normalization

Let

When a list expression E matches a form on the first column of the table below, nlist(E) is defined as another list expression in the corresponding cell on the second column.

E: list expression nlist(E): list expression
[<<<L>>>] [<<<nlbody(L)>>>]

Translation

Let

When a list expression E matches a form on the first column of the table below, tlist(E) is defined as an instruction series in the corresponding cell on the second column.

E: list expression tlist(E): instruction series
[<<<L>>>] <<<tlbody(L)>>>

Example

In this example, the list expression on the first line produces a list containing numbers 1, 2 and 3. The list expression on the second line produces a list containing 'ping', 1, 2, 3 and 'pong', expanding the first list.

:Sub = [1 2 3]
:List = ['ping' [|Sub|] 'pong']
print_line(List)  # => ['ping' 1 2 3 'pong']

2.3.15. Function bodies

fun_body ::= formal_receiver formal_args chunk
           | formal_receiver formal_args '->' chunk
formal_receiver ::= empty
                  | OPENBRACKET expression ']'
                  | WS_OPENBRACKET expression ']'
formal_args ::= empty
              | OPENPAREN list_body ')'
              | WS_OPENPAREN list_body ')'

Function body is used as an alias for the nonterminal fun_body.

Function bodies are used as components of local function expressions and function arguments.

Normalization

Let

When a function body B matches a form on the first column of the table below, nfbody(B) is defined as another function body in the corresponding cell on the second column.

B: function body nfbody(B): function body
<<<C>>>
-> <<<C>>>
-> <<<nchunk(C)>>>
(<<<L>>>) <<<C>>>
(<<<L>>>) -> <<<C>>>
-> [<<<nlbody(L)>>>].op_set(\args) (<<<nchunk(C)>>>)
[<<<R>>>] <<<C>>>
[<<<R>>>] -> <<<C>>>
-> (<<<nexp(R)>>>).op_set(\recv) (<<<nchunk(C)>>>)
[<<<R>>>] (<<<L>>>) <<<C>>>
[<<<R>>>] (<<<L>>>) -> <<<C>>>
-> (<<<nexp(R)>>>).op_set(\recv) [<<<nlbody(L)>>>].op_set(\args) (<<<nchunk(C)>>>)

2.3.16. Local function expressions

local_fun ::= OPENBRACE fun_body '}'
            | WS_NL_OPENBRACE fun_body '}'

Local function expression is used as an alias for the nonterminal local_fun.

A local function expression produces a function packing the context environment as the enclosing environment.

Normalization

Let

When a local function expression E matches a form on the first column of the table below, nlfun(E) is defined as a dotted function expression in the corresponding cell on the second column.

E: local function expression nlfun(E): dotted function expression
{ <<<B>>> } \env.{ <<<nfbody(B)>>> }

Examples

It can be said that the syntax of formal receivers and formal arguments are syntax sugar. In this example, fun1 and fun2 are equivalent.

:fun1 = { [:Self] (:X :Y :Z)
    'result'
}

:fun2 = {
    :Self = \recv
    [:X :Y :Z] = \args
    'result'
}

op_set function of a variable reference returns the variable reference itself. Therefore, default values of arguments can be given like this.

:fun = { (:X :Y = 100 :Z = 200)
    print_line([X Y Z])
}

fun('x' 'y' 'z')  # => ['x' 'y' 'z']
fun('x' 'y')      # => ['x' 'y' 200]
fun('x')          # => ['x' 100 200]
fun               # => No variable 'X' in <env:#program.name='(stdin)':hash=1140>...

2.3.17. Dotted function expressions

dotted_fun ::= primary '.' OPENBRACE fun_body '}'
             | primary '.' WS_NL_OPENBRACE fun_body '}'

Dotted function expression is used as an alias for the nonterminal dotted_fun.

A dotted function expression produces a function packing the result of the expression precedent to the period as the enclosing environment.

Normalization

Let

When a dotted function expression E matches a form on the first column of the table below, ndfun(E) is defined as another dotted function expression in the corresponding cell on the second column.

E: dotted function expression ndfun(E): dotted function expression
<<<P>>>.{ <<<B>>> } <<<nprimary(P)>>>.{ <<<nfbody(B)>>> }

Translation

Let

When a dotted function expression E matches a form on the first column of the table below, tdfun(E) is defined as an instruction series in the corresponding cell on the second column.

E: dotted function expression tdfun(E): instruction series
<<<P>>>.{ -> <<<C>>> } <<<texp(P)>>>; fun { <<<tchunk(C)>>> }

2.3.18. Local dereference expressions

local_deref ::= NOUN | '$' VERB

Local dereference expression is used as an alias for the nonterminal local_deref.

A local dereference expression dereferences a variable of the context environment.

Normalization

Let

When a local dereference expression E matches a form on the first column, nlderef(E) is defined as a an attributional dereference expression in the corresponding cell on the second column.

E: local dereference expression nlderef(E): attributional dereference expression
<<<N>>> \env.<<<N>>>
$<<<V>>> \env$$<<<V>>>

Example

In this example variables named (1) Num and (2) fun are dereferenced from the context environment.

:Num = 42
# (1)
print_line(Num)   # => 42

:fun = { do_something }
# (2)
print_line($fun)  # => { do_something }

2.3.19. Attributional dereference expressions

attr_deref ::= primary '.' NOUN
             | primary '$$' VERB

Attributional dereference expression is used as an alias for the nonterminal attr_deref.

An attributional dereference expression dereferences a variable of the owner.

Normalization

Let

When an attributional dereference expression E matches a form on the first column of the table below, naderef(E) is defined as another attributional dereference expression in the corresponding cell on the second column.

E: attributional dereference expression naderef(E): attributional dereference expression
<<<P>>>.<<<N>>> <<<nprimary(P)>>>.<<<N>>>
<<<P>>>$$<<<V>>> <<<nprimary(P)>>>$$<<<V>>>

Translation

Let

When an attributional dereference expression E matches a form on the first column of the table below, taderef(E) is defined as an instruction series in the corresponding cell on the second column.

E: attributional dereference expression taderef(E): instruction series
<<<P>>>.<<<N>>> <<<texp(P)>>>; deref <<<N>>>
<<<P>>>$$<<<V>>> <<<texp(P)>>>; deref <<<V>>>

Example

In this example, variables named (1) Num and (2) fun owned by the value stored in Owner are dereferenced.

:Owner = new_value

Owner::Num = 42
# (1)
print_line(Owner.Num)   # => 42

Owner::fun = { do_something }
# (2)
print_line(Owner$$fun)   # => { do_something }

2.3.20. Local reference expressions

local_ref ::= ':' NOUN | ':' VERB

Local reference expression is used as an alias for the nonterminal local_ref.

A local reference expression produces a variable reference of the context environment.

Normalization

Let

When a local reference expression E matches a form on the first column of the table below, nlref(E) is defined as an attributional reference expression in the corresponding cell on the second column.

E: local reference expression nlref(E): attributional reference expression
:<<<N>>> \env::<<<N>>>
:<<<V>>> \env::<<<V>>>

Example

In this example, references of variables named (1) Num and (2) fun owned by \env are produced.

# (1)
:Num = 42
print_line(Num)   # => 42

# (2)
:fun = { do_something }
print_line($fun)  # => { do_something }

2.3.21. Attributional reference expressions

attr_ref ::= primary '::' NOUN
           | primary '::' VERB

Attributional reference expression is used as an alias for the nonterminal attr_ref.

An attributional reference expression produces a variable reference of the owner.

Normalization

Let

When an attributional reference expression E matches the first column of the table below, naref(E) is defined as another attributional reference expression in the corresponding cell on the second column.

E: attributional reference expression naref(E): attributional reference expression
<<<P>>>::<<<N>>> <<<nprimary(P)>>>::<<<N>>>
<<<P>>>::<<<V>>> <<<nprimary(P)>>>::<<<V>>>

Translation

Let

When an attributional reference expression E matches the first column of the table below, taref(E) is defined as an instruction series in the corresponding cell on the second column.

E: attributional reference expression taref(E): instruction series
<<<P>>>::<<<N>>> <<<texp(P)>>>; varref <<<N>>>
<<<P>>>::<<<V>>> <<<texp(P)>>>; varref <<<V>>>

Example

In this example, references of variables named (1) Num and (2) fun owned by the value stored in Owner are produced.

:Owner = new_value

# (1)
Owner::Num = 42
print_line(Owner.Num)   # => 42

# (2)
Owner::fun = { do_something }
print_line(Owner$$fun)   # => { do_something }

2.3.22. Actual receivers

recv ::= empty
       | OPENBRACKET expression ']'

Actual receiver is used as an alias for the nonterminal recv.

An actual receiver is a part of local call expressions and attributional call expressions.

Normalization

Let

When an actual receiver R matches a form on the first column of the table below, nrecv(R) is defined as another actual receiver in the corresponding cell on the second column.

R: actual receiver nrecv(R): actual receiver
(empty) (empty)
[<<<E>>>] [<<<nexp(E)>>>]

2.3.23. Function arguments

fun_arg ::= OPENBRACE fun_body '}'

Function argument is used as an alias for the nonterminal fun_arg.

Function arguments are components of actual argument list.

Normalization

Let

When a function argument F matches a form on the first column of the table below, nfarg(F) is defined as a dotted function expression, in the corresponding cell on the second column.

F: function argument nfarg(F): local function expression
{ <<<B>>> } \env.{ <<<nfbody(B)>>> }

2.3.24. Actual argument list

args ::= paren_args fun_args
paren_args ::= empty | OPENPAREN list_body ')'
fun_args ::= empty | fun_arg fun_args

Actual argument list is used as an alias for the nonterminal args.

An actual argument list is a part of local call expressions and attributional call expressions.

Normalization

Let

When an actual argument list A mathces a form on the first column of the table below, nargs(A) is defined as a another acutal operands set in the corresponding cell on the second column.

A: actual argument list nargs(O): actual argument list
(<<<E1 ... En>>>) <<<F1 ... Fm>>> (<<<nelemprod(E1) ... nelemprod(En)>>><<<nfarg(F1) ... nfarg(Em)>>>)
<<<F1 ... Fm>>> (<<<nfarg(F1) ... nfarg(Em)>>>)

2.3.25. Local call expressions

local_call ::= call
call ::= VERB recv args

Local call expression is used as an alias for the nonterminal local_call.

A local call expression calls a function of the context environment.

Normalization

Let

When a local call expression E matches a form on the first column of the table below, nlcall(E) is defined as an attributional call expression in the corresponding cell on the second column.

E: local call expression nlcall(E): attributional call expression
<<<V>>><<<R>>><<<A>>> \env.<<<V>>><<<nrecv(R)>>><<<nargs(A)>>>

2.3.26. Attributional call expressions

attr_call ::= primary '.' call
call ::= VERB recv args

Attributional call expression is used as an alias for the nonterminal attr_call.

A attributional call expression calls a function of the owner.

Normalization

Let

When an attributional call expression E matches a form on the first column of the table below, nacall(E) is defined as another attributional call expression in the corresponding cell on the second column.

E: attributional call expression nacall(E): attributional call expression
<<<P>>>.<<<V>>><<<R>>><<<A>>> <<<nprimary(P)>>>.<<<V>>><<<nrecv(R)>>><<<nargs(A)>>>

Translation

Let

When an attributional call expression E mathces a form on the first column of the table below, tacall(E) is defined as an instruction series in the corresponding cell on the second column.

E: attributional call expression tacall(E): instruction series
<<<P>>>.<<<V>>>[<<<R>>>](<<<B>>>) <<<texp(P)>>>; <<<texp(R)>>>; flip; <<<tlbody(B)>>>; flip; deref <<<V>>>; call
<<<P>>>.<<<V>>>(<<<B>>>) <<<texp(P)>>>; dup; <<<tlbody(B)>>>; flip; deref <<<V>>>; call

2.3.27. Operator expressions

Operator expressions are syntax sugar for other attributional call expressions.

Here is the list of operators.

Priority Operators Associativity
Lowest =, ||=, &&=, |=, ^=, &=, <<=, >>=, +=, -=, *=, /=, //=, %=, **= Non-associative
  || Right-associative
  && Right-associative
  ==, !=, <, >, <=, >=, <=> Non-associative
  .., ..<, <.., <..< Non-associative
  |, ^ Left-associative
  & Left-associative
  <<, >> Left-associative
  +, - Left-associative
  *, /, //, % Left-associative
  ** Right-associative
Highest -, !, - Unary

2.3.27.1. Assignment operator expressions

assign_op ::= logor_op
            | logor_op '=' logor_op
            | logor_op '||=' logor_op
            | logor_op '&&=' logor_op
            | logor_op '|=' logor_op
            | logor_op '^=' logor_op
            | logor_op '&=' logor_op
            | logor_op '<<=' logor_op
            | logor_op '>>=' logor_op
            | logor_op '+=' logor_op
            | logor_op '-=' logor_op
            | logor_op '*=' logor_op
            | logor_op '/=' logor_op
            | logor_op '//=' logor_op
            | logor_op '%=' logor_op
            | logor_op '**=' logor_op

Assignment operator expression is used as an alias for the nonterminal assign_op.

An assignment operator expression calls a function, typically for assigning.

Normalization

Let

When an assignment operator expression E matches a form on the first column of the table below, nassign(E) is defined as an attributional call expression in the corresponding cell on the second column.

E: assignment operator expressions nassign(E): attributional call expression
<<<X>>> <<<nlogor(X)>>>
<<<X>>> = <<<Y>>> <<<nlogor(X)>>>.op_set(<<<nlogor(Y)>>>)
<<<X>>> ||= <<<Y>>> <<<nlogor(X)>>>.op_logor_set(\env.{ -> <<<nlogor(Y)>>> })
<<<X>>> &&= <<<Y>>> <<<nlogor(X)>>>.op_logand_set(\env.{ -> <<<nlogor(Y)>>> })
<<<X>>> |= <<<Y>>> <<<nlogor(X)>>>.op_or_set(<<<nlogor(Y)>>>)
<<<X>>> ^= <<<Y>>> <<<nlogor(X)>>>.op_xor_set(<<<nlogor(Y)>>>)
<<<X>>> &= <<<Y>>> <<<nlogor(X)>>>.op_and_set(<<<nlogor(Y)>>>)
<<<X>>> <<= <<<Y>>> <<<nlogor(X)>>>.op_shl_set(<<<nlogor(Y)>>>)
<<<X>>> >>= <<<Y>>> <<<nlogor(X)>>>.op_shr_set(<<<nlogor(Y)>>>)
<<<X>>> += <<<Y>>> <<<nlogor(X)>>>.op_add_set(<<<nlogor(Y)>>>)
<<<X>>> -= <<<Y>>> <<<nlogor(X)>>>.op_sub_set(<<<nlogor(Y)>>>)
<<<X>>> *= <<<Y>>> <<<nlogor(X)>>>.op_mul_set(<<<nlogor(Y)>>>)
<<<X>>> /= <<<Y>>> <<<nlogor(X)>>>.op_div_set(<<<nlogor(Y)>>>)
<<<X>>> //= <<<Y>>> <<<nlogor(X)>>>.op_intdiv_set(<<<nlogor(Y)>>>)
<<<X>>> %= <<<Y>>> <<<nlogor(X)>>>.op_rem_set(<<<nlogor(Y)>>>)
<<<X>>> **= <<<Y>>> <<<nlogor(X)>>>.op_pow_set(<<<nlogor(Y)>>>)

2.3.27.2. Logical or oeprator expressions

logor_op ::= logand_op
           | logand_op '||' logor_op

Logical or operator expression is used as an alias for the nonterminal logor_op.

A logical or operator expression calls a function, typically for the logical or operation.

Normalization

Let

When a logical or operator expression E takes a form on the first column on the table below, nlogor(E) is defined as an attributional call expression in the corresponding cell on the second column.

E: logical or operator expression nlogor(E): attributional call expression
<<<X>>> <<<nlogand(X)>>>
<<<X>>> || <<<Y>>> <<<nlogand(X)>>>.op_logor(\env.{ -> <<<nlogor(Y)>>> })

2.3.27.3. Logical and operator expressions

logand_op ::= relation_op
            | relation_op '&&' logand_op

Logical and operator expression is used as an alias for the nonterminal logand_op.

A logical and operator expression calls a function, typically for the logical and operation.

Normalization

Let

When a logical and operator expression E takes a form on the first column of the table below, nlogand(E) is defined as an attributional call expression in the corresponding cell on the second column.

E: logical and operator expression nlogand(E): attributional call expression
<<<X>>> <<<nrel(X)>>>
<<<X>>> && <<<Y>>> <<<nrel(X)>>>.op_logand(\env.{ -> <<<nlogand(Y)>>> })

2.3.27.4. Relationship operator expressions

relation_op ::= range_op
              | range_op '==' range_op
              | range_op '!=' range_op
              | range_op '<' range_op
              | range_op '>' range_op
              | range_op '<=' range_op
              | range_op '>=' range_op
              | range_op '<=>' range_op

Relationship operator expression is used as an alias for the nonterminal relation_op.

A relationship operator expression calls a function, typically for relationship operations.

Normalization

Let

When a relationship operator expression E matches a form on the first column of the table below, nrel(E) is defined as an attributional call expression in the corresponding cell on the second column.

E: relationship operator expression nrel(E): attributional call expression
<<<X>>> <<<nrange(X)>>>
<<<X>>> == <<<Y>>> <<<nrange(X)>>>.op_eq(<<<nrange(Y)>>>)
<<<X>>> != <<<Y>>> <<<nrange(X)>>>.op_ne(<<<nrange(Y)>>>)
<<<X>>> < <<<Y>>> <<<nrange(X)>>>.op_lt(<<<nrange(Y)>>>)
<<<X>>> > <<<Y>>> <<<nrange(X)>>>.op_gt(<<<nrange(Y)>>>)
<<<X>>> <= <<<Y>>> <<<nrange(X)>>>.op_le(<<<nrange(Y)>>>)
<<<X>>> >= <<<Y>>> <<<nrange(X)>>>.op_ge(<<<nrange(Y)>>>)
<<<X>>> <=> <<<Y>>> <<<nrange(X)>>>.op_cmp(<<<nrange(Y)>>>)

2.3.27.5. Range operator expressions

range_op ::= and_op
           | and_op '..' and_op
           | and_op '..<' and_op
           | and_op '<..' and_op
           | and_op '<..<' and_op

Range operator expression is used as an alias for the nonterminal range_op.

A range operator expression calls a function, typically for generating range values.

Normalization

Let

When a range operator expression E matches a form on the first column of the table below, nrange(E) is defined as an attributional call expression in the corresponding cell on the second column.

E: range operator expression nrange(E): attributional call expression
<<<X>>> <<<nor(X)>>>
<<<X>>> .. <<<Y>>> \env.op_range_ii(<<<nor(X)>>> <<<nor(Y)>>>)
<<<X>>> ..< <<<Y>>> \env.op_range_ie(<<<nor(X)>>> <<<nor(Y)>>>)
<<<X>>> <.. <<<Y>>> \env.op_range_ei(<<<nor(X)>>> <<<nor(Y)>>>)
<<<X>>> <..< <<<Y>>> \env.op_range_ee(<<<nor(X)>>> <<<nor(Y)>>>)

2.3.27.6. Bitwise or operator expressions

or_op ::= and_op
        | or_op '|' and_op
        | or_op '^' and_op

Bitwise or operator expression is used as an alias for the nonterminal or_op.

A bitwise or operator expression calls a function, typically for the bitwise or/xor operations.

Normalization

Let

A bitwise or operator expression E matches a form on the first column of the table below, nor(E) is defined as an attributional call expression in the corresponding cell on the second column.

E: bitwise or operator expression nor(E): attributional call expression
<<<Y>>> <<<nand(Y)>>>
<<<X>>> | <<<Y>>> <<<nor(X)>>>.op_or(<<<nand(Y)>>>)
<<<X>>> ^ <<<Y>>> <<<nor(X)>>>.op_xor(<<<nand(Y)>>>)

2.3.27.7. Bitwise and operator expressions

and_op ::= shift_op
         | and_op '&' shift_op

Bitwise and operator expression is used as an alias for the nonterminal and_op.

A bitwise and operator expression calls a function, typically for the bitwise and operation.

Normalization

Let

When a bitwise and operator expression E matches a form on the first column of the table, nand(E) is defined as an attributional call expression in the corresponding cell on the second column.

E: bitwise and operator expression nand(E): attributional call expression
<<<Y>>> <<<nshift(Y)>>>
<<<X>>> & <<<Y>>> <<<nand(X)>>>.op_and(<<<nshift(Y)>>>)

2.3.27.8. Bit shift operator expressions

shift_op ::= add_op
           | shift_op '<<' add_op
           | shift_op '>>' add_op

Bit shift operator expression is used as an alias for the nonterminal shift_op.

A bit shift operator expression calls a function, typically for bit shift operations.

Normalization

Let

When a bit shift operator expression E takes a form on the first column of the table below, nshift(E) is defined as an attributional call expression in the corresponding cell on the second column.

E: bit shift operator expression nshift(E): attributional call expression
<<<Y>>> <<<nadd(Y)>>>
<<<X>>> << <<<Y>>> <<<nshift(X)>>>.op_shl(<<<nadd(Y)>>>)
<<<X>>> >> <<<Y>>> <<<nshift(X)>>>.op_shr(<<<nadd(Y)>>>)

2.3.27.9. Additive operator expressions

add_op ::= multiply_op
         | add_op '+' multiply_op
         | add_op '-' multiply_op

Additive operator expression is used as an alias for the nonterminal add_op.

An additive operator expression calls a function, typically for the additive/subtractive operations.

Normalization

Let

When an additive operator expression E matches a form on the first column of the table below, nadd(E) is defined as an attributional call expression in the corresponding cell on the second column.

E: additive operator expression nadd(E): attributional call expression
<<<Y>>> <<<nmul(Y)>>>
<<<X>>> + <<<Y>>> <<<nadd(X)>>>.op_add(<<<nmul(Y)>>>)
<<<X>>> - <<<Y>>> <<<nadd(X)>>>.op_sub(<<<nmul(Y)>>>)

2.3.27.10. Multiplicative operator expressions

multiply_op ::= power_op
              | multiply_op '*' power_op
              | multiply_op '/' power_op
              | multiply_op '//' power_op
              | multiply_op '%' power_op

Multiplicative operator expression is used as an alias for the nonterminal multiply_op.

A multiplicative operator expression calls a function, typically for the multiplicative/division operations.

Normalization

Let

When a multiplicative operator expression E matches a form on the first column of the table, nmul(E) is defined as an attributional call expression in the corresponding cell on the second column.

E: multiplicative operator expression nadd(E): attributional call expression
<<<Y>>> <<<npow(Y)>>>
<<<X>>> * <<<Y>>> <<<nmul(X)>>>.op_mul(<<<npow(Y)>>>)
<<<X>>> / <<<Y>>> <<<nmul(X)>>>.op_div(<<<npow(Y)>>>)
<<<X>>> // <<<Y>>> <<<nmul(X)>>>.op_intdiv(<<<npow(Y)>>>)
<<<X>>> % <<<Y>>> <<<nmul(X)>>>.op_rem(<<<npow(Y)>>>)

2.3.27.11. Power operator expressions

power_op ::= unary_op
           | unary_op '**' power_op

Power operator expression is used as an alias for the nonterminal power_op.

A power operator expression calls a function, typically for the power operation.

Normalization

Let

When a power operator expression E matches a form on the first column of the table below, npow(E) is defined as an attributional call expression in the corresponding cell on the second column.

E: power operator expression npow(E): attributional call expression
<<<X>>> <<<nunary(X)>>>
<<<X>>> ** <<<Y>>> <<<nunary(X)>>>.op_pow(<<<npow(Y)>>>)

2.3.27.12. Unary operator expressions

unary_op ::= primary
           | '-' unary_op
           | '!' unary_op
           | '~' unary_op

Unary operator expression is used as an alias for the nonterminal unary_op.

An unary operator expression calls a function, typically for unary operations.

Normalization

Let

  • P be a primary expression and U is an unary operator expression.

When an unary operator expression E takes a form on the first column of the table below, nunary(E) is defined as an attributional call expression in the corresponding cell on the second column.

E: unary operator expression nunary(E): attributional call expression
<<<P>>> <<<nprimary(P)>>>
- <<<U>>> <<<nunary(U)>>>.op_minus()
! <<<U>>> <<<nunary(U)>>>.op_lognot()
~ <<<U>>> <<<nunary(U)>>>.op_not()

目次

前のトピックへ

2.2. Syntax

次のトピックへ

2.4. Kink Stack Machine (KSM)

このページ