annotate manual.txt @ 245:3590ecca6bc9

Fix handling of unescaped tabs in string literals in new parser
author Mike Pavone <pavone@retrodev.com>
date Mon, 06 Jan 2014 01:03:18 -0800
parents 966a09d226e3
children
rev   line source
pavone@133 1 Intro
pavone@133 2 -----
pavone@133 3
pavone@133 4 TP is an ahead of time compiled, dynamically typed (though there are plans for an optional type checker) language heavily inspired by Smalltalk. The main goal of the language is to be a suitable target for a structured editor on touch-screen devices and tablets in particular. The prototype of the editor is not really complete enough to be useful at this time.
pavone@133 5
pavone@133 6 Assignment
pavone@133 7 ----------
pavone@133 8
pavone@133 9 Assignment is done with the <- operator. Inside a lambda, it is used to assign a value to a variable. Inside an object definition it is used to either assign an initial value to a property or a lambda to be used as the definition of the method. Assignments are currently the only construct that are not expressions and as a result they cannot be used in an expression construct. This may change in the future.
pavone@133 10
pavone@133 11
pavone@133 12 Symbols
pavone@133 13 -------
pavone@133 14
pavone@133 15 Symbols in TP must start with a letter, underscore, bang, question mark or at symbol. Numbers and colons can be used in symbol names as long as they are not the first character. Colons allow a function or method name to be split into multiple parts with the arguments interspersed between them. This is covered in more detail in the second on function and method calls.
pavone@133 16
pavone@133 17 Lambdas
pavone@133 18 -------
pavone@133 19
pavone@133 20 Lambdas are enclosed in curly braces. If present, the argument list is preceded by a colon. Individual argument names are separated by spaces and may also be preceded by a colon. These internal colons provide a hint to the user (and eventually the structured editor) about how to best intersperse function name parts and arguments. The body of a lambda is made up of zero or more assignments or expressions. The result of evaluating the final expression of a lambda is used as the result.
pavone@133 21
pavone@133 22 Examples:
pavone@133 23 {} //Empty lambda with no arguments
pavone@133 24 :foo bar {} //Empty lambda with two arguments: foo and bar
pavone@133 25 :foo :bar {} //Same as before with a placement hint
pavone@133 26 :foo {
pavone@133 27 foo
pavone@133 28 } //A lambda that simply returns its only argument
pavone@133 29
pavone@133 30 Objects
pavone@133 31 -------
pavone@133 32
pavone@133 33 TP has no named object types. All objects are created via object literals. An object literal is started with a hash followed by an open curly bracket character and is terminated with a close curly bracket character. Properties and methods are defined with assignments. A property is really just syntactic sugar for a getter method and a setter method. The getter method has a name that is identical to the name of the property. The setter method has a bang appended to the end of the property name. Setter methods return the object being modified.
pavone@133 34
pavone@133 35 A method is created when a lambda is assigned to a name inside of an object definition. This assignment must be done with a literal lambda. Assigning a lambda to a variable and then using that variable inside an object definition will generate a property that is initialized to that value. The first argument to a method is named self and refers to the object the method was called on. If self is not explicitly named as the first argument, it will be added implicitly.
pavone@133 36
pavone@133 37 Examples:
pavone@133 38 #{} //Object with no methods
pavone@133 39 #{
pavone@133 40 foo <- 42
pavone@133 41 bar <- baz
pavone@133 42 } //Object with two properties
pavone@133 43 #{
pavone@133 44 baz <- 42
pavone@133 45 foo <- :bar {
pavone@133 46 2 * bar + (self baz)
pavone@133 47 }
pavone@133 48 }//object with method with an implicit self parameter
pavone@133 49 #{
pavone@133 50 baz <- 42
pavone@133 51 foo <- :self bar {
pavone@133 52 2 * bar + (self baz)
pavone@133 53 }
pavone@133 54 }//identical object with an explicit self parameter on the foo method
pavone@133 55 _foo <- :bar { 2 * bar }
pavone@133 56 #{
pavone@133 57 foo <- _foo
pavone@133 58 }//object with a property named foo initialized to contain a lambda
pavone@133 59
pavone@133 60 Operators
pavone@133 61 ---------
pavone@133 62
pavone@133 63 TP has the following binary operators. Operators are listed in order of precedence with operators of the same precedence listed on the same line.
pavone@133 64 * / % //multiplication, division, modulus
pavone@133 65 + - . xor and or //addition, subtraction, concatenation, bitwise operations
pavone@133 66 <= >= < > = != //comparison
pavone@133 67 && || //logical
pavone@133 68
pavone@133 69 Operators can be the target of an assignment in an object definition. This allows operators to be defined for user types.
pavone@133 70
pavone@133 71 Function and method calls
pavone@133 72 -------------------------
pavone@133 73
pavone@133 74 There are three syntaxes for function and method calls. There is the unary method syntax, the regular method syntax and the function call syntax. Despite their names, there is no semantic difference between these three syntaxes and they can be used for both function calls and method calls. The one limitation is that the unary method syntax can only be used with methods/functions that take a single argument, including the self argument.
pavone@133 75
pavone@133 76 The unary syntax consists of the first parameter followed by the function or method name. The two are separated by a space. Example:
pavone@133 77
pavone@133 78 object methodName
pavone@133 79
pavone@133 80 The regular method syntax adds a colon to the method or function name. Additional arguments follow the colon and are separated by spaces. Example:
pavone@133 81
pavone@133 82 firstParam methodName: secondParam thirdParam
pavone@133 83
pavone@133 84 The function call syntax is similar, but has the first argument following the method or function name. This syntax is generally the only way to call a function with no arguments. Examples:
pavone@133 85
pavone@133 86 methodName: firstParam secondParam thirdParam
pavone@133 87 funcWithNoArgs:
pavone@133 88
pavone@133 89 Symbols can contain internal colons and when used as a function or method name, the symbol can be split into several pieces at those colons. Example:
pavone@133 90
pavone@133 91 //call foo:withBar:andQux with the arguments: baz, dive and quixotic
pavone@133 92 foo: baz withBar: dive andQux: quixotic
pavone@133 93
pavone@133 94 Flow Control
pavone@133 95 ------------
pavone@133 96
pavone@133 97 TP has no explicit flow control structures. Instead, the flow control structures are implemented as methods that take lambdas as arguments. The methods if and if:else are implemented on the boolean objects and provide for conditional execution. while:do is implemented on lambda objects and provides a basic while loop. foreach is implemented on sequence types to provide a mechanism for easily looping over an array. Examples:
pavone@133 98
pavone@133 99 if: foo = bar {
pavone@133 100 //do something when foo is equal to bar
pavone@133 101 }
pavone@133 102
pavone@133 103 if: foo = bar {
pavone@133 104 //do something when foo is equal to bar
pavone@133 105 } else: {
pavone@133 106 //do something else when foo is not equal to bar
pavone@133 107 }
pavone@133 108
pavone@133 109 while: { foo = bar } do: {
pavone@133 110 foo bazinate
pavone@133 111 }
pavone@133 112
pavone@133 113 //print each string in the array
pavone@133 114 foreach: #["foo" "bar" "baz" "qux"] :index value {
pavone@133 115 print: (value . "\n")
pavone@133 116 }
pavone@133 117
pavone@133 118 Scope
pavone@133 119 -----
pavone@133 120
pavone@133 121 Variables are lexically scoped. Objects also participate in scoping. This allows access to properties and methods in the current object and objects in parent scopes without an explicit reference to the relevant object. Modules exist at the root of the scope tree. The name true, refers to the module in modules/true.tp unless it has been shadowed with an assignment.
pavone@133 122
pavone@133 123 Module
pavone@133 124 ------
pavone@133 125
pavone@133 126 A TP source file contains exactly one module. A module is simply an object. The top level of a TP source file should be an object literal or a lambda with no arguments that returns an object literal.
pavone@133 127
pavone@133 128 Importing
pavone@133 129 ---------
pavone@133 130
pavone@133 131 Methods from one object can be imported into another object. This is essentially just synatctic sugar for delegation. A reference to the imported object is created in the target object and calls to the imported methods are forwarded to that object.
pavone@133 132
pavone@133 133 Imports are currently not really implemented in the C backend at this moment, but I may be able to add partial support in time for the contest.