diff --git a/docs/implementation/31-lexical.md b/docs/implementation/31-lexical.md index c78da47..a471eac 100644 --- a/docs/implementation/31-lexical.md +++ b/docs/implementation/31-lexical.md @@ -1,10 +1,11 @@ ## Lexical analysis Lexical analysis is the process of taking a program as an input string -$A$ and splitting it into a list of $n$ sub-strings -$A_{1},\,A_{2}\ldots A_{n}$ called tokens. The length $n$ of this list -of dependent on several rules that determine how, when and where new -tokens are built - this set of rules is called a *grammar*. +*A* and splitting it into a list of *n* sub-strings +*A*1, *A*2…*A**n* called tokens. The +length *n* of this list of dependent on several rules that determine +how, when and where new tokens are built - this set of rules is called a +*grammar*. ### Grammar @@ -27,7 +28,7 @@ definitions: new Token("int") == new Token("int") ``` - - ...would evaluate to `true`, rather than false by reference + - …would evaluate to `true`, rather than false by reference equality (the default in D) - `Lexer` - The token builder - `sourceCode`, the whole input program (as a string) to be @@ -38,7 +39,7 @@ definitions: - Contains a list of the currently built tokens, `Token[] tokens` - Current line and column numbers as `line` and `column` respectively - - A "build up" - this is the token (in string form) currently + - A “build up” - this is the token (in string form) currently being built - `currentToken` ### Implementation @@ -124,13 +125,10 @@ character == ':'; !!! error FInish this page -• -`\texttt{;}`{=tex} `\texttt{,}`{=tex} `\texttt{(}`{=tex} `\texttt{)}`{=tex} `\texttt{[}`{=tex} `\texttt{]}`{=tex} `\texttt{+}`{=tex} `\texttt{-}`{=tex} `\texttt{/}`{=tex} `\texttt{\%}`{=tex} `\texttt{*}`{=tex} `\texttt{\&}`{=tex} `\texttt{\{}`{=tex} `\texttt{\}}`{=tex} +•               -• `\texttt{=}`{=tex} \| (TODO: make it -texttt) \\texttt{\^} `\texttt{!}`{=tex} `\texttt{\\n}`{=tex}(TODO: -`\n `{=tex}not -appearing) \\texttt{\~} `\texttt{.}`{=tex} `\texttt{\:}`{=tex} +•  \| (TODO: make it texttt) \\texttt{^}  (TODO: not +appearing) \\texttt{\~}   Whenever this method returns `true` it generally means you should flush the current token, start a new token add the offending spliter token and diff --git a/docs/implementation/32-parsing.md b/docs/implementation/32-parsing.md index 840fa9d..b7df6bc 100644 --- a/docs/implementation/32-parsing.md +++ b/docs/implementation/32-parsing.md @@ -2,7 +2,7 @@ Once we have generated a list of tokens (instances of `Token`) from the `Lexer` instance we need to turn these into a structure that represents -our program's source code *but* using in-memory data-structures which we +our program’s source code *but* using in-memory data-structures which we can traverse and process at a later stage. ### Overview @@ -12,7 +12,7 @@ sub-structures of a TLang program and returning different data types generated by these methods. The parser has the ability to move back and forth between the token stream provided and fetch the current token (along with analysing it to return the type of symbol the token -represents - known as the `SymbolType` (TODO: Cite the "Symbol types" +represents - known as the `SymbolType` (TODO: Cite the “Symbol types” section). For example, the method `parseIf()` is used to parse if statements, it @@ -30,7 +30,7 @@ proper module support ### API -The API exposed by the parser is rather minimal as there isn't much to a +The API exposed by the parser is rather minimal as there isn’t much to a parser than controlling the token stream pointer (the position in the token stream), fetching the token and acting upon the type or value of said token. Therefore we have the methods summarised below: @@ -132,7 +132,7 @@ within the `parsing/data/check.d` and contains the following methods: that you provide it a `SymbolType` and it will return the corresponding string that is of that type. - This will work only for back-mapping a sub-section of tokens as - you won't get anything back if you provide + you won’t get anything back if you provide `SymbolType.IDENT_TYPE` as there are infinite possibiltiies for that - not a fixed token. @@ -280,7 +280,7 @@ while (hasTokens()) ``` Following this we now have several checks that make use of -`getSymbolType(Token)` in order to determine what the token's type is +`getSymbolType(Token)` in order to determine what the token’s type is and then in our case if the token is `"if"` then we will make a call to `parseIf()` and append the returned Statement-sub-type to the body of statements (`Statement[]`): diff --git a/docs/implementation/34-dependency.md b/docs/implementation/34-dependency.md index a0a90c1..369caeb 100644 --- a/docs/implementation/34-dependency.md +++ b/docs/implementation/34-dependency.md @@ -12,7 +12,7 @@ time but also makes the implementation bloated as all logic must be in one file to support each stage. There are also other disbenefits: 1. Symbol definitions - - Doing a single pass means you haven't stored all symbols in the + - Doing a single pass means you haven’t stored all symbols in the program yet, hence resolution of some will fail unless you do some sort of over-complicated lookahead to find them - cache them - and then retry. In general it makes all sort of @@ -24,28 +24,28 @@ one file to support each stage. There are also other disbenefits: 2. Dependencies - Some instructions must be generated which do not have a syntactical mapping. I.e. the static initialization of a class - doesn't have a parser/AST node equivalent. Therefore our + doesn’t have a parser/AST node equivalent. Therefore our multi-stage system of parserot-to-dependency coversions allows us to convert all AST nodes to dependency nodes and add extra dependency nodes (such as `ClassStaticInit`) into the dependency tree despite them having no AST equivalent. - - Splitting this up also let's us more easily, once again, about + - Splitting this up also let’s us more easily, once again, about symbols that are defined but reauire static initializations, and looping structures which must be resolved and can easily be done if we know all symbols (we just walk the AST tree) -*And the list goes on...* +*And the list goes on…* Hopefully now one understands as to why a multi-pass compiler is both easier to write (as the code is more modular) and easier to reason about in terms symbol resolution. It is for this reason that a lot of the code you see in the dependency processor looks like a duplicate of the parser -processor but in reality it's doing something different - it's generated +processor but in reality it’s doing something different - it’s generated the actual executable atoms that must be typechecked and have code generated for - taking into account looping structures and so forth. > The dependency processor adds execution to the AST tree and the -> ability to reason about visited nodes and "already-initted" structures +> ability to reason about visited nodes and “already-initted” structures ### What gets accomplished? @@ -60,19 +60,19 @@ and creation process provides us: mark them as visited hence a use-before-declare situation is easy to detect and report to the end-user 2. Tree of execution - - When the dependency tree is fully created it can be "linearized" + - When the dependency tree is fully created it can be “linearized” or left-hand leaf visited whereby eahc leaf-left node is appended into an array. - This array then provides us a list of `DNode`s we walk through in the typechecker and can effectively generate instructions from and perform typechecking - - It's an easy to walk through "process - typecheck - code gen". + - It’s an easy to walk through “process - typecheck - code gen”. 3. Non-AST equivalents - - There is no equivalent AST node that represents a "static - allocation" - that is something derived from the AST tree, - therefore we need a list of **concrete** "instructions" which + - There is no equivalent AST node that represents a “static + allocation” - that is something derived from the AST tree, + therefore we need a list of **concrete** “instructions” which precisely tell the code generator what to do - this is one of - those cases where a AST tree wouldn't help us - or we we would + those cases where a AST tree wouldn’t help us - or we we would effectively have to implement this all in the parser which leads to overly complex parser. @@ -104,7 +104,7 @@ wraps the following methods and fields within it: needed, therefore a second visitation state is required. See `tree()`. 7. `DNode[] dependencies` - - The current `DNode`'s array of depenencies which themselves are + - The current `DNode`’s array of depenencies which themselves are `DNode`s 8. `performLinearization()` - Performs the linearization process on the dependency tree, @@ -133,7 +133,7 @@ wraps the following methods and fields within it: The DNodeGenerator is used to generate dependency node objects (`DNode`s) based on the current state of the type checker. It will use -the type checker's facilities to lookup the `Module` that is contained +the type checker’s facilities to lookup the `Module` that is contained within and use this container-based entity to traverse the entire parse tree of the container and process each different possible type of `Statement` found within, step-by-step generating a dependency node for @@ -156,7 +156,7 @@ TODO: Discuss the `DNodeGenerator` ### Pooling -Pooling is the technique of mapping a given parse node, let's say some +Pooling is the technique of mapping a given parse node, let’s say some kind-of `Statement`, to the same `DNode` everytime and if no mapping exists then creating a `DNode` for the respective parse node once off and then returning that same dependency node on successive requests. @@ -176,7 +176,7 @@ status of said `DNode` during processing. Below we have an example of what this process looks like. In this case we would have done something akin to the following. Our scenario is that -we have some sort of parse node, let's assume it was a `Variable` parse +we have some sort of parse node, let’s assume it was a `Variable` parse node which would represent a variable declaration. ![](/projects/tlang/graphs/pandocplot11037938885968638614.svg) @@ -190,7 +190,7 @@ it and then confirmed that the `varDNode.entity` is equal to that of the (`varPNode`) in order to show the returned dependency node will be the same as that referenced by `varDNode`. -``` {.d .numberLines} +``` d Variable varPNode = <... fetch node>; DNode varDNode = pool(varPNode); diff --git a/docs/implementation/35-typechecking.md b/docs/implementation/35-typechecking.md index d8e67da..a553c7e 100644 --- a/docs/implementation/35-typechecking.md +++ b/docs/implementation/35-typechecking.md @@ -23,7 +23,7 @@ instructions and contains some common methods used by all of them: that if such context is needed during further code generation (or even emit) it can then be accessed 2. `Context getContext()` - - Returns this instruction's associated context via its `Context` + - Returns this instruction’s associated context via its `Context` object 3. `string produceToStrEnclose(string addInfo)` - Returns a string containing the additional info provided through @@ -58,12 +58,12 @@ be found in ### Code generation The method of code generation and type checking starts by being provided -a so-called "action list" which is a linear array of dependency-nodes -(or `DNode`s for code's sake), this list is then iterated through by a +a so-called “action list” which is a linear array of dependency-nodes +(or `DNode`s for code’s sake), this list is then iterated through by a for-loop, and each `DNode` is passed to a method called `typeCheckThing(DNode)`: -``` {.d .numberLines} +``` d foreach(DNode node; actionList) { /* Type-check/code-gen this node */ @@ -75,7 +75,7 @@ The handling of every different instruction type and its associated typechecking requirements are handled in one huge if-statement within the `typeCheckThing(DNode)` method. This method will analyse a given dependency-node and perform the required typechecking by extracting the -`DNode`'s emebedded parser-node, whilst doing so if a type check passes +`DNode`’s emebedded parser-node, whilst doing so if a type check passes then code generation takes place by generating the corresponding instruction and adding this to some position in the code queue (discussed later). @@ -86,8 +86,8 @@ TODO: Add information on this The code queue is used as a stack and a queue in order to facilitate instruction generation. Certain instructions are produced once off and -then added to the back of the queue (*"consuming"* instructions) whilst -other are produced and pushed onto the top of the queue (*"producing"* +then added to the back of the queue (*“consuming”* instructions) whilst +other are produced and pushed onto the top of the queue (*“producing”* instructions) for consumption by other consuming instructions later. An example of this would be the following T code which uses a binary diff --git a/docs/implementation/36-emit.md b/docs/implementation/36-emit.md index 996ca0e..2efa9a1 100644 --- a/docs/implementation/36-emit.md +++ b/docs/implementation/36-emit.md @@ -94,7 +94,7 @@ else if(cast(VariableDeclaration)instruction) What we have here is some code which will extract the name of the variable being declared via `varDecInstr.varName` which is then used to lookup the parser node of type `Variable`. The `Variable` object -contains information such as the variable's type and also if a variable +contains information such as the variable’s type and also if a variable assignment is attached to this declaration or not. TODO: Insert code regarding assignment checking @@ -129,7 +129,7 @@ usage. In this case we want to translate the symbol of the entity named `simple_variables_decls_ass`. Therefore we provide both peices of information into the function `symbolLookup`: -``` {.d .numberLines} +``` d // The relative container of this variable is the module Container container = tc.getModule(); diff --git a/docs/implementation/37-compiler.md b/docs/implementation/37-compiler.md index dc4e0f4..e16c85f 100644 --- a/docs/implementation/37-compiler.md +++ b/docs/implementation/37-compiler.md @@ -21,9 +21,9 @@ following methods: 1. `this(string sourceCode, File emitOutFile)` - Constructs a new compiler object with the given source code and the file to write the emitted code out to - - An newly initialized `File` struct that doesn't contain a valid + - An newly initialized `File` struct that doesn’t contain a valid file handle can be passed in in the case whereby the emitter - won't be used but an instance of the compiler is required + won’t be used but an instance of the compiler is required 2. `doLex()` - Performs the tokenization of the input source code, `sourceCode`. @@ -118,7 +118,7 @@ The types that can be stored and their respectives methods are: Below is an example of the usage of the `ConfigEntry`s in the `CompilerConfiguration` system, here we add a few entries: -``` {.d .numberLines} +``` d /* Enable Behaviour-C fixes */ config.addConfig(ConfigEntry("behavec:preinline_args", true)); @@ -138,7 +138,7 @@ Later on we can retrieve these entries, the below is code from the `DGen` class which emits the C code), here we check for any object files that should be linked in: -``` {.d .numberLines} +``` d //NOTE: Change to system compiler (maybe, we need to choose a good C compiler) string[] compileArgs = ["clang", "-o", "tlang.out", file.name()]; diff --git a/docs/introduction/11-why.md b/docs/introduction/11-why.md index f24b15a..095a746 100644 --- a/docs/introduction/11-why.md +++ b/docs/introduction/11-why.md @@ -3,15 +3,15 @@ Despite my eagerness to jump directly into the subject matter at hand I think believe there is something of even greater importance. Despite there being a myriad of reasons I embarked upon this project something -more important than the stock-and-standard "I needed it to solve a -problem of mine" reasoning comes to mind. There is indeed a better +more important than the stock-and-standard “I needed it to solve a +problem of mine” reasoning comes to mind. There is indeed a better reason for embarking on something that the mere technical *requirement thereof* - I did this **because I can**. This sentiment is something that I really hold dear to my heart despite it being a seemingly obvious -one. Of course you can do what you want with your code - it's a free +one. Of course you can do what you want with your code - it’s a free country. One would not be wrong to make such a statement but mention -your ideas online and you get hounded down by others saying "that's -dumb, just use X" or "your implementation will be inefficient". These +your ideas online and you get hounded down by others saying “that’s +dumb, just use X” or “your implementation will be inefficient”. These statements are not entirely untrue but they miss the point that this is an exercise in scientific thinking and an artistic approach at it in that as well. @@ -23,5 +23,5 @@ expectations but luckily I do not require the external feedback of the mass - just some close few friends who can appreciate my work and join the endeavor with me. -*Don't let people stop you, you only have one life - take it by the +*Don’t let people stop you, you only have one life - take it by the horns and fly* diff --git a/docs/introduction/12-aims.md b/docs/introduction/12-aims.md index cb4278a..662396f 100644 --- a/docs/introduction/12-aims.md +++ b/docs/introduction/12-aims.md @@ -13,7 +13,7 @@ filter. Tristan aims to be able to support all of these but with certain limits, this is after all mainly an imperative language with those paradigms as -*"extra features"*. Avoiding feature creep in other systems-levels +*“extra features”*. Avoiding feature creep in other systems-levels languages such as C++ is something I really want to stress about the design of this language, I do not want a big and confusing mess that has an extremely steep learning curve and way too many moving parts. @@ -117,7 +117,7 @@ in my viewpoint and hence we support such features as: - Pointers - The mere *support* of pointers allowing one to take a memory-level view of objects in memory rather than the normal - "safe access" means + “safe access” means - Inline assembly - Inserting of arbitrary assembler is allowed, providing the programmer with access to systems level registers, @@ -125,7 +125,7 @@ in my viewpoint and hence we support such features as: - Custom byte-packing - Allowing the user to deviate from the normal struct packing structure in favor of a tweaked packing technique - - Custom packing on a system that doesn't agree with the alignment + - Custom packing on a system that doesn’t agree with the alignment of your data **is** allowed but the default is to pack accordingly to the respective platform diff --git a/docs/language/30-index.md b/docs/language/30-index.md index 9843c68..ec42557 100644 --- a/docs/language/30-index.md +++ b/docs/language/30-index.md @@ -1,6 +1,6 @@ # Language -This page serves as an official manual for both user's of TLang and +This page serves as an official manual for both user’s of TLang and those who want to understand/develop the internals of the compiler and runtime (the language itself). diff --git a/docs/language/31-grammar.md b/docs/language/31-grammar.md index 1444c09..f510e14 100644 --- a/docs/language/31-grammar.md +++ b/docs/language/31-grammar.md @@ -2,7 +2,7 @@ The grammar for the language is still a work in progress and may take some time to become concrete but every now and then I update this page -to add more to it or fix any incongruencies with the parser's actual +to add more to it or fix any incongruencies with the parser’s actual implementation. The grammar starts from the simplest building blocks and then progresses to the more complex (heavily composed) ones and these are placed into sections whereby they are related. diff --git a/docs/language/33-types.md b/docs/language/33-types.md index 419a090..c4aa523 100644 --- a/docs/language/33-types.md +++ b/docs/language/33-types.md @@ -12,22 +12,22 @@ attributes: ### Integral types - Type Width Intended interpretation - -------- ------- --------------------------------- - byte 8 signed byte (two's complement) - ubyte 8 unsigned byte - short 16 signed short (two's complement) - ushort 16 unsigned short - int 32 signed int (two's complement) - uint 32 unsigned int - long 64 signed long (two's complement) - ulong 64 unsigned long +| Type | Width | Intended interpretation | +|--------|-------|---------------------------------| +| byte | 8 | signed byte (two’s complement) | +| ubyte | 8 | unsigned byte | +| short | 16 | signed short (two’s complement) | +| ushort | 16 | unsigned short | +| int | 32 | signed int (two’s complement) | +| uint | 32 | unsigned int | +| long | 64 | signed long (two’s complement) | +| ulong | 64 | unsigned long | #### Conversion rules 1. TODO: Sign/zero extension 2. Promotion? -3. Precedence in interpretation when the first two don't apply +3. Precedence in interpretation when the first two don’t apply ### Decimal diff --git a/docs/language/35-conditionals.md b/docs/language/35-conditionals.md index 24584a2..a0b4806 100644 --- a/docs/language/35-conditionals.md +++ b/docs/language/35-conditionals.md @@ -32,7 +32,7 @@ else if(val == 3) ``` In the case the conditions are not true for any of the `if` or `else if` -branches then "default" code can be run in the `else` branch as such: +branches then “default” code can be run in the `else` branch as such: ``` d int val = 2; diff --git a/docs/language/38-arrays.md b/docs/language/38-arrays.md index 7bcf5dc..c779864 100644 --- a/docs/language/38-arrays.md +++ b/docs/language/38-arrays.md @@ -3,7 +3,7 @@ Arrays allow us to have one name refer to multiple instances of the same type. Think of an array like having multiple variables of the same type tightly packed next to one-another but being able to refer to this group -by a *single name* and *each instance* by a number - an *"offset"* so to +by a *single name* and *each instance* by a number - an *“offset”* so to speak. ### Stack arrays @@ -13,7 +13,7 @@ Stack arrays are what we refer to when we allocate an array stack space of the current stack frame (the space for the current function call). -``` {.d numberLines="1" hl_lines="5"} +``` d module simple_stack_arrays4; int function() diff --git a/docs/language/39-pointers.md b/docs/language/39-pointers.md index 9922745..eb438f6 100644 --- a/docs/language/39-pointers.md +++ b/docs/language/39-pointers.md @@ -2,14 +2,14 @@ Pointers are just like any other variable one would declare but what is important is that their values can be used in certain operations. A -pointer's value is an address of another variable and one can use a +pointer’s value is an address of another variable and one can use a pointer to indirectly refer to such a variable and indirectly fetch or update its value. A pointer type is written in the form of `*`, for example one may -write `int*` which is read as "a pointer to an `int`". +write `int*` which is read as “a pointer to an `int`”. -TODO: All pointers are 64-bit values - the size of addresses on one's +TODO: All pointers are 64-bit values - the size of addresses on one’s system. ### Pointer syntax @@ -17,22 +17,16 @@ system. There are a few operators that can be used on pointers which are shown below, most specific of which are the `*` and `&` unary operators: - --------------------------------------------------------------------------------- - Operator Description Example - ---------------------- ----------------------------- ---------------------------- - `&` Gets the address of the `int* myVarPtr = &myVar` - identifier - - `*` Gets the value at the address `int myVarVal = *myVarPtr` - held in the referred - identifier - --------------------------------------------------------------------------------- +| Operator | Description | Example | +|----------|---------------------------------------------------------------|----------------------------| +| `&` | Gets the address of the identifier | `int* myVarPtr = &myVar` | +| `*` | Gets the value at the address held in the referred identifier | `int myVarVal = *myVarPtr` | Below we will declare a module-level global variable `j` of type `int` and then use a function to indirectly update its value by the use of a pointer to this integer - in other words an `int*`: -``` {.d numberLines="1"} +``` d module simple_pointer; int j; @@ -58,7 +52,7 @@ named `ptr`. This can hold the address of memory that points to an function with the argument `&j` which means it is passing a pointer to the `j` variable in. -``` {.d numberLines="1"} +``` d int function(int* ptr) { *ptr = 2+2; @@ -81,15 +75,15 @@ What `int function(int* ptr)` does is two things: Some of the existing operators such as those used for arithmetic have special usage when used on pointers: - Operator Description Example - ---------- ------------------------------------------------------------------ --------- - `+` Allows one to offset the pointer by a `+ offset*sizeof(ptrType)` `ptr+1` - `-` Allows one to offset the pointer by a `- offset*sizeof(ptrType)` `ptr-1` +| Operator | Description | Example | +|----------|------------------------------------------------------------------|---------| +| `+` | Allows one to offset the pointer by a `+ offset*sizeof(ptrType)` | `ptr+1` | +| `-` | Allows one to offset the pointer by a `- offset*sizeof(ptrType)` | `ptr-1` | Below we show how one can use pointer arithmetic and the casting of pointers to work on sub-sections of data referenced to by a pointer: -``` {.d linenums="1" hl_lines="12-14"} +``` d module simple_pointer_cast_le; int j; @@ -123,7 +117,7 @@ access the 4 byte integer byte-by-byte, on x86 we would be starting with the least-significant byte. What we have done here is updated said byte to the value of `2+2`: -``` {.d linenums="1"} +``` d byte* bytePtr = cast(byte*)ptr; *bytePtr = 2+2; ``` @@ -133,7 +127,7 @@ which would increment the address by `1`, resultingly pointing to the second least significant byte, we then use the dereference operator `*` to set this byte to `1`: -``` {.d linenums="1"} +``` d *(bytePtr+1) = 1; ``` @@ -142,7 +136,7 @@ should (TODO: we can explain the memory here) become the result of `256+4` (that is `260`). After this we then return that number with two added to it: -``` {.d linenums="1"} +``` d return (*ptr)+1*2; ``` @@ -151,7 +145,7 @@ return (*ptr)+1*2; One can even mix these if they want, for example we can do the following: -``` {.d numberLines="1"} +``` d module simple_stack_arrays3; void function() diff --git a/docs/language/40-structs.md b/docs/language/40-structs.md index 8f6ceee..976c059 100644 --- a/docs/language/40-structs.md +++ b/docs/language/40-structs.md @@ -18,7 +18,7 @@ struct } ``` -Note: Assignments to these variables within the struct's body is not +Note: Assignments to these variables within the struct’s body is not allowed. #### Example diff --git a/docs/language/43-extern.md b/docs/language/43-extern.md index 6da9719..dcc7f84 100644 --- a/docs/language/43-extern.md +++ b/docs/language/43-extern.md @@ -1,21 +1,21 @@ ## External symbols Some times it is required that a symbol be processed at a later stage -that is not within the T compiler's symbol procvessing stage but rather +that is not within the T compiler’s symbol procvessing stage but rather at the linking stage. This is known as late-binding at link time where such symbols are only resolved then which can help one link their T program to some symbol in an ELF file (linked in with extra `gcc` arguments to `DGen`) or in a C standard library autpmatically included -in the DGen's emitted C code. +in the DGen’s emitted C code. In order to use such a feature one can make use of the `extern` keyword -which us specify either a function's signature or variable that should +which us specify either a function’s signature or variable that should be resolved during C compilation time **but** such that we can still use it in our T program with typechecking and all. One could take a C program such as the following: -``` {.c .numberLines} +``` c #include int ctr = 2; @@ -29,14 +29,14 @@ unsigned int doWrite(unsigned int fd, unsigned char* buffer, unsigned int count) and then compile it to an on object file named `file_io.o` with the following command: -``` {.bash .numberLines} +``` bash gcc source/tlang/testing/file_io.c -c -o file_io.o ``` And then link this with your T program using the command (take note of the flag `-ll file_io.o` which specifies the object to link in): -``` {.bash .numberLines} +``` bash ./tlang compile source/tlang/testing/simple_extern.t \ -sm HASHMAPPER \ -et true \ @@ -47,16 +47,16 @@ the flag `-ll file_io.o` which specifies the object to link in): ### External functions To declare an external function use the `extern efunc ...` clause -followed by a function's signature. Below we have an example of the +followed by a function’s signature. Below we have an example of the `doWrite` function from our C program (seen earlier) being specified: -``` {.d .numberLines} +``` d extern efunc uint doWrite(uint fd, ubyte* buffer, uint count); ``` We can now go ahead and use this function as a call such as with: -``` {.d .numberLines} +``` d extern efunc uint write(uint fd, ubyte* buffer, uint count); void test() @@ -75,13 +75,13 @@ followed by the variable declaration (type and name). Below we have an example of the `ctr` variable from our C program seen earlier being specified: -``` {.d .numberLines} +``` d extern evar int ctr; ``` We have the same program as before where we then refer to it with: -``` {.d .numberLines} +``` d ... extern evar int ctr; diff --git a/docs_src/language/33-types.md b/docs_src/language/33-types.md index 5a6027d..ae1cecb 100644 --- a/docs_src/language/33-types.md +++ b/docs_src/language/33-types.md @@ -11,7 +11,7 @@ Primitive data type are the building blocks of which other more complex types ar ### Integral types | Type | Width | Intended interpretation | -|-|-|-| +|------|-------|-------------------------| | byte | 8 | signed byte (two's complement) | | ubyte | 8 | unsigned byte | | short | 16| signed short (two's complement) | diff --git a/helpers.sh b/helpers.sh index c65799b..455636d 100644 --- a/helpers.sh +++ b/helpers.sh @@ -37,7 +37,7 @@ function generateMarkdown() outputFile="docs/$(echo $doc | cut -b 9-)" - pandoc -F pandoc-plot -M plot-configuration=pandoc-plot.conf -f markdown -t markdown "$doc" -o "$outputFile" + pandoc -F pandoc-plot -M plot-configuration=pandoc-plot.conf -f markdown -t gfm "$doc" -o "$outputFile" echo "$(cat $outputFile | sed -e s/docs\\//\\/projects\\/tlang\\//)" > "$outputFile" cat "$outputFile"