print(syntax)

Ok, it’s time to introduce some of the syntax and features of my language. Having already gone over the requirements and goals of this language in earlier posts, I won’t reiterate them here.

First, I’m quite accustomed to the idea of visual connectivity. While Python is nice in simplicity, I lean more towards the curly-bracket approach. All executing bodies of code should be surrounded by curly brackets. The exception to this rule is that there is no “main” function, so it mutually shares the run-everything-found-first rule with Python. Furthermore, parameters for functions, if-statement structures, and such are all enclosed by parentheses; no related-by-proxy rules. Visually connectivity is important primarily for related things, so side-by-side objects aren’t necessarily related. What relates them is by certain key tokens, such as the symbol indicating assignment of one to the other.

Second, the simplification of syntax can be done by following a bare-minimums principle: Use the bare minimum necessary to convey a perfectly valid idea. That said, the parse tree is relatively straight-forward for the most part.

expr = {
	variable
	fn
	execution body
	if
	loop
	skip
	stop
	ret
	own
}

variable -> [	
	/
	assignment
	pointer assignment
	parameter body
]

fn -> [
	construction parameter body -> execution body		
	execution body
]

if -> parameter body -> execution body -> [
	/
	elif -> parameter body -> execution body
	else -> execution body
]

loop -> execution body

assignment = symbol -> [
	expr
	data
]

pointer assignment = symbol -> [
	variable
]

construction parameter body = {
	open symbol -> start: [
		name -> [
			assignment -> start
			pointer assignment -> start
		]
		close symbol
	]
}

parameter body = {
	open symbol -> start: [
		name -> [
			assignment -> start
			pointer assignment -> start
		]
		close symbol
	]
}

execution body = {
	open symbol -> start: [	
		expr -> start
		close symbol			
	]
}

“expr” denotes “expression”. An expression is raw code. The backslash (“/”) indicates than nothing may follow, effectively ending an expression statement. The curly brackets indicate what that part of the tree is composed off, and they contain all of the available options that make up such an expression. The square brackets indicate the optional endings that MUST follow a given option. “start” is used as a goto label within the section of the parse tree it is found. That said, it should be fairly obvious now how it’s used.

One thing not explicitly stated here is that “if” control structures require a conditional parameter body – that is, a parameter body that works much like other parameter bodies but results in a boolean value. As I may explain later, this language uses an explicit boolean.

Notice in this that there are no “end-statement” indicators (usually a single token). This is deliberate. While there is technically an available token dedicated to this purpose, it isn’t needed. As you can see, the syntax tree is complete without it.

This parse tree is beautiful to me. The one for the latest Goldfish was shorter to write and messier to work with, so almost anything would seem to be an improvement over that, but I do find this new tree to be delightful on its own. Sadly, I may have forgotten to add something.

Without looking at an example, there are a few things that should be pointed out about this parse tree.

First, we have variables. Variables only store functions. They are created via declaration of only their name, which must be an unused word (which, at the current time, is permitted as Unicode). Consequently, a reserved keyword for creating variables would be pointless. Function names can optionally be followed by a direct assignment of an object (be it a number, string, or perhaps another function) or a pointer assignment (in which case, they point to another variable). More explanation of the rules on that later. Thirdly, they can be followed by a body of parameters. What does this mean? – By being followed by a body of parameters, the function can be run. At the moment, we’re not really concerned with the exact syntax of these things are how it works, but these things are rather simple.

There are a number of reserved keywords in the parse tree. The “if” and “loop” create control structures, which are fundamentally important for performing useful operations. The role of these can be shown best by example as neither is very complicated. The “stop” keyword relates to the “loop” keyword in that it is designed to terminate a loop and nothing else.

The “fn” keyword is used for creating functions. Alternately, the execution body can also be used for creating functions. The syntax in each case is straightforward and best shown by example, but “fn” has a couple of special aspects that will be discussed in more detail later.

For functions, there is a reserved keyword called “ret”. This is the return-value keyword, and it is used to signal the currently open function to return the next object. Having created this tree a while ago, I have since modified the “ret” keyword to be a system function that does effectively the same thing but looks more natural for the language.

Lastly, there is a reserved keyword called “own”. Secretly, it is a control structure (because of how it works), but it acts like a function, so there is nothing more to be added to the tree.

~ Fizz Buzz and Beyond ~

Now that you’ve seen the parse tree and have a general overview of what is going on, what does the language actually look like? Below is an overly complicated example of FizzBuzz that represents many of the essentials:

fizzbuzz = fn(i) {
	if ( eq( %(i() 15) 0 ) ) {
		ret "FizzBuzz"
	}	
	elif( eq( %(i() 5) 0 ) ) {
		ret "Buzz"
	}	
	elif( eq( %(i() 3) 0 ) ) {	
		ret "Fizz"
	}
	else {
		ret i()
	}
}

i = 0
fizzy~fizzbuzz
loop {
	if ( gte(i() 100) ) {	
		stop	
	}
	print( fizzy(i) )
	i = +(i() 1)
}

There are a couple of key features not shown (namely “this” and “super”), but everything above should suffice to give you a good introduction to the language.

There are a few expected built-in functions: “%”, “eq”, “gte”, and “print”, which respectively perform modulus, check equality, check for greater than or equality, and print to the console. In the interpreter, these will likely be extensions. They are used here to give you an idea of how a typical program might look.

There are three variables used in this program – “i”, “fizzbuzz”, and “fizzy”. The weird syntax between “fizzy” and “fizzbuzz” indicates pointer-creation. The variable “fizzy” has been made a pointer to the function “fizzbuzz” holds. All three variables – “i”, “fizzbuzz”, and “fizzy” – can be used in the exact same way; there is no need for some sort of specialized syntax for pointers.

Notice that there is no main() function. Like Python, the user program is understood progressively. Languages like JavaScript (and Goldfish) allow the interpreter to take the time to scan the global namespace for function names. This is slow, and the only advantage it gives is allowing functions to be in whatever order you wish. If this language were intended to be compiled, my evaluation would be different no doubt, but this language is not designed to be compiled anyways.

At this point, it’s difficult to say much more about the language itself due to its sheer simplicity. There are no end-statement tokens, though as you might wish, there is a token that can be used to visually separate variables within function calls, function creation, and variable declarations. It isn’t needed and therefore isn’t shown.

Stand-alone parentheses in many languages are used for grouping operations and making the code more readable. In a stroke of irony, they would actually worsen the code in a language such as this. Hence, I have excluded such a feature. Why would they make it worse? Considering the parse tree, variables don’t need to be initialized. As whitespace is not recognized, the following would appear to be a function call:

a
( 2 )

Moreover, grouping operations is needless in this language because operations are already grouped within the parameter bodies of functions.

In future articles, I’ll cover useful paradigms that can be implemented, allowing this language to mimic the functionality and structure of many other languages.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s