Last active
October 5, 2019 16:29
-
-
Save aaronfranke/89e5c7c13b3527b5210ae61c0e7b9caf to your computer and use it in GitHub Desktop.
Prototype syntax for "Aaron Language", my dream programming language.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This is a prototype syntax for "Aaron Lang". | |
# Inspired by C#, C++, GDScript, and Python. | |
# I doubt this would ever be a thing, but it shows what I would put in "the perfect language" | |
# The file is ".py" to make GitHub display the comments as a different color, but to be clear, this is nowhere close to Python. | |
# Comments are defined with "# " at the start. | |
# This is because "//" is used for math (floor division). | |
/* Inline and multi-line comments are also supported, but I only use the hash in this file */ | |
# Methods can be in the global scope with no namespace. | |
# Main method is in the global scope and has no namespace. | |
# Main method returns int (like C++) and takes in a string array (like C#). | |
int Main (string[] args) | |
{ | |
# C++ style indentation. Tabs standard for indentation, and language does not depend on indentation. | |
# Part of the language, also in global namespace. Writes to STDOUT. | |
Print("Hello World!"); | |
# Method declarations do have a space before parenthesis. | |
# Method calls do NOT have a space before the parenthesis. | |
# This mostly just looks nice to me. | |
# Searches ahead automatically, no need for C++ forward declarations or header files. | |
int five = Math.Abs(-5); | |
# Constructors do not need the type repeated, just use "();". Type inferred from left. | |
# This is pretty much the opposite of what Python and GDScript do. | |
Math.Vector2i m = (1, 2); | |
# Namespaces can be added directly into functions, or other namespaces, or at the top of a file. | |
using Math; | |
# No need to write "Math.Vector2i", but it still would work. | |
Vector2i v = (1, 2); | |
five = Abs(-5); # Would need to be Math.Abs if there wasn't "using Math;" above. | |
# For polymorphism, you must create the object separately from its final container. | |
MySecret mySec = (); | |
Secret sec = mySec; | |
# Now sec contains a MySecret object. | |
# One would typically have separate a declaration anyway, inline polymorphism isn't very clear. | |
# C# code such as "Secret test = new MySecret();" seems confusing, strange, and niche to me. | |
# Decimal number literals can be written as "1.2" etc, no need for "1.2f". | |
Vector2 v = (1.2, 3.4); | |
} | |
namespace Math; | |
# Functions can exist directly in a namespace without a class, similarly to how Main exists without a class. | |
# Yet you are still able to create objects via classes and structs. | |
# This makes the language object-capable, while not requiring object-oriented for all code. | |
# Namespace functions take the place of "static class" in C# (but class members can still be static). | |
# I would rather have an "import-able" Math namespace that holds functions, than write "Math.Whatever" each time. | |
# See above with the "using Math;" line in Main if you're not sure of what I mean. | |
# C-like syntax, return type, name, arguments. | |
int Abs (int s) | |
{ | |
return s < 0 ? -s : s; # Ternary operator | |
} | |
# Namespaces can also contain classes and structs. | |
struct Vector2 | |
{ | |
real x, y; | |
# Real is abstract and precision is controlled by compiler flags. | |
# For explicit precision, use "float32" or "float64" etc. | |
# There would probably also be "float" and "double" aliases for familiarity's sake. | |
real Length () | |
{ | |
return Sqrt(x*x + y*y); | |
# A call for Sqrt here checks for the existence of Vector2.Sqrt, Math.Sqrt, and global Sqrt. | |
# Locality takes priority. It searches Vector2 first, then Math, then global. | |
# If there's a conflict, you can be explicit: "this.Sqrt" or "Math.Sqrt" or "Global.Sqrt". | |
} | |
Vector2 (real X, real Y) | |
{ | |
x = X; | |
y = Y; | |
} | |
} | |
# Structs are pass-by-value and don't use pointers or references. | |
# Classes are objects, fields for classes are references to them. Just like C++ and C#. | |
# Namespaces can be defined multiple times, so you can add your own code to Math. | |
# Note: A default Math namespace would be distributed with the language itself as a standard library. | |
struct Vector2i | |
{ | |
int x, y; | |
# Int is abstract and size is controlled by compiler flags. | |
# For explicit size, use "int32" or "int64" etc. | |
real Length () | |
{ | |
return Sqrt(x*x + y*y); # Sqrt accepts reals, which the ints are implicitly casted to. | |
} | |
int LengthSquared () | |
{ | |
return x*x + y*y; | |
} | |
Vector2i (int X, int Y) | |
{ | |
x = X; | |
y = Y; | |
} | |
} | |
# Note how Math.Vector2 is defined above as well. | |
# Similarly to multiple namespaces, classes and structs can be defined multiple times to add stuff to them. | |
# This allows adding code to classes and structs without creating a second class that extends it. | |
# Why: Does the standard library Vector2 not have a function you need? Don't re-write your own Vector2, just add to it! | |
# This also means that all Vector2 are the same and cross-compatible, no need to convert | |
# "YourProgram.YourVector2" to "Math.Vector2" before using it in the default Math namespace. | |
# Conflicting code additions could be handled by warnings, or by specifying | |
# an inheritance order, or requiring an "override" keyword. | |
struct Vector2 | |
{ | |
real LengthSquared () | |
{ | |
return x*x + y*y; | |
} | |
} | |
namespace Testing123 | |
{ | |
# Protected would be publicly visible, but its members are private by default. | |
# Private would be visible only in the namespace, and have private members by default. | |
# Internal would be visible only in the namespace, and have public members by default. | |
# Public would be publicly visible and have public members. | |
# Public is default unless the namespace itself has the an access modifier (relative to parent namespace). | |
protected class Secret | |
{ | |
int a; # Private | |
public real b; # Public | |
# Like C# properties, access control can be imposed like this: | |
public int c | |
{ | |
get; # Default getter, same as "get: return value;" | |
#get: return value + 1; # Would returns the value plus one if uncommented. | |
# Alternative syntax: | |
#get: | |
#{ | |
#return value + 1; | |
#} | |
# Getters/setters can have multi-line code blocks with "{}" | |
set: | |
{ | |
int temp = Abs(input); # "input" is the variable fed into setters, such as with "c = 5;" | |
value = temp; # "value" always means the variable's value. Only valid inside getters/setters. | |
} | |
} | |
# Basically, "c" here would be a variable that can't be negative, | |
# setting itself to the absolute value of what you give it. | |
# No particular reason for this, it's just a demonstration. | |
} | |
# Traits can add code to classes and structs. They are like C# interfaces, but with default implementations. | |
trait PrintStuff | |
{ | |
void PrintHello () | |
{ | |
Print("Hello!"); | |
} | |
# Yes this function is pretty useless. It's for simple demonstration purposes. | |
void PrintInt (int s) | |
{ | |
Print(s); # Implicit cast to string. | |
} | |
void PrintNumber (real s) | |
{ | |
# Primitive types can have methods called on them. | |
# Prints 3 decimal places, including trailing zeros. | |
Print(s.ToString("0.000")); | |
} | |
} | |
# Traits can extend other traits with ":". | |
trait PrintStuffAndFive : PrintStuff | |
{ | |
void PrintFive () | |
{ | |
PrintInt(5); | |
} | |
} | |
# Traits are added to objects with a "can" keyword. | |
class MySecret : Secret can PrintStuff | |
{ | |
void PrintB () | |
{ | |
PrintNumber(b); | |
# Functionality obtained via PrintStuff. | |
# "b" is a variable in the Secret class. | |
# Remember that this is the 2nd declaration of MySecret which adds code to the original declaration. | |
} | |
} | |
# Show warnings when files are using CRLF and/or UTF-8 w/ BOM. | |
# Also, compile warnings if 3+ newlines are found in the middle of a file. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment