about summary refs log blame commit diff stats
path: root/awk/scheme/s.awk
blob: 7c8bba6ab7e490624a5d0fcfa18bef41c17f8a60 (plain) (tree)










































































































































                                                                     
#!/usr/bin/awk -f

# Set debug mode
DEBUG = 1  # Change to 0 to disable debug output

# Environment to store variable bindings
BEGIN {
    print "Welcome to the AWK Scheme Interpreter!"
    print "Type your Scheme expressions below (type 'exit' to quit):"
    while (1) {
        printf "> "
        if (getline input <= 0) {
            print "Error reading input. Exiting."
            break
        }
        if (input == "exit") {
            print "Exiting the interpreter."
            exit
        }
        if (input == "") {
            print "Empty input received, continuing..."
            continue
        }
        
        print "Input received: " input  # Echo the input
        ast = parse(input)  # Parse the input
        
        # Print the entire AST for debugging
        for (i = 1; i <= length(ast); i++) {
            print "AST[" i "] = " ast[i]
        }
        
        # Evaluate the AST
        if (length(ast) > 0) {
            result = eval(ast)  # Evaluate the AST
            print "Result: " result  # Print the result
        } else {
            print "Parsed AST is empty."
        }
    }
}

# Function to parse input into an AST
function parse(input) {
    # Remove outer whitespace
    gsub(/^\s+|\s+$/, "", input)
    
    # Check if input is empty after trimming
    if (input == "") {
        print "Input is empty after trimming"
        return ""
    }
    
    # Debugging: Print input before processing
    print "Debug: Raw input for parsing: " input
    
    # Remove parentheses at start and end
    if (substr(input, 1, 1) == "(") {
        input = substr(input, 2)
    }
    if (substr(input, length(input), 1) == ")") {
        input = substr(input, 1, length(input) - 1)
    }
    
    # Debugging: Print input after removing outer parentheses
    print "Debug: Input after removing outer parentheses: " input
    
    # Split the input into tokens
    gsub(/\(/, " ( ", input)
    gsub(/\)/, " ) ", input)
    gsub(/\s+/, " ", input)  # normalize whitespace
    gsub(/^\s+|\s+$/, "", input)  # trim
    
    # Debugging: Print input after tokenization
    print "Debug: Input after tokenization: " input
    
    n = split(input, ast, " ")
    
    # Debugging: Print the number of tokens
    print "Debug: Number of tokens: " n
    
    return ast
}

# Function to evaluate the AST
function eval(ast,    i, result) {
    # Debugging: Print the current AST being evaluated
    print "Debug: Evaluating AST: " ast[1] " " ast[2] " " ast[3]
    
    # Handle numbers directly
    if (ast[1] ~ /^[+-]?[0-9]+$/) {
        print "Debug: Returning number: " ast[1]
        return ast[1] + 0  # Convert string to number
    }
    
    # Handle addition
    if (ast[1] == "+") {
        result = 0
        for (i = 2; i <= length(ast); i++) {
            print "Debug: Adding operand: " ast[i]
            result += eval(ast[i])  # Recursively evaluate operands
        }
        return result
    }
    
    # Handle subtraction
    if (ast[1] == "-") {
        result = eval(ast[2])  # Start with the first operand
        for (i = 3; i <= length(ast); i++) {
            print "Debug: Subtracting operand: " ast[i]
            result -= eval(ast[i])  # Subtract subsequent operands
        }
        return result
    }
    
    # Handle multiplication
    if (ast[1] == "*") {
        result = 1
        for (i = 2; i <= length(ast); i++) {
            print "Debug: Multiplying operand: " ast[i]
            result *= eval(ast[i])  # Multiply operands
        }
        return result
    }
    
    # Handle division
    if (ast[1] == "/") {
        result = eval(ast[2])  # Start with the first operand
        for (i = 3; i <= length(ast); i++) {
            print "Debug: Dividing by operand: " ast[i]
            result /= eval(ast[i])  # Divide by subsequent operands
        }
        return result
    }
    
    # If we reach here, the operation is not recognized
    return "Error: Unknown operation " ast[1]
}