about summary refs log tree commit diff stats
path: root/awk/scheme/s.awk
blob: 7c8bba6ab7e490624a5d0fcfa18bef41c17f8a60 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#!/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]
}