[ create a new paste ] login | about

Link: http://codepad.org/l5jkQNp6    [ raw code | output | fork ]

adrien1018 - C++, pasted on May 22:
#include <unordered_map>
#include <cstdio>
#include <string>
#include <vector>
#include <cstring>
#include <utility>

using std::pair;
using std::unordered_map;
using std::string;
using std::vector;

const char code_path[20] = "sub_1.txt"; //code file
const char grid_path[20] = "grid_1.txt"; //grid file
const uint32_t gridN = 256; // grid size
bool print_grid = true; //print final grid

char code[1048571];

struct error {
    error() {}
    error(uint32_t a, uint32_t b, string c) : error_no(a), line(b), str(c) {}
    uint32_t error_no, line;
    string str;
};

const uint32_t maxpeb = 15;
uint8_t grid[gridN][gridN], grid_init[gridN][gridN];

uint32_t lines, tline;
unordered_map<string, uint32_t> tag; //tag, line
vector<pair<uint32_t, string>> totag; //line, tag
vector<pair<uint32_t, uint32_t>> program; //mode, (toline)
    // 0: left, 1: right, 2: move, 3: get, 4: put, 5: halt, 6: jump, 7: border, 8: pebble

void initialize() {
    freopen(grid_path, "r", stdin);
    memset(grid, 0x00, gridN * gridN);
    uint32_t x, y, t;
    while (~scanf("%u%u%u", &x, &y, &t)) {
        if (x >= gridN || x >= gridN || t > maxpeb) throw error(0, 0, ""); //invalid input
        grid[x][y] = t;
    }
    memcpy(grid_init, grid, gridN * gridN);

    lines = tline = 0;

    FILE* pFile = fopen(code_path, "r");
    size_t p = fread(code, 1, 1048571, pFile);
    code[p] = 0;
}

inline bool isg(char p) {
    return (p >= 'A' && p <= 'Z' || p >= 'a' && p <= 'z' || p >= '0' && p <= '9' || p == '_');
}

void compile_line(char* p, char* end) {
    tline++;
    string str[2];
    bool flag = false;
    int8_t cr = 0;
    while (p != end) {
        if (isg(*p)) {
            if (cr == 2 || flag) throw error(1, tline, ""); //word after tag or two words
            str[cr] += *p;
            if (str[cr].size() > 128) throw error(2, tline, ""); //too long
        }
        else if (*p == ' ') {
            if (str[cr].size()) cr++;
        }
        else if (*p == '#' || *p == '\n' || *p == '\r' || *p == '\0') {
            if (str[cr].size()) cr++;
            break;
        }
        else if (*p == ':') {
            if (!str[cr].size()) throw error(3, tline, ""); //empty tag
            cr++, flag = true;
        }
        else throw error(4, tline, string(1, *p)); //invalid character
        p++;
    }

    if (flag) {
        if (tag.count(str[0])) throw error(5, tline, str[0]); //same-name tag
        tag[str[0]] = lines--;
    }
    else if (str[0] == "left" && !str[1].size()) program.push_back(pair<uint32_t, uint32_t>(0, 0));
    else if (str[0] == "right" && !str[1].size()) program.push_back(pair<uint32_t, uint32_t>(1, 0));
    else if (str[0] == "move" && !str[1].size()) program.push_back(pair<uint32_t, uint32_t>(2, 0));
    else if (str[0] == "get" && !str[1].size()) program.push_back(pair<uint32_t, uint32_t>(3, 0));
    else if (str[0] == "put" && !str[1].size()) program.push_back(pair<uint32_t, uint32_t>(4, 0));
    else if (str[0] == "halt" && !str[1].size()) program.push_back(pair<uint32_t, uint32_t>(5, 0));
    else if (str[0] == "jump" && str[1].size()) {
        program.push_back(pair<uint32_t, uint32_t>(6, 0));
        totag.push_back(pair<uint32_t, string>(lines, str[1]));
    }
    else if (str[0] == "border" && str[1].size()) {
        program.push_back(pair<uint32_t, uint32_t>(7, 0));
        totag.push_back(pair<uint32_t, string>(lines, str[1]));
    }
    else if (str[0] == "pebble" && str[1].size()) {
        program.push_back(pair<uint32_t, uint32_t>(8, 0));
        totag.push_back(pair<uint32_t, string>(lines, str[1]));
    }
    else if (!str[0].size()) lines--;
    else throw error(6, tline, str[0] + ' ' + str[1]); //invalid command
    lines++;
}

void compile(char* p) {
    char *prev = p, *now = p;
    while (*now) {
        if (*now == '\n') {
            compile_line(prev, now + 1);
            prev = now + 1;
        }
        now++;
    }
    compile_line(prev, now + 1);

    unordered_map<string, uint32_t>::iterator it;
    for (auto& i : totag) {
        if ((it = tag.find(i.second)) != tag.end()) program[i.first].second = it->second;
        else throw error(7, 0, i.second); //undefined tag
    }
}

uint32_t tx, ty, dir;
uint32_t nowline;
uint32_t steps;
const int32_t dy[4] = {0, -1, 0, 1}; //left++
const int32_t dx[4] = {-1, 0, 1, 0};

inline bool face_border() {
    return (!ty && dir == 1 || !tx && !dir || ty == gridN - 1 && dir == 3 || tx == gridN - 1 && dir == 2);
}

void execute() {
    nowline = steps = tx = ty = dir = 0;
    bool cont = true;
    while (cont && nowline < lines) {
        steps++;
        switch (program[nowline].first) {
            case 0: dir = (dir + 1) & 3; break;
            case 1: dir = (dir + 3) & 3; break;
            case 2: if (!face_border()) tx += dx[dir], ty += dy[dir]; break;
            case 3: if (grid[tx][ty]) grid[tx][ty]--; break;
            case 4: if (grid[tx][ty] != 15) grid[tx][ty]++; break;
            case 5: cont = false; break;
            case 6: nowline = program[nowline].second - 1; break;
            case 7: if (face_border()) nowline = program[nowline].second - 1; break;
            case 8: if (grid[tx][ty]) nowline = program[nowline].second - 1;
        }
        nowline++;
    }
}

int main()
{
    try {
        initialize();
        compile(code);
        printf("Compiled. Commands: %u.\n", lines);
        execute();
        printf("Executed. Final position: (%u, %u). Steps: %u.\n", tx, ty, steps);
        if (print_grid) {
            for (uint32_t i = 0; i < gridN; i++) {
                for (uint32_t j = 0; j < gridN; j++) printf("%hhd ", grid[i][j]);
                putchar('\n');
            }
        }
    }
    catch (error e) {
        puts("Complication error.");
        switch (e.error_no) {
            case 0: puts("Invalid grid input."); break;
            case 1: printf("Line %u: Text after tag or too many arguments.", e.line); break;
            case 2: printf("Line %u: Identifier is too long.", e.line); break;
            case 3: printf("Line %u: Empty tag.", e.line); break;
            case 4: printf("Line %u: Invalid character \'%s\'.", e.line, e.str.c_str()); break;
            case 5: printf("Line %u: Redefinition of tag \'%s\'.", e.line, e.str.c_str()); break;
            case 6: printf("Line %u: Invalid command \'%s\'.", e.line, e.str.c_str()); break;
            case 7: printf("Undefined tag \'%s\'.", e.str.c_str());
        }
    }
}


Output:
1
2
3
Line 24: error: unordered_map: No such file or directory
Line 9: error: 'std::unordered_map' has not been declared
compilation terminated due to -Wfatal-errors.


Create a new paste based on this one


Comments: