Added label initialization check to `vvi`.
[vvhitespace] / vv_compiler.c
CommitLineData
249fb9ba
AT
1/*
2 * (c) 2019 Aaron Taylor <ataylor at subgeniuskitty dot com>
3 * All rights reserved.
4 */
5
6#include <stdio.h>
7#include <stdlib.h>
8#include <unistd.h>
9#include <string.h>
10#include <errno.h>
11#include <getopt.h>
12#include <stdint.h>
13
14#define VERSION 1
15
16void
17print_usage(char ** argv)
18{
19 printf( "VVhitespace Interpreter v%d (www.subgeniuskitty.com)\n"
20 "Usage: %s -i <file> -o <file>\n"
21 " -h Help (prints this message)\n"
22 " -i <file> Specify a pseudo-VVhitespace source file as input.\n"
23 " -o <file> Specify location for VVhitespace output.\n"
24 , VERSION, argv[0]
25 );
26}
27
28int
29main(int argc, char ** argv)
30{
31 /*
32 * Process command line arguments
33 */
34 int c;
35 FILE * input = NULL, * output = NULL;
36 while ((c = getopt(argc,argv,"i:o:h")) != -1) {
37 switch (c) {
38 case 'i':
39 if ((input = fopen(optarg, "r")) == NULL) {
40 fprintf(stderr, "ERROR: %s: %s\n", optarg, strerror(errno));
41 }
42 break;
43 case 'o':
44 if ((output = fopen(optarg, "w+")) == NULL) {
45 fprintf(stderr, "ERROR: %s: %s\n", optarg, strerror(errno));
46 }
47 break;
48 case 'h':
49 print_usage(argv);
50 exit(EXIT_SUCCESS);
51 break;
52 default:
53 break;
54 }
55 }
56 if (input == NULL) {
57 fprintf(stderr, "ERROR: Must specify a pseudo-VVhitespace source file with -i flag.\n");
58 print_usage(argv);
59 exit(EXIT_FAILURE);
60 }
61 if (output == NULL) {
62 fprintf(stderr, "ERROR: Must specify destination for VVhitespace source file with -o flag.\n");
63 print_usage(argv);
64 exit(EXIT_FAILURE);
65 }
66
67 /*
68 * Main Loop
69 */
70 uint8_t temp_byte;
71 while (fread(&temp_byte, 1, 1, input)) {
72 switch (temp_byte) {
73 case 't':
74 case 'T':
75 temp_byte = '\t';
76 fwrite(&temp_byte, 1, 1, output);
77 break;
78 case 's':
79 case 'S':
80 temp_byte = ' ';
81 fwrite(&temp_byte, 1, 1, output);
82 break;
83 case 'n':
84 case 'N':
85 temp_byte = '\n';
86 fwrite(&temp_byte, 1, 1, output);
87 break;
88 case 'v':
89 case 'V':
90 temp_byte = '\v';
91 fwrite(&temp_byte, 1, 1, output);
92 break;
93 case '\n':
94 /* Intentionally empty */
95 break;
96 default:
97 /* The first non-[tTsSnNvV] character begins a comment lasting until end of line. */
98 while (fread(&temp_byte, 1, 1, input)) {
99 if (temp_byte == '\n') break;
100 }
101 break;
102 }
103 }
104
105 /*
106 * Cleanup and exit
107 */
108 fclose(input);
109 fclose(output);
110
249fb9ba
AT
111 exit(EXIT_SUCCESS);
112}