Releases: Program132/GW
V1.1 : Native functions
GW Language v1.1.0
This release introduces native modules, you can now build web servers, manipulate files, execute system commands, and more!
Issues solved
- Native functions: Input Output
- Native functions: Sys / OS
- Native functions: Network / Socket
- Native functions: String Utilities
New Features
⌨️ I/O Module (#1)
- Added file operations:
read,write,append. - Enhanced Console I/O:
color,clear,cursormanipulation. - Pipe support (
stdin,stdout) for CLI redirection.
🖥️ System Module (#2)
- Added OS interaction:
exec,exit,is_windows/linux/mac. - Command Line Arguments support:
get_arg_count(),get_arg(i).
🌐 Network Module (#3)
- Implemented
__native_socket_*primitives. - Support for TCP Client & Server.
- Added
connect,send,receive,bind,listen,accept. - Example: Built a working HTTP Server in pure GW!
📝 String Utilities (#4)
- Added native string manipulation:
length,at - Base for building "complex" strings
🕛 Other Improvements
- Updated
Timemodule with a better precision about timestamps. - Comprehensive documentation in
doc/native/.
Happy Coding with GW 1.1!
V1.0 - A new start with GW
GW V1.0 - Release Notes
GW is an object-oriented interpreted programming language designed to combine features from several existing languages into a single cohesive experience. It draws inspiration from well-known languages such as Python, C++, Java, and Kotlin.
Key Features
Types
GW supports standard data types found in most modern languages:
IntegerNumberBooleanStringCharacter
Flow Control
The language includes essential control structures:
ifandelseconditionalswhileloopsforloops
Object-Oriented Programming & Structs
GW offers a flexible object system. Although it currently does not enforce access modifiers (private/public/protected), features include:
- Class definition and instantiation
- Inheritance (
extends) - Operator overloading
- Multiple constructors
- Static and instance methods
Additionally, structs are available as lightweight data containers—effectively classes without methods.
C++ Interoperability
GW is designed to be hackable. You can fork or clone the project and extend it as needed.
The language natively supports defining functions in C++ that are callable from GW code.
Example: Defining a Native Function
inline Value __nativeTime(const std::vector<Value> &args) {
if (args.size() != 0) {
throw std::runtime_error("[GW NATIVE] time() takes 0 arguments");
}
return Value((int)std::time(nullptr));
}Registering in main.cpp
void registerNatives(Interpreter &interpreter) {
// ...
interpreter.addNativeFunction("__native_time", __nativeTime);
// ...
}Full Changelog: https://github.com/Program132/GW/commits/V1.0
Examples
List.gw
Implementation of a Linked List demonstrating classes, constructors, methods, and recursion.
class IntList {
val: Integer,
next: IntList
constructor(val: Integer) {
this.val = val;
this.next = null;
}
constructor(val: Integer, next: IntList) {
this.val = val;
this.next = next;
}
func append(a: Integer) -> Integer {
if (this.next == null) {
this.next = IntList(a);
return 0;
}
this.next.append(a);
return 0;
}
func get(index: Integer) -> Integer {
if (index == 0) {
return this.val;
}
if (this.next == null) {
return null;
}
return this.next.get(index - 1);
}
func pop() -> Integer {
if (this.next == null) {
return this.val;
}
if (this.next.next == null) {
var val = this.next.val;
this.next = null;
return val;
}
return this.next.pop();
}
func str() -> String {
if (this.next == null) {
return "" + this.val;
}
return "" + this.val + ", " + this.next.str();
}
}
var list = IntList(1);
list.append(2);
list.append(3);
println(list.get(1));
println(list.str());
println(list.pop());
println(list.pop());
println(list.pop());
println(list.str());Time.gw
A demonstration of native function usage and complex logic (UTC Date calculation) implemented purely in GW.
class DateUtils {
static func isLeapYear(year: Int) -> Boolean {
if (year % 400 == 0) { return true; }
if (year % 100 == 0) { return false; }
if (year % 4 == 0) { return true; }
return false;
}
static func getDaysInMonth(month: Int, year: Int) -> Int {
if (month == 2) {
if (DateUtils.isLeapYear(year)) { return 29; }
return 28;
}
if (month == 4 || month == 6 || month == 9 || month == 11) {
return 30;
}
return 31;
}
static func div(a: Int, b: Int) -> Int {
return (a - (a % b)) / b;
}
static func getMonthName(month: Int) -> String {
if (month == 1) { return "Jan"; }
if (month == 2) { return "Feb"; }
if (month == 3) { return "Mar"; }
if (month == 4) { return "Apr"; }
if (month == 5) { return "May"; }
if (month == 6) { return "Jun"; }
if (month == 7) { return "Jul"; }
if (month == 8) { return "Aug"; }
if (month == 9) { return "Sep"; }
if (month == 10) { return "Oct"; }
if (month == 11) { return "Nov"; }
return "Dec";
}
static func getDayName(dayIndex: Int) -> String {
if (dayIndex == 0) { return "Sun"; }
if (dayIndex == 1) { return "Mon"; }
if (dayIndex == 2) { return "Tue"; }
if (dayIndex == 3) { return "Wed"; }
if (dayIndex == 4) { return "Thu"; }
if (dayIndex == 5) { return "Fri"; }
return "Sat";
}
static func timestampToString(ts: Int) -> String {
var seconds = ts;
var minutes = DateUtils.div(seconds, 60);
seconds = seconds % 60;
var hours = DateUtils.div(minutes, 60);
minutes = minutes % 60;
var totalDays = DateUtils.div(hours, 24);
var dayOfWeek = (4 + totalDays) % 7;
var days = totalDays;
hours = hours % 24;
var year = 1970;
var daysInYear = 365;
while (true) {
daysInYear = 365;
if (DateUtils.isLeapYear(year)) {
daysInYear = 366;
}
if (days < daysInYear) {
break;
}
days = days - daysInYear;
year = year + 1;
}
var month = 1;
var daysInMonth = 0;
while (true) {
daysInMonth = DateUtils.getDaysInMonth(month, year);
if (days < daysInMonth) {
break;
}
days = days - daysInMonth;
month = month + 1;
}
var day = days + 1;
var dayName = DateUtils.getDayName(dayOfWeek);
var monthName = DateUtils.getMonthName(month);
var timeStr = "";
if (hours < 10) { timeStr = timeStr + "0"; }
timeStr = timeStr + hours + ":";
if (minutes < 10) { timeStr = timeStr + "0"; }
timeStr = timeStr + minutes + ":";
if (seconds < 10) { timeStr = timeStr + "0"; }
timeStr = timeStr + seconds;
var dayStr = "" + day;
if (day < 10) { dayStr = " " + day; }
return dayName + " " + monthName + " " + dayStr + " " + timeStr + " " + year;
}
}
class Time {
static func now() -> Int {
return __native_time();
}
static func sleep(seconds: Int) {
__native_sleep(seconds);
}
static func ctime(timestamp: Int) -> String {
return DateUtils.timestampToString(timestamp);
}
}
# Test Logic
print("UTC Date for 0 (1970-1-1): " + Time.ctime(0));
print('\n');
print("UTC Date for 2000 (1970-1-1 + 2000s): " + Time.ctime(2000));
print('\n');
print("UTC Date for 400000000 (1982-9-5): " + Time.ctime(400000000));
print('\n');
var now = Time.now();
println("Timestamps (now): " + now);
print("Current UTC Time: " + Time.ctime(now));
print('\n');