/
CDC-1.2b/
CDC-1.2b/src/
parent $root_evaluator
object $compile_evaluator

var $root dbref 'compile_evaluator
var $root child_index 0
var $root fertile 1
var $root manager $compile_evaluator
var $root owned [$compile_evaluator]
var $root owners [$]
var $root writable []
var $root readable ['parameters, 'methods, 'code]
var $root inited 1

method compile_cml
    arg text;
    var output, char, mode, vars;
    
    //Turn the given text into the ctext format.
    if (type(text) == 'list)
        text = text.to_string(" ");
    if (type(text) != 'string)
        throw(~type, "Text should be a string.");
    text = text + "\"";
    if ((text[1]) == "\"")
        text = substr(text, 1);
    vars = #[];
    vars = .parse_string(vars, text);
    return vars;
.

method parse_string
    arg vars, text;
    var output, word, is_text, token, ret_val;
    
    output = [];
    word = "";
    is_text = 0;
    while (text) {
        ret_val = text.split_on_next(["\"", "{", "%", "&"]);
        word = ret_val[1];
        token = ret_val[2];
        text = ret_val[3];
        switch (token) {
            case "{":
                output = ._handle_word(output, word);
                vars = .parse_command(vars, text);
                output = [@output, vars['result]];
                text = vars['text];
                is_text = 1;
            case "%":
                output = ._handle_word(output, word);
                vars = .parse_varref(vars, text);
                output = [@output, vars['result]];
                text = vars['text];
                is_text = 1;
            case "&":
                output = ._handle_word(output, word);
                vars = .parse_charref(vars, text);
                output = [@output, vars['result]];
                text = vars['text];
                is_text = 1;
            case "\"":
                output = ._handle_word(output, word);
                if (is_text) {
                    vars = .text_stmt(vars, output);
                    output = vars['result];
                }
                if (listlen(output) == 1)
                    output = output[1];
                vars = dict_add(vars, 'text, text);
                return dict_add(vars, 'result, output);
        }
    }
    vars = dict_add(vars, 'text, text);
    return dict_add(vars, 'result, output);
.

method parse_command
    arg vars, text;
    var output, ret_val, term, word, final, first_term, final_args, token;
    
    output = [];
    term = [];
    word = "";
    while (text) {
        ret_val = text.split_on_next(["\"", "{", "%", "&", "[", " ", "}"]);
        word = ret_val[1];
        token = ret_val[2];
        text = ret_val[3];
        switch (token) {
            case "{":
                output = ._handle_word(output, term);
                vars = .parse_command(vars, text);
                output = [@output, vars['result]];
                text = vars['text];
            case "[":
                output = ._handle_word(output, term);
                vars = .parse_list(vars, text);
                output = [@output, vars['result]];
                text = vars['text];
            case "%":
                output = ._handle_word(output, term);
                vars = .parse_varref(vars, text);
                output = [@output, vars['result]];
                text = vars['text];
            case "\"":
                output = ._handle_word(output, term);
                vars = .parse_string(vars, text);
                output = [@output, vars['result]];
                text = vars['text];
            case " ":
                if ((word == "pre") && (!output)) {
                    ret_val = ")" in text;
                    output = [['string_type, "pre"], ['string_type, substr(text, 1, ret_val - 1)]];
                    text = substr(text, ret_val);
                } else {
                    output = ._handle_word(output, word);
                }
            case "}":
                output = ._handle_word(output, word);
    
                //       if (type(output[1]) != 'list)
                //         output = [output];
                first_term = output[1];
                if ((first_term[1]) == 'string_type) {
                    first_term = tosym((first_term[2]) + "_stmt");
                    final_args = sublist(output, 2);
                    catch ~methodnf {
                        vars = .(first_term)(vars, final_args);
                    } with handler {
                        vars = dict_add(vars, 'result, [first_term, final_args]);
                    }
                } else if (type(first_term[1]) == 'symbol) {
                    final_args = [@first_term[2], @sublist(output, 2)];
                    first_term = first_term[1];
                    vars = dict_add(vars, 'result, [first_term, final_args]);
                } else {
                    first_term = 'eval_stmt;
                    final_args = [first_term];
                    vars = dict_add(vars, 'result, [first_term, final_args]);
                }
                vars = dict_add(vars, 'text, text);
                return vars;
        }
    }
    vars = dict_add(vars, 'text, "");
    return dict_add(vars, 'result, ['string_type, "unended command"]);
.

method parse_charref
    arg vars, text;
    var pos;
    
    pos = ";" in text;
    vars = dict_add(vars, 'text, substr(text, pos + 1));
    text = substr(text, 1, pos - 1);
    switch (text) {
        case "lp":
            text = "(";
        case "amp":
            text = "&";
        case "quote":
            text = "\"";
        case "per":
            text = "%";
        case "lb":
            text = "{";
        case "rb":
            text = "}";
        case "tick":
            text = "'";
        default:
            text = (">>ERROR: Unknown character " + text) + "<<";
    }
    return dict_add(vars, 'result, ['string_type, text]);
.

method parse_varref
    arg vars, text;
    var output, ret_val, word, token;
    
    output = [];
    word = "";
    while (text) {
        ret_val = text.split_on_next(["{", "%", "&", ";"]);
        word = ret_val[1];
        token = ret_val[2];
        text = ret_val[3];
        switch (token) {
            case "{":
                output = ._handle_word(output, word);
                ret_val = .parse_command(vars, text);
                output = [@output, vars['result]];
                text = vars['text];
            case "%":
                output = ._handle_word(output, word);
                ret_val = .parse_varref(vars, text);
                output = [@output, vars['result]];
                text = vars['text];
            case "&":
                output = ._handle_word(output, word);
                ret_val = .parse_charref(vars, text);
                output = [@output, vars['result]];
                text = vars['result];
            case ";":
                output = ._handle_word(output, word);
                vars = dict_add(vars, 'text, text);
                return dict_add(vars, 'result, ['get_stmt, output]);
        }
    }
.

method parse_list
    arg vars, text;
    var output, term, word, token, int, ret_val;
    
    output = [];
    term = [];
    word = "";
    while (text) {
        ret_val = text.split_on_next(["[", "]", "{", "\"", "%", "&", " "]);
        word = ret_val[1];
        token = ret_val[2];
        text = ret_val[3];
        switch (token) {
            case "{":
                output = ._handle_word(output, word);
                vars = .parse_command(vars, text);
                output = [@output, vars['result]];
                text = vars['text];
            case "[":
                output = ._handle_word(output, word);
                vars = .parse_list(vars, text);
                output = [@output, vars['result]];
                text = vars['text];
            case "%":
                output = ._handle_word(output, word);
                vars = .parse_varref(vars, text);
                output = [@output, vars['result]];
                text = vars['text];
            case "\"":
                output = ._handle_word(output, word);
                vars = .parse_string(vars, text);
                output = [@output, vars['text]];
                text = vars['text];
            case " ":
                output = ._handle_word(output, word);
            case "]":
                output = ['list_type, ._handle_word(output, word)];
                vars = dict_add(vars, 'text, text);
                return dict_add(vars, 'result, output);
        }
    }
.

method _handle_word
    arg output, word;
    
    if (word) {
        if (type(word) == 'string) {
            if (word.is_numeric()) {
                word = ['integer_type, toint(word)];
            } else if ((word[1]) == "$") {
                if (" " in word)
                    word = ['string_type, word];
                else
                    word = ['dbref_type, $object.to_dbref(word)];
            } else if ((word[1]) == "'") {
                word = ['symbol_type, tosym(word)];
            } else {
                word = ['string_type, word];
            }
        }
        output = [@output, word];
    }
    return output;
.

method char_type
    arg vars, args;
    
    .debug("foo");
    if ((args[1]) != 'string_type)
        return ['string_type, ">>ERROR: Character must be a constant string."];
    switch (args) {
        case "lp":
            return ['string_type, "("];
        case "amp":
            return [string_type, "&"];
        case "quote":
            return ['string_type, "\""];
        case "per":
            return ['string_type, "%"];
        default:
            return ['string_type, (">>ERROR: Unknown character " + args) + "<<"];
    }
.

method text_stmt
    arg vars, args;
    var last, output, term, first;
    
    output = [];
    for term in (args) {
        if (output) {
            last = output.last();
            if (((term[1]) == 'string_type) && ((last[1]) == 'string_type)) {
                term = ['string_type, (last[2]) + (term[2])];
                output = output.chop();
            }
        }
        output = [@output, term];
    }
    if (listlen(output) == 1) {
        first = output[1];
        if ((first[1]) == 'string_type)
            return dict_add(vars, 'result, first);
    }
    return dict_add(vars, 'result, ['text_stmt, output]);
.