Skip to content

vinvicta/gs2-parser

 
 

Repository files navigation

gs2-parser

A compiler and disassembler for the Graal Script 2 (GS2) language used in GraalOnline games.

Features

  • GS2 Compiler: Convert GS2 source code (.gs2, .txt) to bytecode (.gs2bc)
  • GS2 Disassembler: Disassemble bytecode files to human-readable format
  • Full AST-based compilation: Proper parsing and semantic analysis
  • Multi-file support: Process multiple files or directories at once
  • WASM support: Compile to WebAssembly for browser usage

Prerequisites

Before building, clone the repository and recursively clone the submodules:

git clone https://github.com/vinvicta/gs2-parser.git --recursive
cd gs2-parser

Dependencies

  • CMake (3.10+)
  • C++ Compiler (C++17 support required: GCC 7+, Clang 5+, MSVC 2017+)
  • Bison (3.4+)
  • Flex (2.6+)

Ubuntu/Debian

sudo apt-get install cmake g++ bison flex

macOS

brew install cmake bison flex

Windows (with vcpkg)

vcpkg install cmake bison flex

Building

Native Build

mkdir build
cd build
cmake ..
make -j$(nproc)

The executable will be created at ../bin/gs2test.

WebAssembly Build

First, ensure you have Emscripten installed. Then:

mkdir build
cd build
emcmake cmake ..
make -j$(nproc)

The resulting gs2test.js and gs2test.wasm files can be imported into a webpage.

Usage

Compiler

Basic usage:

./bin/gs2test script.gs2
# Creates: script.gs2bc

With custom output:

./bin/gs2test script.gs2 -o output.gs2bc

Verbose mode:

./bin/gs2test script.gs2 -v

Disassembler

The disassembler converts .gs2bc bytecode files to human-readable disassembly.

Basic disassembly:

./bin/gs2test script.gs2bc -d
# Creates: script.gs2

With custom output:

./bin/gs2test script.gs2bc -d -o disassembled.gs2

Verbose disassembly:

./bin/gs2test script.gs2bc -d -v

Command-Line Options

GS2 Script Compiler/Disassembler

Usage:
  gs2test [OPTIONS] INPUT [OUTPUT]
  gs2test INPUT -o OUTPUT
  gs2test --help

Arguments:
  INPUT              Input file (.gs2, .txt, or .gs2bc) or directory
  OUTPUT             Output file (.gs2bc for compile, .gs2 for disassemble)

Options:
  -o, --output FILE  Specify output file
  -d, --disassemble  Disassemble .gs2bc to .gs2 format
  -v, --verbose      Verbose output
  -h, --help         Show this help message

Examples:
  gs2test script.gs2                    # Creates script.gs2bc (compile)
  gs2test script.gs2bc -d               # Creates script.gs2 (disassemble)
  gs2test script.gs2 output.gs2bc       # Creates output.gs2bc
  gs2test script.gs2bc -o output.gs2 -d # Creates output.gs2 (disassemble)
  gs2test scripts/                      # Process directory
  gs2test file1.gs2 file2.gs2 file3.gs2 # Process multiple files

Multi-File and Directory Processing

Process a directory:

./bin/gs2test scripts/

Process multiple files:

./bin/gs2test file1.gs2 file2.gs2 file3.gs2

Disassembler Output

The disassembler generates a human-readable disassembly showing:

  • Function structure and names
  • String constants from the string table
  • Opcode names and descriptions
  • Operands (numbers, strings, jump offsets)

Example output:

function onCreated() {
  // Function: onCreated
  // Opcodes: 52 bytes
  // OP_SET_INDEX
  // OP_TYPE_ARRAY
  // OP_FUNC_PARAMS_END
  // OP_JMP 2493
  // OP_TYPE_VAR "x"
  // OP_MEMBER_ACCESS
  // OP_TYPE_NUMBER 5
  // OP_ASSIGN
  // OP_TEMP
  // OP_TYPE_VAR "y"
  // OP_MEMBER_ACCESS
  // OP_TYPE_NUMBER 10
  // OP_ASSIGN
  // OP_TYPE_ARRAY
  // OP_TYPE_STRING "Result: "
  // OP_TEMP
  // OP_TYPE_VAR "x"
  // OP_MEMBER_ACCESS
  // OP_CONV_TO_FLOAT
  // OP_TEMP
  // OP_TYPE_VAR "y"
  // OP_MEMBER_ACCESS
  // OP_CONV_TO_FLOAT
  // OP_ADD
  // OP_CONV_TO_STRING
  // OP_JOIN
  // OP_TYPE_VAR "echo"
  // OP_CALL
  // OP_INDEX_DEC
  // OP_TRUE
  // OP_RET
}

Bytecode Format

GS2 bytecode files (.gs2bc) consist of 4 segments:

  1. GS1 Flags Segment (type 1)

    • Bitflags for GS1 events
  2. Function Table Segment (type 2)

    • List of functions with their opcodes and names
    • Format: [opIndex: 4 bytes][functionName: null-terminated string]
  3. String Table Segment (type 3)

    • All string constants used in the script
    • Format: [string: null-terminated]
  4. Bytecode Segment (type 4)

    • The actual bytecode instructions
    • Format: [opcode: 1 byte][operands: variable]

Dynamic Number Encoding

Numbers are encoded with a prefix byte:

  • 0xF0-F2: Signed integers (1, 2, 4 bytes)
  • 0xF3-F5: Numbers after OP_TYPE_NUMBER (1, 2, 4 bytes)
  • 0xF6: Double-precision float (as null-terminated string)

Architecture

The compiler uses a multi-stage pipeline:

  1. Lexical Analysis: Flex-based scanner tokenizes GS2 source
  2. Parsing: Bison-based parser builds Abstract Syntax Tree (AST)
  3. Semantic Analysis: Type checking and symbol resolution
  4. Code Generation: Visitor pattern emits bytecode
  5. Optimization: Jump label resolution and optimization

The disassembler performs bytecode analysis:

  1. Segment Parsing: Reads bytecode segments (flags, functions, strings, bytecode)
  2. Instruction Decoding: Parses opcodes and operands
  3. Symbol Resolution: Extracts string table and function names
  4. Disassembly Generation: Produces human-readable output

Key Components

  • src/parser.y: Bison grammar for GS2 language
  • src/scanner.l: Flex lexer for tokenization
  • src/ast/: AST node definitions
  • src/visitors/GS2CompilerVisitor.cpp: Bytecode emission
  • src/visitors/GS2Decompiler.cpp: Bytecode parsing and disassembly
  • src/GS2Bytecode.cpp: Bytecode buffer management
  • src/opcodes.h: Opcode definitions and mappings

Testing

Run the test suite:

cd build
make run-tests

Generate test baselines:

make test-baselines

Clean test artifacts:

make test-clean

License

This project is licensed under the MIT License - see the LICENSE file for details.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Acknowledgments

  • Original compiler by xtjoeytx
  • Disassembler implementation by vinvicta
  • Based on the GraalOnline GS2 language specification

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages

  • C++ 71.0%
  • Python 7.9%
  • Yacc 7.3%
  • Shell 4.8%
  • CMake 3.0%
  • Rust 2.0%
  • Other 4.0%