· 7 years ago · Sep 03, 2018, 06:38 PM
1Table Of Contents
2
3 0. Overview
4
5 1. Preprocessor
6
7 a. Comments
8 b. Includes
9 c. Macros
10 d. Conditionals
11 e. Escape Codes
12 f. Line Continuation
13
14 2. Syntax
15
16 a. Overview
17 b. Keywords
18 c. Declarations
19 d. Assignments
20 e. Functions
21 f. Expressions
22 g. Classes
23 h. Inheritance
24 i. Identifiers
25
26 3. Standard Library
27
28 a. Base Classes
29
300. Overview
31
32The language defined in this specification utilizes a simple syntax. The syntax is not alike the syntax of C family languages, it is more along the lines of Python. A single line represents a single operation. Indentation matters and is strictly enforced by the compiler. Bear in mind that as this language is compileable, the variables and functions are strictly typed (a variable is assigned a type on creation which may not ever change). This will hopefully give you a basic idea of the language that is represented hereon.
33
341. Preprocessor
35
36The preprocessor is responsible for processing raw text input and preparing it for the next stages in the compiler. The preprocessor will handle the removal of comments, the inclusion of header files, the definition, replacement and undefinition of macros, along with conditionals and ANSI escape code formatting.
37
38 a. Comments
39
40 Comments are lines that do not serve any computational purpose; they are used only for providing information to the programmer. Comments can be found by checking if the first character of a line (if any) is a hashtag symbol ('#'). If so, the line may be discarded.
41
42 Comments may also exist alongside a functional line of code. Whenever a hashtag symbol is encountered outside of a string or character literal, then that character and any that follow it must be discarded by the preprocessor.
43
44 int n = 1 # This variable is of no significance whatsoever, to mortals and immortals alike.
45
46 becomes
47
48 int n = 1
49
50 b. Includes
51
52 It is possible to include the source of another file into the current file by using preprocessor directives. This removes the need to write code over and over again, as it can be stored in another file and reused at will. There are no headers, just source files. The include directive takes the form of
53
54 include <...> or include "..."
55
56 Pointy brackets ('<' and '>') indicate that the file is a standard header, which is included with all compilers. Double quotes '"' indicate the file exists in a path relative to the path of the current file.
57
58 When files are included, they are preprocessed recursively. The output of their respective preprocessing calls are inserted directly into the current file, after removing the include directive. Recursive includes must be detected by compilers, and should be avoided by using preprocessor conditionals. For example, say we have file "a.ws", the contents of which are
59
60 include "b.ws"
61
62 ...
63
64 and we have the file "b.ws", the contents of which are
65
66 int a = 1
67 int b = 2
68 int c = 3
69
70 and the preprocessor is asked to preprocess "a.ws",
71
72 1. The preprocessor begins scanning a.ws and encounters the include directive for "b.ws".
73 2. The preprocessor attempts to locate "b.ws" relative to "a.ws"'s path, it succeeds.
74 3. The preprocessor initializes another instance of itself, and asks it to preprocess "b.ws".
75 4. The child preprocessor does not notice any preprocessor directives, and passes the file's content unchanged back to it's parent.
76 5. The preprocessor replaces the include directive with the text generated by it's child preprocessor, the file now looks like this
77
78 int a = 1
79 int b = 2
80 int c = 3
81
82 ...
83
84 6. The preprocessor continues to scan the file.
85
86 c. Macros
87
88 Macros can be defined using the 'define' keyword. The syntax of the define keyword is as follows
89
90 define <identifier> <...>
91
92 The syntax consists of the define keyword followed by exactly one space and an identifier, followed by any string of text that occurs on one line.
93
94 Whenever an occurrance of the defined identifier appears in following lines, that identifier is replaced by the exact copy of the text following the identifier in the preprocessor directive.
95
96 d. Conditionals
97
98 Conditionals may be implemented in a further revision of this language, but as of now there are no preprocessor conditionals provided.
99
100 e. Escape Codes
101
102 In string and character literals escape codes may be used. These escape codes must NOT be translated into their appropriate form by the preprocessor. The reason for this is that the escape codes which create a line break ('\n', etc.) can corrupt the flow of the program, as the entire language is based on indentation and line-feeds.
103
104 Instead, escape codes should be processed by the lexer and converted into their appropriate form when generating a string or character token.
105
106 f. Line Continuation
107
108 Code that is too long to be legible on one line may be split into many lines by using the '\' token. You cannot split a line in the middle of a string or character literal. The following line should have proper indentation, but this is not required. Line continuation should be processed by the preprocessor before anything else, including macro replacement.
109
1102. Syntax
111
112The syntax of the language is defined hereon. This includes the grammatical and semantic rules of the language, and the strict coding practises to be used while writing code in this language.
113
114 a. Overview
115
116 Seeing as this language is a indentation based language, the program flow can be different from one expects, this results is hard-to-find and annoying coding mistakes. However, this language is designed for the elite, and the elite only, so such mistakes are not uttered by the fingers of the elite. Thus, worthy users of this language need not worry about senseless and pleghm-brained mistakes.
117
118 However, it is prudent to include examples of such mistakes, so that some of the lower-tier elite shall not have to embarrass themselves in front of masters of this language
119
120 This programmer tried to count to one hundred and only swallow the even numbers. This was his code
121
122 1. for int x = 0 while x < 100 doing x += 1
123 2. # Only swallow even numbers
124 3. if x % 2 == 0
125 4. swallow(x)
126
127 He noticed that his code was swallowing 0, 1, 2, 3 ... all the way to 99. The reason for this is that on line 4, his swallow call is under line 1's indentation. Thus line 4 is inside line 1's closure, not line 3's. He should fix his code to include line 4 inside line 3's closure. His code will look like this
128
129 1. for int x = 0 while x < 100 doing x += 1
130 2. # Only swallow even numbers
131 3. if x % 2 == 0
132 4. swallow(x)
133
134 This code swallows 0, 2, 4, 6 ..., which is what the programmer wanted.
135
136 b. Keywords
137
138 There are quite a few keywords in this language. The keywords include
139
140 byte if include func
141 short else delete of
142 int for inherits void
143 long while public
144 float do private
145 double doing auto
146 number class type
147 decimal define const
148
149 c. Declarations
150
151 A declaration in this language follows this syntax
152
153 <type> <identifer>
154
155 or, one could use the following syntax to initialize a value to the declared variable
156
157 <type> <identifier> = <expression>
158
159 The following criteria must be met when declaring a variable
160
161 1. The type must have been declared previous to this declaration
162 2. The identifier must not have been previously used in this variables full scope
163 3. The identifier must be valid (see 2.i Identifiers)
164 4. The expression used (if any) must be the same type as the type of the variable
165 5. The identifier may not have been used previously as a function name
166
167 If so, the variable can be declared. The variable can be deleted using the following syntax
168
169 <delete> <identifier>
170
171 The following criteria must be met when deleting a variable
172
173 1. The identifier may not be a function name
174 2. The identifier must have been previously declared
175 3. The identifier may not have a constant type
176
177 d. Assignments
178
179 It is possible to assign a variable a value. The syntax of which is as follows
180
181 <identifier> <assignment-operator> <expression>
182
183 The following criteria must be met when declaring a variable
184
185 1. Don't make me spell out what the identifier should and shouldn't be, you're not stupid.
186 2. The expression must be the same type as the type of the identifier.
187
188 The assignment operators that may be used are as follows
189
190 Sequence Function Description
191
192 = asgn(...) Assign the right-hand operand to the left-hand operand
193 += addasgn(...) Add the right-hand operand to the left-hand operand
194 -= subasgn(...) Subtract the right-hand operand from the left-hand operand
195 *= mulasgn(...) Multiply right-hand operand by the left-hand operand
196 /= divasgn(...) Divide the right-hand operand by the left-hand operand
197 %= modasgn(...) Set the right-hand operand to (right-hand modulo left-hand)
198
199 You can call any of the asgn functions like this
200
201 <assignment-function>(<identifier>, <expression>)
202
203 Don't try to make your own asgn or addasgn or something because it's impossible. These should be keywords but they are not because thats just stupid.
204
205 e. Functions
206
207 Functions look like this
208
209 func <identifier>(<arg-type> <arg-identifier>, ...) of <return-type>
210 ...
211 return <expression>
212
213 You can omit the 'return <expression>' if your <return-type> is void.
214
215 As of the current revision of this language, it is impossible to
216
217 1. Define a function signature without actually coding the function body
218 2. Delete a function
219 3. Modify a function body programmatically
220
221 It might be possible to do these things in later revisions of this language.
222
223 Functions return a reference to the expression that was returned. Function arguments are references to the values passed, so modifying an argument modifies the value passed to the function as that argument as well, as they are literally the same object under different identifiers.
224
225 f. Expressions
226
227 Expressions are a wide topic. There are many literals that can be used as expressions
228
229 String "string\n"
230
231 String literals consist of a string of text surrounded by double quotes ('"'). These are of type byte[] usually, but some standard libraries may implement a string type.
232
233 Character '\n'
234
235 Character literals consist of one character or one escape code surrounded by single quotes ('''). These are of type byte.
236
237 Integer 1, 2, +1, -2
238
239 Integer literals consist of a number with an optional sign and no decimal point. If no sign is provided, is is assumed that the integer is positive. You may dictate the signed/unsigned part of the intger by following the literal with
240
241 'U' or 'S' (capitalization matters)
242
243 You may dictate the integer type that the literal is by following the literal with
244
245 'l' long
246 'i' int
247 's' short
248 'b' byte
249
250 Lowercase matters.
251
252 Make sure that the signage follows the type specification if both are used, for example, to cast to an unsigned int, you should use
253
254 14393iU
255
256 not
257
258 14393Ui
259
260 If no type is specified, the type is inferred from the context of the literal.
261
262 Decimal 0.0, +0.0, -0.0
263
264 Decimal literals are a number with an optional sign and an optional decimal point. You may dictate the type of the literal by following it with either of
265
266 'd' double or
267 'f' float
268
269 There are no signed/unsigned doubles or floats. If no type is specified, the type is inferred from the context of the literal.
270
271 Hexadecimal 0xFFF, 0xfff, 0xFfF
272
273 These are not yet implemented, but will be soon.
274
275 Binary 0b101010
276
277 These are not yet implemented, but will be soon.
278
279 You can use these literal types as expressions or combine them with other literals to make expressions. The operators that can be used in expressions are
280
281 + Addition
282 - Subtraction
283 * Multiplication
284 / Division
285 % Modulo
286
287 You can also use the member access operator to access members of an object
288
289 . Member Access
290
291 Identifiers can be used in expressions as well, and combined with literals. Literals are indeed objects themselves, as they are casted to an object before usage. To access members of a literal, use parentheses
292
293 ("dude")[0].getHashCode()
294
295 Parentheses can be used to seperate expressions. When parentheses are not used, the BEDMAS/PEDMAS precedence table is used for numerical expressions. For non-numerical expressions, the expressions are evaluated left-to-right.