Kylin

From Esolang
Jump to navigation Jump to search

Kylin is an Object-oriented programming language designed by PSTF.

Overview

Basic Structure of Programs

class Main {
    main() {
        # Your code
    }
}

Yes, even a program is in class, just like Java!

Data types

  1. Integer
  2. Floating point number
  3. String Literal
  4. Boolean value
  5. Dynamic list

All functions are called 'methods' rather than the more common 'subroutines', 'functions', or 'lambdas'.

Type conversion table
↓To From→ Integer Float String Boolean List
Integer As-is round(x) parseInt(x) x ? 1 : 0 length(x)
Float x * 1.0 As-is parseFloat(x) x ? 1.0 : 0.0 length(x) * 1.0
String toStr(x) toStr(x) As-is x ? "true" : "false" "[" + ", ".join(x) + "]"
Boolean x != 0 x != 0.0 !x.empty() As-is !x.empty()
List [x] [x] [x] [x] As-is

I/O

input(__prompt) # Get and return a line of user_input.
evaluated_input(__prompt) # Evaluated input.
print(*args, **kwargs, sep = " ", end = "\n") # Print something.

Each command is separated by a semicolon. If there is no semicolon between two commands, it cannot be interpreted syntactically.

Lists

list numbers = [2, 3, 5, 7, 13, 15, 18, 19];
numbers.append(17);
numbers.insert(11, 4);
numbers.replace(6, 19);
x = numbers.pop(-1);
numbers.delete(-1);

Implementation in Python

import re
import sys
from typing import Any, Dict, List, Optional, Union

class KylinInterpreter:
    def __init__(self):
        self.variables = {}
        self.classes = {}
        self.current_class = None
        self.call_stack = []
        
    # Data types
    class KylinList:
        def __init__(self, elements=None):
            self.elements = elements or []
            
        def get(self, index):
            if 0 <= index < len(self.elements):
                return self.elements[index]
            return None
            
        def add(self, element):
            self.elements.append(element)
            
        def size(self):
            return len(self.elements)
            
        def __str__(self):
            return str(self.elements)
    
    class KylinClass:
        def __init__(self, name, parent=None):
            self.name = name
            self.parent = parent
            self.methods = {}
            self.fields = {}
            
        def call_method(self, method_name, interpreter, args):
            if method_name in self.methods:
                return interpreter.execute_function(self.methods[method_name], args, self)
            elif self.parent:
                return self.parent.call_method(method_name, interpreter, args)
            return None
    
    def execute(self, code):
        lines = code.split('\n')
        for line in lines:
            line = line.strip()
            if line and not line.startswith('//'):
                self.execute_line(line)
    
    def execute_line(self, line):
        # Class definition
        if line.startswith('class '):
            self.parse_class(line)
        # Method definition
        elif '()' in line and '{' in line and self.current_class:
            self.parse_method(line)
        # Variable assignment
        elif '=' in line:
            self.parse_assignment(line)
        # Method call
        elif '.' in line and '(' in line and ')' in line:
            self.parse_method_call(line)
        # Print statement
        elif line.startswith('print('):
            self.parse_print(line)
        # Input statement
        elif line.startswith('input('):
            self.parse_input(line)
        # If statement
        elif line.startswith('if '):
            self.parse_if(line)
        # While loop
        elif line.startswith('while '):
            self.parse_while(line)
        # Return statement
        elif line.startswith('return '):
            return self.parse_expression(line[7:].strip())
    
    def parse_class(self, line):
        match = re.match(r'class\s+(\w+)(?:\s+extends\s+(\w+))?\s*\{', line)
        if match:
            class_name = match.group(1)
            parent_name = match.group(2)
            parent = self.classes.get(parent_name) if parent_name else None
            self.current_class = self.KylinClass(class_name, parent)
            self.classes[class_name] = self.current_class
    
    def parse_method(self, line):
        match = re.match(r'(\w+)\(\)\s*\{', line)
        if match and self.current_class:
            method_name = match.group(1)
            self.current_class.methods[method_name] = line
    
    def parse_assignment(self, line):
        var, expr = line.split('=', 1)
        var = var.strip()
        value = self.parse_expression(expr.strip())
        if self.current_class:
            self.current_class.fields[var] = value
        else:
            self.variables[var] = value
    
    def parse_expression(self, expr):
        # String literals
        if expr.startswith('"') and expr.endswith('"'):
            return expr[1:-1]
        # Character literals
        elif expr.startswith("'") and expr.endswith("'"):
            return expr[1:-1]
        # List literals
        elif expr.startswith('[') and expr.endswith(']'):
            elements = [self.parse_expression(e.strip()) for e in expr[1:-1].split(',') if e.strip()]
            return self.KylinList(elements)
        # Integer literals
        elif expr.isdigit():
            return int(expr)
        # Float literals
        elif re.match(r'^\d+\.\d+$', expr):
            return float(expr)
        # Boolean literals
        elif expr == 'true':
            return True
        elif expr == 'false':
            return False
        # Variable references
        elif expr in self.variables:
            return self.variables[expr]
        # Arithmetic operations
        elif '+' in expr:
            parts = expr.split('+', 1)
            return str(self.parse_expression(parts[0].strip())) + str(self.parse_expression(parts[1].strip()))
        # Method calls
        elif '.' in expr and '(' in expr and ')' in expr:
            return self.parse_method_call(expr)
        return expr
    
    def parse_method_call(self, line):
        match = re.match(r'(\w+)\.(\w+)\(\)', line)
        if match:
            obj_name = match.group(1)
            method_name = match.group(2)
            
            if obj_name == 'this' and self.current_class:
                return self.current_class.call_method(method_name, self, [])
            elif obj_name in self.variables:
                obj = self.variables[obj_name]
                if isinstance(obj, self.KylinClass):
                    return obj.call_method(method_name, self, [])
        return None
    
    def parse_print(self, line):
        match = re.match(r'print\((.*)\)', line)
        if match:
            expr = match.group(1)
            value = self.parse_expression(expr)
            print(value)
    
    def parse_input(self, line):
        match = re.match(r'input\((.*)\)', line)
        if match:
            prompt = match.group(1).strip('"')
            user_input = input(prompt)
            # Store in a special variable
            self.variables['_input'] = user_input
    
    def parse_if(self, line):
        # Simplified if implementation
        condition = line[3:].strip()
        # For demo, always execute the if block
        return True
    
    def parse_while(self, line):
        # Simplified while implementation
        condition = line[6:].strip()
        # For demo, execute once
        return True
    
    def execute_function(self, function_code, args, obj):
        # Extract function body
        lines = function_code.split('\n')
        body_start = function_code.find('{') + 1
        body_end = function_code.rfind('}')
        body = function_code[body_start:body_end].strip()
        
        # Save current context
        old_vars = self.variables.copy()
        old_class = self.current_class
        
        # Set new context
        self.current_class = obj
        self.variables = obj.fields.copy()
        
        # Execute function body
        result = None
        for line in body.split(';'):
            line = line.strip()
            if line:
                line_result = self.execute_line(line)
                if line_result is not None:
                    result = line_result
        
        # Restore context
        self.variables = old_vars
        self.current_class = old_class
        
        return result

# Example Kylin Programs
def run_example(example_name, code):
    print(f"\n=== {example_name} ===")
    interpreter = KylinInterpreter()
    interpreter.execute(code)

# 1. Hello World with I/O
hello_world = """
class Program {
    main() {
        print("Hello, Kylin!");
        input("What's your name? ");
        print("Hello, " + _input);
    }
}
"""

# 2. Fibonacci with Recursion
fibonacci = """
class Math {
    fib(n) {
        if (n <= 1) {
            return n;
        }
        return this.fib(n-1) + this.fib(n-2);
    }
}

class Program {
    main() {
        math = Math();
        print("Fibonacci sequence:");
        list sequence = [];
        int i = 0;
        while (i < 10) {
            sequence.add(math.fib(i));
            i = i + 1;
        }
        print(sequence);
    }
}
"""

# 3. List Operations with Characters
list_operations = """
class ListProcessor {
    process() {
        list chars = ['a', 'b', 'c', 'd', 'e'];
        list numbers = [1, 2, 3, 4, 5];
        
        print("Characters: " + chars);
        print("Numbers: " + numbers);
        
        // Add elements
        chars.add('f');
        numbers.add(6);
        
        print("Updated chars: " + chars);
        print("Updated numbers: " + numbers);
        
        // Access elements
        char first_char = chars.get(0);
        int first_num = numbers.get(0);
        
        print("First char: " + first_char);
        print("First number: " + first_num);
    }
}

class Program {
    main() {
        processor = ListProcessor();
        processor.process();
    }
}
"""

# 4. Object-Oriented Inheritance
inheritance_example = """
class Animal {
    speak() {
        return "Some sound";
    }
    
    move() {
        return "Moving";
    }
}

class Dog extends Animal {
    speak() {
        return "Woof!";
    }
}

class Cat extends Animal {
    speak() {
        return "Meow!";
    }
}

class Program {
    main() {
        dog = Dog();
        cat = Cat();
        
        print("Dog says: " + dog.speak());
        print("Cat says: " + cat.speak());
        print("Dog moves: " + dog.move());
        print("Cat moves: " + cat.move());
    }
}
"""

# 5. Complex Recursion with Lists
complex_recursion = """
class ListUtils {
    reverse_list(lst) {
        if (lst.size() == 0) {
            return [];
        }
        list rest = this.reverse_list(this.sublist(lst, 1, lst.size()));
        rest.add(lst.get(0));
        return rest;
    }
    
    sublist(lst, start, end) {
        list result = [];
        int i = start;
        while (i < end) {
            result.add(lst.get(i));
            i = i + 1;
        }
        return result;
    }
}

class Program {
    main() {
        utils = ListUtils();
        list original = [1, 2, 3, 4, 5];
        list reversed = utils.reverse_list(original);
        
        print("Original: " + original);
        print("Reversed: " + reversed);
    }
}
"""

if __name__ == "__main__":
    # Run examples
    run_example("Hello World with I/O", hello_world)
    run_example("Fibonacci with Recursion", fibonacci)
    run_example("List Operations with Characters", list_operations)
    run_example("Object-Oriented Inheritance", inheritance_example)
    run_example("Complex Recursion with Lists", complex_recursion)

Example

Hello, world!

class HelloWorld {
    main() {
        print("Hello, world!");
    }
}

Categories