cannam@133
|
1 # Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
|
cannam@133
|
2 # Licensed under the MIT License:
|
cannam@133
|
3 #
|
cannam@133
|
4 # Permission is hereby granted, free of charge, to any person obtaining a copy
|
cannam@133
|
5 # of this software and associated documentation files (the "Software"), to deal
|
cannam@133
|
6 # in the Software without restriction, including without limitation the rights
|
cannam@133
|
7 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
cannam@133
|
8 # copies of the Software, and to permit persons to whom the Software is
|
cannam@133
|
9 # furnished to do so, subject to the following conditions:
|
cannam@133
|
10 #
|
cannam@133
|
11 # The above copyright notice and this permission notice shall be included in
|
cannam@133
|
12 # all copies or substantial portions of the Software.
|
cannam@133
|
13 #
|
cannam@133
|
14 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
cannam@133
|
15 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
cannam@133
|
16 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
cannam@133
|
17 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
cannam@133
|
18 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
cannam@133
|
19 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
cannam@133
|
20 # THE SOFTWARE.
|
cannam@133
|
21
|
cannam@133
|
22 @0x85150b117366d14b;
|
cannam@133
|
23
|
cannam@133
|
24 interface Calculator {
|
cannam@133
|
25 # A "simple" mathematical calculator, callable via RPC.
|
cannam@133
|
26 #
|
cannam@133
|
27 # But, to show off Cap'n Proto, we add some twists:
|
cannam@133
|
28 #
|
cannam@133
|
29 # - You can use the result from one call as the input to the next
|
cannam@133
|
30 # without a network round trip. To accomplish this, evaluate()
|
cannam@133
|
31 # returns a `Value` object wrapping the actual numeric value.
|
cannam@133
|
32 # This object may be used in a subsequent expression. With
|
cannam@133
|
33 # promise pipelining, the Value can actually be used before
|
cannam@133
|
34 # the evaluate() call that creates it returns!
|
cannam@133
|
35 #
|
cannam@133
|
36 # - You can define new functions, and then call them. This again
|
cannam@133
|
37 # shows off pipelining, but it also gives the client the
|
cannam@133
|
38 # opportunity to define a function on the client side and have
|
cannam@133
|
39 # the server call back to it.
|
cannam@133
|
40 #
|
cannam@133
|
41 # - The basic arithmetic operators are exposed as Functions, and
|
cannam@133
|
42 # you have to call getOperator() to obtain them from the server.
|
cannam@133
|
43 # This again demonstrates pipelining -- using getOperator() to
|
cannam@133
|
44 # get each operator and then using them in evaluate() still
|
cannam@133
|
45 # only takes one network round trip.
|
cannam@133
|
46
|
cannam@133
|
47 evaluate @0 (expression :Expression) -> (value :Value);
|
cannam@133
|
48 # Evaluate the given expression and return the result. The
|
cannam@133
|
49 # result is returned wrapped in a Value interface so that you
|
cannam@133
|
50 # may pass it back to the server in a pipelined request. To
|
cannam@133
|
51 # actually get the numeric value, you must call read() on the
|
cannam@133
|
52 # Value -- but again, this can be pipelined so that it incurs
|
cannam@133
|
53 # no additional latency.
|
cannam@133
|
54
|
cannam@133
|
55 struct Expression {
|
cannam@133
|
56 # A numeric expression.
|
cannam@133
|
57
|
cannam@133
|
58 union {
|
cannam@133
|
59 literal @0 :Float64;
|
cannam@133
|
60 # A literal numeric value.
|
cannam@133
|
61
|
cannam@133
|
62 previousResult @1 :Value;
|
cannam@133
|
63 # A value that was (or, will be) returned by a previous
|
cannam@133
|
64 # evaluate().
|
cannam@133
|
65
|
cannam@133
|
66 parameter @2 :UInt32;
|
cannam@133
|
67 # A parameter to the function (only valid in function bodies;
|
cannam@133
|
68 # see defFunction).
|
cannam@133
|
69
|
cannam@133
|
70 call :group {
|
cannam@133
|
71 # Call a function on a list of parameters.
|
cannam@133
|
72 function @3 :Function;
|
cannam@133
|
73 params @4 :List(Expression);
|
cannam@133
|
74 }
|
cannam@133
|
75 }
|
cannam@133
|
76 }
|
cannam@133
|
77
|
cannam@133
|
78 interface Value {
|
cannam@133
|
79 # Wraps a numeric value in an RPC object. This allows the value
|
cannam@133
|
80 # to be used in subsequent evaluate() requests without the client
|
cannam@133
|
81 # waiting for the evaluate() that returns the Value to finish.
|
cannam@133
|
82
|
cannam@133
|
83 read @0 () -> (value :Float64);
|
cannam@133
|
84 # Read back the raw numeric value.
|
cannam@133
|
85 }
|
cannam@133
|
86
|
cannam@133
|
87 defFunction @1 (paramCount :Int32, body :Expression)
|
cannam@133
|
88 -> (func :Function);
|
cannam@133
|
89 # Define a function that takes `paramCount` parameters and returns the
|
cannam@133
|
90 # evaluation of `body` after substituting these parameters.
|
cannam@133
|
91
|
cannam@133
|
92 interface Function {
|
cannam@133
|
93 # An algebraic function. Can be called directly, or can be used inside
|
cannam@133
|
94 # an Expression.
|
cannam@133
|
95 #
|
cannam@133
|
96 # A client can create a Function that runs on the server side using
|
cannam@133
|
97 # `defFunction()` or `getOperator()`. Alternatively, a client can
|
cannam@133
|
98 # implement a Function on the client side and the server will call back
|
cannam@133
|
99 # to it. However, a function defined on the client side will require a
|
cannam@133
|
100 # network round trip whenever the server needs to call it, whereas
|
cannam@133
|
101 # functions defined on the server and then passed back to it are called
|
cannam@133
|
102 # locally.
|
cannam@133
|
103
|
cannam@133
|
104 call @0 (params :List(Float64)) -> (value :Float64);
|
cannam@133
|
105 # Call the function on the given parameters.
|
cannam@133
|
106 }
|
cannam@133
|
107
|
cannam@133
|
108 getOperator @2 (op :Operator) -> (func :Function);
|
cannam@133
|
109 # Get a Function representing an arithmetic operator, which can then be
|
cannam@133
|
110 # used in Expressions.
|
cannam@133
|
111
|
cannam@133
|
112 enum Operator {
|
cannam@133
|
113 add @0;
|
cannam@133
|
114 subtract @1;
|
cannam@133
|
115 multiply @2;
|
cannam@133
|
116 divide @3;
|
cannam@133
|
117 }
|
cannam@133
|
118 }
|