Skip to content

Releases: Program132/GW

V1.1 : Native functions

19 Feb 21:27

Choose a tag to compare

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

New Features

⌨️ I/O Module (#1)

  • Added file operations: read, write, append.
  • Enhanced Console I/O: color, clear, cursor manipulation.
  • 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 Time module with a better precision about timestamps.
  • Comprehensive documentation in doc/native/.

Happy Coding with GW 1.1!

V1.0 - A new start with GW

17 Feb 18:42

Choose a tag to compare

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:

  • Integer
  • Number
  • Boolean
  • String
  • Character

Flow Control

The language includes essential control structures:

  • if and else conditionals
  • while loops
  • for loops

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');