├── Calculator.md ├── CodeGen.md ├── LICENSE ├── README.md └── TOC.md /Calculator.md: -------------------------------------------------------------------------------- 1 | # Calculator Language 2 | 3 | > A compiler is just a staged definitional interpreter. What's the problem? 4 | 5 | Don't worry about the above quote. Let's design a programming language, and write a compiler for it! 6 | 7 | ## Design 8 | 9 | What should the language look like? 10 | 11 | JSON. To be precise, the source code of the program is a JSON file. By doing so, we do not need to parse the program from a textual format - it is already done. Even though parsing makes your program look nice (because it is not in JSON), and parsing is deep and useful knowledge, we will completely skip parsing: it is very complex, and if we talk about it, we will spend most of our time talking about it, leaving little time for everything else. 12 | 13 | OK. What feature should it have? 14 | 15 | Almost none. The more features a language has, the harder it is to design and implement. To ease such a task, we will be doing, essentially, agile development. We will design and implement a simple language, refactor the code, add more features to the language, and repeat. This way, the learning curve will be smoother, and you get to see the conflict between different programming language features, and the conflict between performance and expressivity, as the language evolves. 16 | 17 | ## Language Definition 18 | 19 | Our language is so simple that your (non-scientific) calculator will laugh at it. It has exactly three features: number (an integer), plus (add two numbers), and multiply (time two numbers). 20 | 21 | Now we have to specify the JSON format for our program. 22 | 23 | For a number x, the format is `{type: "Literal", value: x}`. 24 | For a + b, the format is `{type: "Plus", left: a, right: b}`. 25 | For a * b, the format is `{type: "Multiply", left: a, right: b}`. 26 | 27 | As an example, (1 + 2) * (3 + 4) is written as 28 | 29 | {type: "Multiply", 30 | left: {type: "Plus", 31 | left: {type: "Literal", value: 1}, 32 | right: {type: "Literal", value: 2}}, 33 | right: {type: "Plus", 34 | left: {type: "Literal", value: 3}, 35 | right: {type: "Literal", value: 4}}} 36 | 37 | What a pain in the ass. Even though we don't have a parser, we can still write a pretty printer: it outputs the code in a prettier, actually human-readable format. 38 | 39 | ## Pretty Print 40 | 41 | We will write it in Java, cause everyone knows Java. I am gonna code it with you, step by step. This is like pair programming. 42 | 43 | static String prettyPrint(JSONObject json) { 44 | throw new RuntimeException("..."); 45 | }; 46 | 47 | We start by getting the 'type' field from the JSON, and see which case it is: 48 | 49 | static String prettyPrint(JSONObject j) { 50 | String type = j.getString("type"); 51 | return switch (type) { 52 | case "Literal" -> throw new RuntimeException("..."); 53 | case "Plus" -> throw new RuntimeException("..."); 54 | case "Multiply" -> throw new RuntimeException("..."); 55 | default -> throw new RuntimeException("Unexpected: " + type); 56 | }; 57 | 58 | Literal is easy - we just print the value: 59 | 60 | case "Literal" -> String.valueOf(j.getInt("value")); 61 | 62 | Unlike Literal, Plus and Multiply contain more JSON as children, in the left and right fields, which we have to handle by calling prettyPrint() again - recursion! 63 | 64 | case "Plus" -> "(" + prettyPrint(j.getJSONObject("left")) + 65 | "+" + prettyPrint(j.getJSONObject("right")) + ")"; 66 | case "Multiply" -> "(" + prettyPrint(j.getJSONObject("left")) + 67 | "*" + prettyPrint(j.getJSONObject("right")) + ")"; 68 | 69 | Now calling prettyPrint() on our example return "((1+2)*(3+4))". Look pretty neat. 70 | 71 | ## Evaluate 72 | 73 | Moving on to the evaluator, which takes a JSON, and returns an Int: 74 | 75 | static int evaluate(JSONObject j) { 76 | throw new RuntimeException("..."); 77 | } 78 | 79 | Get the type and match on it... 80 | 81 | static int evaluate(JSONObject j) { 82 | String type = j.getString("type"); 83 | return switch (type) { 84 | case "Literal" -> throw new RuntimeException("..."); 85 | case "Plus" -> throw new RuntimeException("..."); 86 | case "Multiply" -> throw new RuntimeException("..."); 87 | default -> throw new RuntimeException("Unexpected value: " + type); 88 | }; 89 | } 90 | 91 | Handle the base case (no recursion, simple)... 92 | 93 | case "Literal" -> j.getInt("value"); 94 | 95 | Handle the recursive case (recurse into the children, and combine the result)... 96 | 97 | case "Plus" -> evaluate(j.getJSONObject("left")) + evaluate(j.getJSONObject("right")); 98 | case "Multiply" -> evaluate(j.getJSONObject("left")) * evaluate(j.getJSONObject("right")); 99 | 100 | If you compare evaluate() to prettyPrint(), you will find that they are almost the same! The biggest difference is that one of them has + as an operator that adds two Int, and one of them has + as "+" the string. 101 | 102 | This is not a coincidence. Think about how we can process program in our calculator language: 103 | - Given a program in the JSON format, we must retrieve its type so we can work on it 104 | - For the base case, we can immediately return the correct value 105 | - For the recursive case, we have to handle the children by recursing 106 | 107 | Without any of the three steps, the program is incorrect, and cannot be fixed without essentially re-introducing it. This pattern is thus universal: you will see it again, a lot. 108 | 109 | ## Meta-Language, Object-Language, and the Definitional Interpreter 110 | Let's step back and reflect on what we had done: in less than 10 lines of code, we had implemented an Interpreter! What is the magic? Before I answer this question, some terminology: when we use a program X to manipulate another program Y, the language X is in, is called the metalanguage, and Y's language is the objectlanguage. 111 | A definitional interpreter is when we use metalanguage's feature to implement the corresponding objectlanguage's feature. In this case, evaluate() is a definitional interpreter, because we use Java's Int to implement Calculator's Int. Definitional interpreters are known for their simplicity because they essentially do nothing. 112 | 113 | However, despite doing nothing, they are very useful. The most straightforward and popular use of a definitional interpreter is to give new syntax or to provide eval(), for already-existing features, also known as inventing a novel programming language. We could take a definitional interpreter, and add a new language feature that we actually implement. We could also take a definitional interpreter, add some print to every case, and now we had a tracing debugger. Or, as the quote at the beginning of the chapter dictate, a compiler is also a definitional interpreter but slightly modified. Essentially, a definitional interpreter is a solid foundation, allowing you to make a bunch of modifications to it, to get all sorts of useful things. 114 | 115 | ## Refactoring 116 | Manipulating JSON is hard! I have to remember the name and the type of everything, and that sure is tiresome! I am gonna refactor the JSON (JavaScript object) into Java Objects since we are writing Java not JavaScript. 117 | 118 | static class Expr {} 119 | 120 | static class Lit extends Expr { 121 | int val; 122 | 123 | Lit(int val) {this.val = val;} 124 | } 125 | 126 | static class Plus extends Expr { 127 | Expr left, right; 128 | 129 | Plus(Expr left, Expr right) { 130 | this.left = left; 131 | this.right = right; 132 | } 133 | } 134 | 135 | static class Mult extends Expr { // ... 136 | 137 | The class definitions. 138 | 139 | static Expr mkLit(int val) {return new Lit(val);} 140 | 141 | static Expr mkPlus(Expr left, Expr right) {return new Plus(left, right);} 142 | 143 | static Expr mkMult(Expr left, Expr right) {return new Mult(left, right);} 144 | 145 | Some shorthands. 146 | 147 | mkMult(mkPlus(mkLit(1), mkLit(2)), mkPlus(mkLit(3), mkLit(4))); 148 | 149 | Now our example looks much better - it is just a one-liner. 150 | 151 | After the above refactoring, besides the conversion, the JSON is nowhere to be seen - this is expected. From now on, we will simply not talk about JSON, and focus on Expr. Conversion from JSON to Expr can be easily written, by recursing on the JSON object and emitting the corresponding Java object. And we do not even need to work with text, or JSON, to begin with - the above Expr construction is an easy way to test our programs. We can also imagine adding a parser that goes straight from text to Expr later on - we don't have to do it now, our time is better spent focusing on the compiler itself. 152 | 153 | static int eval(Expr expr) { 154 | if (expr instanceof Lit) { 155 | return ((Lit) expr).val; 156 | } else if (expr instanceof Plus) { 157 | return eval(((Plus) expr).left) + eval(((Plus) expr).right); 158 | } else if (expr instanceof Mult) { 159 | return eval(((Mult) expr).left) * eval(((Mult) expr).right); 160 | } else { 161 | throw new RuntimeException("Unexpected value: " + expr.getClass()); 162 | } 163 | } 164 | 165 | We have to now fix the definition for prettyPrint() and evaluate(). While we are at it, let's also move prettyPrint() into Java's toString(), and rename evaluate() into eval(): our code is, and will, remain short and concise. The code for pp(), likewise, is a mechanical transformation, which we will skip presenting. 166 | 167 | One problem with the above code is that it relies heavily on instanceof, and downcasting, which is frowned upon in Java. This could be fixed by making pp() and eval() abstract functions in Expr, and having each subclass override it. 168 | 169 | // In Lit 170 | public String toString() {return String.valueOf(val);} 171 | 172 | int eval() {return val;} 173 | 174 | // In Plus 175 | public String toString() {return "(" + left.toString() + "+" + right.toString() + ")";} 176 | 177 | int eval() {return left.eval() + right.eval();} 178 | 179 | The @override function for Lit and Plus. The case for Mult is almost the same, so I will not show it here. 180 | 181 | Alas, we can't write a compiler yet, as our language is so trivial a compiler is pointless. Let's add some more features. 182 | 183 | ## Input 184 | 185 | Right now our language is really, really boring. It reacts the same (output a constant number) no matter what, while most program behaves differently according to the context. 186 | 187 | The easiest way to do this is to add variables to the language. For now, for the sake of complexity, all variables are defined externally and inputted by the user when the program run. We will add defining and assigning to variables some other times. 188 | 189 | static class Var extends Expr { 190 | String name; 191 | Var(String name) {this.name = name;} 192 | 193 | public String toString() {return name;} 194 | } 195 | 196 | OK. On to eval(). Hmm... 197 | 198 | int eval() { 199 | throw new RuntimeException("..."); 200 | } 201 | 202 | What do I put in here? Seems like we are stuck! For a good reason: we now have unknown variables in our language, but we don't know which value they are. Luckily, they are all user-defined variables, so we can require our user to pass in a Mapping, environment(env) from variable to int. 203 | 204 | // In Expr 205 | abstract int eval(Map env); 206 | 207 | Now our definitions for Lit, Plus, and Mult are broken. We can fix Lit by accepting the env and doing nothing for it. For Plus and Mult, we pass env into the recursive call. 208 | 209 | int eval(Map env) {return env.get(name);} 210 | 211 | Now for Var, we look up the value from the environment. 212 | 213 | Pretty Good! I wrote another example, which multiplies 2 n*n matrices, where n = 2, and add up all the cell in the resulting matrix, into a single number. The code is hidden because it is not too related to what we are doing right now. Running the example on 2 matrices with all cells as 1 will give 8, which is expected. However, printing the matrix will give: 214 | 215 | ((((0+((0+(a_0_0*b_0_0))+(a_0_1*b_1_0)))+((0+(a_0_0*b_0_1))+(a_0_1*b_1 ... 216 | 217 | Urgh. What a mess! Look like there is a bunch of 0 in our program. We can write a function, simp(), just like pp() and eval(), to simplify the input program and remove them. 218 | 219 | ## Simplification 220 | 221 | // In Expr 222 | Expr simp() {return this;} 223 | 224 | The case for Lit and Var is trivial: there is nothing to simplify, so we just `return this;`. In fact, we had moved this code into the base class, Expr, because it is always correct to simplify, by doing nothing! 225 | 226 | Let's get back to programming, and fill out the case for Plus. 227 | 228 | Expr left = this.left.simp(); 229 | Expr right = this.right.simp(); 230 | return mkPlus(left, right); 231 | 232 | We begin by traversing left and right, simplifying them. Note that the above code is universal - we can also do this for the simp() for Mult (of course, we have to change mkPlus into mkMult). This is because if a == and b == y, mkPlus(a, b) == mkPlus(x, y). Even when we have nothing to do for a Node, we can and should still optimize by recursing. This way its children can do its things. Now, onto some real optimization for Plus. 233 | 234 | // After left, right is defined, before mkPlus 235 | if (left.equals(Cal.mkLit(0))) { 236 | return right; 237 | } else if (right.equals(Cal.mkLit(0))) { 238 | return left; 239 | } 240 | 241 | If left or right is 0, we just return the other Expr. Note that I had override equals for all the Expr. I won't show them because they are not interesting, but you can see them in the code. Another case: 242 | 243 | // After left, right is defined, before mkPlus 244 | if (left instanceof Lit && right instanceof Lit) { 245 | return mkLit(((Lit) left).val + ((Lit) right).val); 246 | } 247 | 248 | If left and right are both Lit, we can do our simplification by adding them up. 249 | 250 | The case for Mult is very similar: 251 | 252 | - 0: Recurse on the children 253 | - 1: If both expr is Lit, multiply the val and return a Lit 254 | - 2: If any expr is 0, return 0 255 | - 3: If any expr is 1, return the other expr 256 | - 4: otherwise return mkMult(left, right) 257 | 258 | Now calling example.simp().pp() will give a string of length 126, as opposed to length 146, and we can see, with our eyes, that it is a bit prettier: 259 | 260 | (((((a_0_0*b_0_0)+(a_0_1*b_1_0))+((a_0_0*b_0_1)+(a_0_1*b_1_1)))+((a_1_ ... 261 | 262 | ## Deja Vu 263 | 264 | If we look at our simp(), we will see that it is very much like eval()! If we give it an Expr with no Var in it, it will always return a Lit! And the code that will be executed, in that case, is exactly the code for a definitional Interpreter. This is not a coincidence: the definitional Interpreter is a recurring echo, which we will see multi, multiple times in the book. 265 | 266 | ## Staging 267 | 268 | Ignore the scary title for now. Let's try to make our Interpreter faster. I had increased n from 2 to 4, so we are now multiplying 2 4*4 matrices, and run the eval() in a loop, and profiling the resulting code. 269 | 270 | public static void profileEval(int n, int length) { 271 | Expr example = getExample(n); 272 | Map env = getExampleEnv(n); 273 | for (int i = 0; i < length; ++i) { 274 | example.eval(env); 275 | } 276 | } 277 | 278 | The profiler tells me that most time is spent in `Map.get()`. Why? What is in a Map? 279 | 280 | There are multiple ways to implement a Map from String to Int. The most notable examples are search trees, hash maps, and tries. 281 | However, in order to look up a key, they all need to traverse the String to compare/compute the hash/traverse the trie and look at multiple buckets/nodes to find the value. Looking at multiple places is not good, as it requires multiple memory fetches, which may be a cache miss and stall the pipeline, and it also requires conditional jump, which may fail the branch predictor and require conditional jump. In short - we will like to look only once. If env is an Array, there is fewer cache miss as the values are compactly stored, and there are no failed branch prediction because there is no branch. 282 | 283 | // Inside Expr 284 | abstract int yolo(int[] env); 285 | 286 | We will call our new function yolo because you only look once (into the array). 287 | The change for Lit, Plus, Mult are all mechanical and not shown, but we are stuck on Input again: we don't have a way to go from String name to an index in env! We can fix this, by adding a mapping from String to index as an argument to yolo: 288 | 289 | // In Expr 290 | abstract int yolo(Map loc, int[] env); 291 | // In Var 292 | int yolo(Map loc, int[] env) { 293 | int idx = loc.get(name); 294 | return env[idx]; 295 | } 296 | 297 | How do we turn the old Map env, to a Map loc and int[] env though? We can walk the whole Expr, and put every unique Var into a Map once. 298 | 299 | // In Expr 300 | abstract void locate(Map loc); 301 | // In Var 302 | void locate(Map loc) { 303 | if (!loc.containsKey(name)) { 304 | loc.put(name, loc.size()); 305 | } 306 | } 307 | 308 | The other cases are uninteresting. 309 | 310 | static int[] envToLocEnv(Map env, Map loc) { 311 | int[] arr = new int[loc.size()]; 312 | for (Map.Entry x : loc.entrySet()) { 313 | arr[x.getValue()] = env.get(x.getKey()); 314 | } 315 | return arr; 316 | } 317 | 318 | Now, a function to turn the old Env into the new Env. Now we can profile our code again: 319 | 320 | public static void profileYolo(int n, int length) { 321 | Expr example = getExample(n); 322 | Map env = getExampleEnv(n); 323 | Map loc = new HashMap<>(); 324 | example.locate(loc); 325 | int[] locEnv = envToLocEnv(env, loc) 326 | for (int i = 0; i < length; ++i) { 327 | example.yolo(loc, locEnv); 328 | } 329 | } 330 | 331 | This isn't any faster. Duh - we are still calling .get(name) inside yolo(), but the point is to not call it! Let's take a moment to look at yolo() for Var and think. 332 | 333 | int idx = loc.get(name); 334 | return env[idx]; 335 | 336 | One thing to note is that the code has two lines. One line uses only loc, and one line uses env, alongside the value produced by loc. Furthermore, loc is calculated using Expr only, and env is defined by the user. If we have an Expr, which will be run multiple times, we can execute `int idx = loc.get(name);` only once, store the result, and only execute `return env[idx];` every time we run the Expr. This way, we will spend some time when we get the Expr, to precompute indexes, but then we will be very fast! 337 | 338 | // In Expr 339 | abstract Function again(Map loc); 340 | 341 | We can represent it by a Function returning a Function. The idea is, for the same Expr, we will call again once, but we can call the result multiple times, each time representing a run of the program. 342 | 343 | // In Lit 344 | Function again(Map loc) {return env -> val;} 345 | 346 | The case for Lit is simple. We return a Function, which takes env and ignores it. It is just like the old yolo() function. 347 | 348 | // In Plus 349 | Function again(Map loc) { 350 | Function left = this.left.again(loc); 351 | Function right = this.right.again(loc); 352 | return env -> left.apply(env) + right.apply(env); 353 | } 354 | 355 | In Plus, we recurse, just as always. One important thing to notice in this code: the one-liner 356 | 357 | return env -> left.again(loc).apply(env) + right.again(loc).apply(env); 358 | 359 | is not what we want: every time the inside function is executed, we are calling again() again, but we only want to call again() once. 360 | 361 | // In Var 362 | Function again(Map loc) { 363 | int idx = loc.get(name); 364 | return env -> env[idx]; 365 | } 366 | 367 | The case for Var. The lambda perfectly separates the two worlds - a world where we only have loc, but we can do heavy computation (because it is run once), and a world with env, but we want to execute ASAP (because it is run multiple times). The world is called a stage, and usually, there are two stages: the compile and the run time. 368 | 369 | Wait, compile time? We separate our interpreter into two stages, run one stage once and run the next stage multiple times. A compiler also works in two stages, compiling the program once and executeing it many time. But note that our compiler is very much like our definitional interpreter, eval(), the difference only being splitting lookup into two phases, and the stage separation. This is what "A compiler is just a staged definitional interpreter" mean! Hurray! Now we have a compiler with 20 lines of code! 370 | 371 | Some profiling shows that our code is now about 4x as fast, by removing the hash table lookup at runtime. Some profiling will show that the bottleneck is no longer HashMap or any particular Java library call, but time is instead spent during all the recursive calls. 372 | 373 | ## Code Generation 374 | 375 | What else is there to optimize? To understand this, we have to understand that calling a nonstatic method in Java is somewhat slow, as opposed to e.g. indexing into an array, or doing int addition. Objects, unlike int in an array, are not tightly packed together (on the heap). This means accessing objects takes possibly a few orders of magnitude slower than accessing local variables (on the stack), or sequential access to an array. (And no, putting Objects into an array will not help because they are boxed). Furthermore, calling a nonstatic method will do dynamic dispatch, which requires jumping to an unknown place in the code, which will induce pipeline stall which is also very expensive. 376 | 377 | However, note that in our calculator language, there is no Object, and there is no dynamic dispatch. So, where are they from? We introduced them by calling the Function returned by again(). This is known as the interpretive overhead (A compiler can still have interpretive overhead because an interpreter (in this case, JVM Function) might be used to interpret the compiled result.). 378 | 379 | To combat this, we can, instead of calling the returned value of again(), find a more efficient method to execute it. We start by using a class, LExpr (LocatedExpr), to store the return of again(), now renamed to located: 380 | 381 | abstract static class LExpr { 382 | abstract int eval(int[] env); 383 | } 384 | 385 | located is changed to return anonymous class, instead of an anonymous function: 386 | 387 | LExpr located(Map loc) { 388 | return new LExpr() { 389 | int eval(int[] env) { 390 | return val; 391 | } 392 | }; 393 | } 394 | 395 | OK, back onto the point. What is more efficient than the Java Runtime? The Java Compiler! Instead of turning LExpr into Function, we can turn LExpr into a String, which represents some Java code. We can then compile the java code and execute it. 396 | 397 | // In LExpr 398 | abstract String compile(); 399 | // In Lit.located 400 | String compile() {return String.valueOf(val);} 401 | // In Lit.Plus 402 | String compile() {return "(" + left.compile() + "+" + right.compile() + ")";} 403 | 404 | Huh. Look very familiar... 405 | 406 | String compile() {return "env[" + idx + "]";} 407 | 408 | Isn't this just the code for eval(), our definitional interpreter, only you put it in quotation marks? Precisely. This is called quoting, where we, instead of executing a code, just store the representation of that code, so we can do stuff with it later. Again, note how we are using Java's feature to implement Calculator's feature, only this time, we use the Java compiler instead of the Java runtime. You might recall that this code is also exactly our pp(), which is not a coincidence. PrettyPrinting output a representation of the code, which is also what compile() does as oppose to eval(). With compile() coded up we can execute the code 10x as fast then LExpr's eval() - which, keep in mind, is 4x as fast then Expr's eval. So, we achieve a whooping 40x speedup! 409 | 410 | ## More Refactoring 411 | 412 | The code for Plus and Mult has way, way too much similarity. We can refactor them into an ApplyBinOp class, which has two children, left and right, alongside a BinOp, an abstract class, with the function `abstract int eval(int left, int right)`. The code for Plus and Mult is now merged, with the only difference being they use different BinOp. 413 | 414 | ## Conclusion 415 | 416 | If you want a 1-day intro to compiler, this is it. Stop reading. 417 | This chapter is a microcosm of the whole book: It contains programming language design, evaluation, performance debugging by profiling and reasoning about hardware, optimization, staging, and finally code generation, with all of them interacting with the definitional interpreter. The rest of the book is an extension of all we saw before, only in more depth. 418 | 419 | After all, a compiler isn't a menacing dragon, to be conquered by a knight, but a dragon-friend, whom once you befriend, will be amazed by its beauty. 420 | 421 | ## Challenge 422 | 423 | - 0: rewrite LExpr's compile to generate python code instead of java code. When you do that, of the three languages (Calculator, Java, Python), which are the metalanguage, and which are the objectlanguage? 424 | - 1: Introduce Minus, and Divide, and think about what simp() rules there is. Is `(a + b) - b -> a` a good rule? What about `(a / b) * b -> a` and `(a * b) / b -> a`? How about `a * 2 -> a + a`? Mult is more expensive so we want to do + instead, right? 425 | - 2: look at the code that generates the Expr that represents the sum of the resulting matrix multiplication. Try to understand it, and modify it so it returns the sum of the resulting matrix multiplication, but with each element squared. LExpr.eval() it. Is it about as fast as the code, unchanged, as the bottleneck is in the matrix multiplication, not the squaring/summing? 426 | 427 | -------------------------------------------------------------------------------- /CodeGen.md: -------------------------------------------------------------------------------- 1 | # CodeGen 2 | 3 | 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Creative Commons Legal Code 2 | 3 | CC0 1.0 Universal 4 | 5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 6 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN 7 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 8 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 9 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS 10 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM 11 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED 12 | HEREUNDER. 13 | 14 | Statement of Purpose 15 | 16 | The laws of most jurisdictions throughout the world automatically confer 17 | exclusive Copyright and Related Rights (defined below) upon the creator 18 | and subsequent owner(s) (each and all, an "owner") of an original work of 19 | authorship and/or a database (each, a "Work"). 20 | 21 | Certain owners wish to permanently relinquish those rights to a Work for 22 | the purpose of contributing to a commons of creative, cultural and 23 | scientific works ("Commons") that the public can reliably and without fear 24 | of later claims of infringement build upon, modify, incorporate in other 25 | works, reuse and redistribute as freely as possible in any form whatsoever 26 | and for any purposes, including without limitation commercial purposes. 27 | These owners may contribute to the Commons to promote the ideal of a free 28 | culture and the further production of creative, cultural and scientific 29 | works, or to gain reputation or greater distribution for their Work in 30 | part through the use and efforts of others. 31 | 32 | For these and/or other purposes and motivations, and without any 33 | expectation of additional consideration or compensation, the person 34 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she 35 | is an owner of Copyright and Related Rights in the Work, voluntarily 36 | elects to apply CC0 to the Work and publicly distribute the Work under its 37 | terms, with knowledge of his or her Copyright and Related Rights in the 38 | Work and the meaning and intended legal effect of CC0 on those rights. 39 | 40 | 1. Copyright and Related Rights. A Work made available under CC0 may be 41 | protected by copyright and related or neighboring rights ("Copyright and 42 | Related Rights"). Copyright and Related Rights include, but are not 43 | limited to, the following: 44 | 45 | i. the right to reproduce, adapt, distribute, perform, display, 46 | communicate, and translate a Work; 47 | ii. moral rights retained by the original author(s) and/or performer(s); 48 | iii. publicity and privacy rights pertaining to a person's image or 49 | likeness depicted in a Work; 50 | iv. rights protecting against unfair competition in regards to a Work, 51 | subject to the limitations in paragraph 4(a), below; 52 | v. rights protecting the extraction, dissemination, use and reuse of data 53 | in a Work; 54 | vi. database rights (such as those arising under Directive 96/9/EC of the 55 | European Parliament and of the Council of 11 March 1996 on the legal 56 | protection of databases, and under any national implementation 57 | thereof, including any amended or successor version of such 58 | directive); and 59 | vii. other similar, equivalent or corresponding rights throughout the 60 | world based on applicable law or treaty, and any national 61 | implementations thereof. 62 | 63 | 2. Waiver. To the greatest extent permitted by, but not in contravention 64 | of, applicable law, Affirmer hereby overtly, fully, permanently, 65 | irrevocably and unconditionally waives, abandons, and surrenders all of 66 | Affirmer's Copyright and Related Rights and associated claims and causes 67 | of action, whether now known or unknown (including existing as well as 68 | future claims and causes of action), in the Work (i) in all territories 69 | worldwide, (ii) for the maximum duration provided by applicable law or 70 | treaty (including future time extensions), (iii) in any current or future 71 | medium and for any number of copies, and (iv) for any purpose whatsoever, 72 | including without limitation commercial, advertising or promotional 73 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each 74 | member of the public at large and to the detriment of Affirmer's heirs and 75 | successors, fully intending that such Waiver shall not be subject to 76 | revocation, rescission, cancellation, termination, or any other legal or 77 | equitable action to disrupt the quiet enjoyment of the Work by the public 78 | as contemplated by Affirmer's express Statement of Purpose. 79 | 80 | 3. Public License Fallback. Should any part of the Waiver for any reason 81 | be judged legally invalid or ineffective under applicable law, then the 82 | Waiver shall be preserved to the maximum extent permitted taking into 83 | account Affirmer's express Statement of Purpose. In addition, to the 84 | extent the Waiver is so judged Affirmer hereby grants to each affected 85 | person a royalty-free, non transferable, non sublicensable, non exclusive, 86 | irrevocable and unconditional license to exercise Affirmer's Copyright and 87 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 88 | maximum duration provided by applicable law or treaty (including future 89 | time extensions), (iii) in any current or future medium and for any number 90 | of copies, and (iv) for any purpose whatsoever, including without 91 | limitation commercial, advertising or promotional purposes (the 92 | "License"). The License shall be deemed effective as of the date CC0 was 93 | applied by Affirmer to the Work. Should any part of the License for any 94 | reason be judged legally invalid or ineffective under applicable law, such 95 | partial invalidity or ineffectiveness shall not invalidate the remainder 96 | of the License, and in such case Affirmer hereby affirms that he or she 97 | will not (i) exercise any of his or her remaining Copyright and Related 98 | Rights in the Work or (ii) assert any associated claims and causes of 99 | action with respect to the Work, in either case contrary to Affirmer's 100 | express Statement of Purpose. 101 | 102 | 4. Limitations and Disclaimers. 103 | 104 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 105 | surrendered, licensed or otherwise affected by this document. 106 | b. Affirmer offers the Work as-is and makes no representations or 107 | warranties of any kind concerning the Work, express, implied, 108 | statutory or otherwise, including without limitation warranties of 109 | title, merchantability, fitness for a particular purpose, non 110 | infringement, or the absence of latent or other defects, accuracy, or 111 | the present or absence of errors, whether or not discoverable, all to 112 | the greatest extent permissible under applicable law. 113 | c. Affirmer disclaims responsibility for clearing rights of other persons 114 | that may apply to the Work or any use thereof, including without 115 | limitation any person's Copyright and Related Rights in the Work. 116 | Further, Affirmer disclaims responsibility for obtaining any necessary 117 | consents, permissions or other rights required for any use of the 118 | Work. 119 | d. Affirmer understands and acknowledges that Creative Commons is not a 120 | party to this document and has no duty or obligation with respect to 121 | this CC0 or use of the Work. 122 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DefComBlog 2 | 3 | Source Code: https://github.com/MarisaKirisame/DefCom 4 | -------------------------------------------------------------------------------- /TOC.md: -------------------------------------------------------------------------------- 1 | # Table Of Content 2 | 3 | - 0: Calculator 4 | - 1: CodeGen 5 | 6 | --------------------------------------------------------------------------------