| 1 | --
|
|---|
| 2 | -- Copyright (c) 2011 Jiri Svoboda
|
|---|
| 3 | -- All rights reserved.
|
|---|
| 4 | --
|
|---|
| 5 | -- Redistribution and use in source and binary forms, with or without
|
|---|
| 6 | -- modification, are permitted provided that the following conditions
|
|---|
| 7 | -- are met:
|
|---|
| 8 | --
|
|---|
| 9 | -- o Redistributions of source code must retain the above copyright
|
|---|
| 10 | -- notice, this list of conditions and the following disclaimer.
|
|---|
| 11 | -- o Redistributions in binary form must reproduce the above copyright
|
|---|
| 12 | -- notice, this list of conditions and the following disclaimer in the
|
|---|
| 13 | -- documentation and/or other materials provided with the distribution.
|
|---|
| 14 | -- o The name of the author may not be used to endorse or promote products
|
|---|
| 15 | -- derived from this software without specific prior written permission.
|
|---|
| 16 | --
|
|---|
| 17 | -- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|---|
| 18 | -- IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|---|
| 19 | -- OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|---|
| 20 | -- IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|---|
| 21 | -- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|---|
| 22 | -- NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|---|
| 23 | -- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|---|
| 24 | -- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|---|
| 25 | -- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|---|
| 26 | -- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|---|
| 27 | --
|
|---|
| 28 |
|
|---|
| 29 | --- Switch statement demo.
|
|---|
| 30 | --
|
|---|
| 31 | -- This demonstrates the switch statement. The switch statement looks like:
|
|---|
| 32 | --
|
|---|
| 33 | -- switch <s_expr> is
|
|---|
| 34 | -- when <e1> [, <e2> ...] do
|
|---|
| 35 | -- <statements1>
|
|---|
| 36 | -- when <f1> [, <f2> ...] do
|
|---|
| 37 | -- <statements2>
|
|---|
| 38 | -- [...]
|
|---|
| 39 | -- [else do
|
|---|
| 40 | -- <statements3>]
|
|---|
| 41 | -- end
|
|---|
| 42 | --
|
|---|
| 43 | -- It is mostly equivalent to the pseudocode:
|
|---|
| 44 | --
|
|---|
| 45 | -- var v : <type of s_expr>;
|
|---|
| 46 | -- if v == <e1> [or v == <e2> ...] then
|
|---|
| 47 | -- <statements1>
|
|---|
| 48 | -- elif v == <f1> [ or v == <f2> ...] then
|
|---|
| 49 | -- <statements2>
|
|---|
| 50 | -- [...]
|
|---|
| 51 | -- [else
|
|---|
| 52 | -- <statements3>]
|
|---|
| 53 | -- end
|
|---|
| 54 | --
|
|---|
| 55 | -- This means there is no artificial limitation as to what you can switch
|
|---|
| 56 | -- on. The expressions don't have to be constant and they can be of any type
|
|---|
| 57 | -- as long as the switch expression (<s_expr>) can be compared with each
|
|---|
| 58 | -- of the when expressions (<e1>, <e2>, <f1>, <f2>, ...).
|
|---|
| 59 | --
|
|---|
| 60 | -- Note however, the 'or' here denotes short-circuit evaluation. (Currently
|
|---|
| 61 | -- the 'or' operation does not use short-circuit evaluation, but that's
|
|---|
| 62 | -- more of a bug than a feature.
|
|---|
| 63 | --
|
|---|
| 64 | class SwitchDemo is
|
|---|
| 65 | class A is
|
|---|
| 66 | end
|
|---|
| 67 |
|
|---|
| 68 | var a1 : A, static;
|
|---|
| 69 | var a2 : A, static;
|
|---|
| 70 | var a3 : A, static;
|
|---|
| 71 | var a4 : A, static;
|
|---|
| 72 |
|
|---|
| 73 | enum MyEnum is
|
|---|
| 74 | red;
|
|---|
| 75 | green;
|
|---|
| 76 | blue;
|
|---|
| 77 | black;
|
|---|
| 78 | cyan;
|
|---|
| 79 | end
|
|---|
| 80 |
|
|---|
| 81 | -- Switch on boolean value
|
|---|
| 82 | fun SwitchBool(v : bool) : string, static is
|
|---|
| 83 | switch v is
|
|---|
| 84 | when false do
|
|---|
| 85 | return "false";
|
|---|
| 86 | when true do
|
|---|
| 87 | return "true";
|
|---|
| 88 | end
|
|---|
| 89 | end
|
|---|
| 90 |
|
|---|
| 91 | -- Switch on char value
|
|---|
| 92 | fun SwitchChar(v : char) : string, static is
|
|---|
| 93 | switch v is
|
|---|
| 94 | when 'a', 'b' do
|
|---|
| 95 | return "a/b";
|
|---|
| 96 | when 'c', 'd' do
|
|---|
| 97 | return "c/d";
|
|---|
| 98 | else do
|
|---|
| 99 | return "<other>";
|
|---|
| 100 | end
|
|---|
| 101 | end
|
|---|
| 102 |
|
|---|
| 103 | -- Switch on integer value
|
|---|
| 104 | fun SwitchInt(v : int) : string, static is
|
|---|
| 105 | switch v is
|
|---|
| 106 | when 0, 1 do
|
|---|
| 107 | return "0/1";
|
|---|
| 108 | when 2, 3 do
|
|---|
| 109 | return "2/3";
|
|---|
| 110 | else do
|
|---|
| 111 | return "<other>";
|
|---|
| 112 | end
|
|---|
| 113 | end
|
|---|
| 114 |
|
|---|
| 115 | -- Switch on string value
|
|---|
| 116 | fun SwitchString(v : string) : string, static is
|
|---|
| 117 | switch v is
|
|---|
| 118 | when "foo", "bar" do
|
|---|
| 119 | return "foo/bar";
|
|---|
| 120 | when "hello", "world" do
|
|---|
| 121 | return "hello/world";
|
|---|
| 122 | else do
|
|---|
| 123 | return "<other>";
|
|---|
| 124 | end
|
|---|
| 125 | end
|
|---|
| 126 |
|
|---|
| 127 | -- Switch on object reference
|
|---|
| 128 | fun SwitchObj(v : A) : string, static is
|
|---|
| 129 | switch v is
|
|---|
| 130 | when a1, a2 do
|
|---|
| 131 | return "a1/a2";
|
|---|
| 132 | when a3, a4 do
|
|---|
| 133 | return "a3/a4";
|
|---|
| 134 | else do
|
|---|
| 135 | return "<other>";
|
|---|
| 136 | end
|
|---|
| 137 | end
|
|---|
| 138 |
|
|---|
| 139 | -- Switch on object reference
|
|---|
| 140 | fun SwitchEnum(v : MyEnum) : string, static is
|
|---|
| 141 | switch v is
|
|---|
| 142 | when MyEnum.red, MyEnum.green do
|
|---|
| 143 | return "red/green";
|
|---|
| 144 | when MyEnum.blue, MyEnum.black do
|
|---|
| 145 | return "blue/black";
|
|---|
| 146 | else do
|
|---|
| 147 | return "<other>";
|
|---|
| 148 | end
|
|---|
| 149 | end
|
|---|
| 150 |
|
|---|
| 151 | fun Test(res : string; test_expr : string; expected : string), static is
|
|---|
| 152 | Console.WriteLine(test_expr + " = '" + res + "' (expected '" +
|
|---|
| 153 | expected + "')");
|
|---|
| 154 | if res != expected then
|
|---|
| 155 | Console.WriteLine("Error: Got unexpected result.");
|
|---|
| 156 | raise new Error.Base();
|
|---|
| 157 | end
|
|---|
| 158 | end
|
|---|
| 159 |
|
|---|
| 160 | fun Main(), static is
|
|---|
| 161 | a1 = new A();
|
|---|
| 162 | a2 = new A();
|
|---|
| 163 | a3 = new A();
|
|---|
| 164 | a4 = new A();
|
|---|
| 165 |
|
|---|
| 166 | Test(SwitchBool(false), "SwitchBool(false)", "false");
|
|---|
| 167 | Test(SwitchBool(true), "SwitchBool(true)", "true");
|
|---|
| 168 |
|
|---|
| 169 | Test(SwitchChar('a'), "SwitchChar('a')", "a/b");
|
|---|
| 170 | Test(SwitchChar('b'), "SwitchChar('b')", "a/b");
|
|---|
| 171 | Test(SwitchChar('c'), "SwitchChar('c')", "c/d");
|
|---|
| 172 | Test(SwitchChar('d'), "SwitchChar('d')", "c/d");
|
|---|
| 173 | Test(SwitchChar('e'), "SwitchChar('e')", "<other>");
|
|---|
| 174 |
|
|---|
| 175 | Test(SwitchInt(0), "SwitchInt(0)", "0/1");
|
|---|
| 176 | Test(SwitchInt(1), "SwitchInt(1)", "0/1");
|
|---|
| 177 | Test(SwitchInt(2), "SwitchInt(2)", "2/3");
|
|---|
| 178 | Test(SwitchInt(3), "SwitchInt(3)", "2/3");
|
|---|
| 179 | Test(SwitchInt(4), "SwitchInt(4)", "<other>");
|
|---|
| 180 |
|
|---|
| 181 | Test(SwitchString("foo"), "SwitchString('foo')", "foo/bar");
|
|---|
| 182 | Test(SwitchString("bar"), "SwitchString('bar')", "foo/bar");
|
|---|
| 183 | Test(SwitchString("hello"), "SwitchString('hello')", "hello/world");
|
|---|
| 184 | Test(SwitchString("world"), "SwitchString('world')", "hello/world");
|
|---|
| 185 | Test(SwitchString("boom"), "SwitchString('boom')", "<other>");
|
|---|
| 186 |
|
|---|
| 187 | Test(SwitchObj(a1), "SwitchObj(a1)", "a1/a2");
|
|---|
| 188 | Test(SwitchObj(a2), "SwitchObj(a2)", "a1/a2");
|
|---|
| 189 | Test(SwitchObj(a3), "SwitchObj(a3)", "a3/a4");
|
|---|
| 190 | Test(SwitchObj(a4), "SwitchObj(a4)", "a3/a4");
|
|---|
| 191 | Test(SwitchObj(nil), "SwitchObj(nil)", "<other>");
|
|---|
| 192 |
|
|---|
| 193 | Test(SwitchEnum(MyEnum.red), "SwitchEnum(MyEnum.red)", "red/green");
|
|---|
| 194 | Test(SwitchEnum(MyEnum.green), "SwitchEnum(MyEnum.green)", "red/green");
|
|---|
| 195 | Test(SwitchEnum(MyEnum.blue), "SwitchEnum(MyEnum.blue)", "blue/black");
|
|---|
| 196 | Test(SwitchEnum(MyEnum.black), "SwitchEnum(MyEnum.black)", "blue/black");
|
|---|
| 197 | Test(SwitchEnum(MyEnum.cyan), "SwitchEnum(MyEnum.cyan)", "<other>");
|
|---|
| 198 | end
|
|---|
| 199 | end
|
|---|