Welcome to the Pineapple Programming Language
Pineapple is the name of the language. Iwa is the name of the compiler I built for it. Iwa generates C code, and utilizes clang to compile the C code. Pineapple gets translated into an intermediate language using Python that is easier to work with, that is then used when generating C code. This intermediate code can then be easily made compatible with any compiler.
The language has very specific rules of how syntax is allowed, and ordered, allowing for a parser to be very easily made. In attempt to truly bridge the gap in transcompiling between languages. I want to make an attempt at creating a unified system to tokenize, and communicate between languages.
You can think of every line as a statement. A line can contain two statements, but the philosophy of the languages asks for modularity, and to conform to the single-responsibility principle, within reason.
We have opening, and closing tokens for code blocks containing multiple statements, and most importantly, all variables are immutable by default, and when the values are changed, if they are not assigned, they are not held.
Pineapple's memory management aims to be simple, easy to use, and east to extend. Iwa analyzes the source code you feed it, and attempts to create a memory safe program by testing against the bounds of each variable.
Everything is dynamically allocated otherwise, and if you need to take control of memory, you can access the heap exactly how you would an array.
All Int's are 64 bit signed integers by default unless otherwise compiling for a 32 bit system.
Pineapple explicitly supports standard implementions over backwards compatibility, and future proofing.
Therefore an expectation is allowed that you have access to the largest forms of data structures allowed by the system.
When you download the compiler for 32 bit systems, they will be 32 bit integers.
The `O` flag when compiling will tell Iwa to optimize, and finds the outer bounds of each integer case, and utilize a integer will less bits if allowed.
This will probably be a slow build as the project grows, but it's also probably necessary, and I'll hopefully optimize it overtime.
Int X = 5;
Int Y = 6;
Out(&0);
Outputs
5
You can assign values using this method:
&0 = "I'm a string";
Outputs
ERROR | &0 = "I'm a string";
^ is typed: Int, cannot implicitly cast to: Str
Explicit Cast Example:
Str Greeting:&0 = "I'm a String"
Pineapple's memory space accepts the ultimate foot-gun in favor of an explicit, and simplistic knowledge on how it works. Everything in the program is bounded, living, and accessible. Everything outside of the program is not accessible.
The Iwa compiler tests all accessible bounds, and determines if the declarative bounds are measurable. If they are not, you will be provided an error at compile time dependant on the context, and you will have to flag the specific variable UNBOUNDED, or you will have to guard against it's bounds.
Int Health = 50;
Str FirstName = Roger;
Str LastName = Rabbit;
Str FullName = "{FirstName} {LastName}";
Str Multiline = | # Always skips the first new line #
This is
a multiline
string.
; # Also skips the last new line #
# Strings are arrays as always, and can be index, and sliced. Slices are inclusive. #
Str Greeting = "Hello there!";
Str Hello = Greeting[0:4];
Dct Students = [
"Kevin":14,
"Bill":15,
"Julia":14,
]
Int X = 5; # Default to system word size #
Int64 Y = 1000000000000; # Explicitly 64-bit #
Int8 Z = 100; # Explicitly 8-bit #
Fnc ParseData(Int32 Data) {
# Function that explicitly works with 32-bit integers #
}
# Compiler error that this will overflow: #
Int8 Small = 256;
Pineapple attempts to take on a form of test-driven philosophy during compilation. Iwa will not let you compile what it thinks to be an unsafe program unless you painstakingly accept the consequences. This means that you should never ship a production product that does not check against it's bounds before compile time. All bounds are checked at 2 million by default.
Str Food = In("What is your favorite food?");
If Food == "Grapefruit" {
Out("I don't like this food.");
} Or Food == "Strawberries" {
Out("I like this food.");
} Else {
Out("I don't know about this food.");
}
# `not in` is a thing #
Lst Students = ["Jeffery", "Sara", "Kevin"];
If "Aaron" not in Students {
Students.Append("Aaron");
}
Lst Fruits = ["Oranges", "Apples", "Bananas"]
For Str Fruit in Fruits {
Out(Fruits);
}
Dct Students = [
"Kevin":14,
"Bill":15,
"Julia":14,
]
For Str Name, Int Age in Students{
Out("{Name} is {Age} years old");
}
Fnc Sum(Int X, Int Y){
Return X + Y;
}
Sum(Int 5, Int 7)
Obj Person {
Fnc Init(Str InitialName){
# All Object variables are fully scoped to the object,
and can be accessed from any method without any notation. #
Str Name = InitialName;
}
}
Obj Human {
Fnc Init(Str InitialName){
Int Age = InitialAge;
}
}
Obj Person | Human {
Fnc Init(Str InitialName, Int InitialAge){
Str Name = InitialName;
}
Fnc Greeting(){
Return "Hello, my name is {Name}, and I'm {Age} years old.";
}
}