mirror of
https://github.com/Smaug123/hvm
synced 2025-10-17 09:48:40 +00:00
Better CLI, some linting
This commit is contained in:
56
hvm/hvm.c
56
hvm/hvm.c
@@ -68,12 +68,12 @@ set_memory (const int *const initialise,
|
||||
size_t n)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
|
||||
if (n > MEMORY_SIZE) {
|
||||
n = MEMORY_SIZE;
|
||||
}
|
||||
memcpy(memory, initialise, n * sizeof(int));
|
||||
|
||||
|
||||
for (i = n; i < MEMORY_SIZE; i++) {
|
||||
memory[i] = 0;
|
||||
}
|
||||
@@ -97,16 +97,16 @@ pop (int *const output,
|
||||
int *const stack)
|
||||
{
|
||||
int rc = ERR_IS_OK;
|
||||
|
||||
|
||||
if (stack_depth == 0) {
|
||||
rc = ERR_EMPTY_STACK;
|
||||
}
|
||||
|
||||
|
||||
if (rc == ERR_IS_OK) {
|
||||
*output = stack[stack_depth - 1];
|
||||
stack_depth -= 1;
|
||||
}
|
||||
|
||||
|
||||
return (rc);
|
||||
}
|
||||
|
||||
@@ -130,11 +130,11 @@ delete (int *const arr,
|
||||
size_t *const len)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
|
||||
for (i = index; i < *len; i++) {
|
||||
arr[i] = arr[i+1];
|
||||
}
|
||||
|
||||
|
||||
*len -= 1;
|
||||
}
|
||||
|
||||
@@ -163,16 +163,16 @@ push (int val,
|
||||
if (*stack == NULL) {
|
||||
rc = ERR_OTHER;
|
||||
}
|
||||
|
||||
|
||||
if (rc == ERR_IS_OK) {
|
||||
curr_allocated *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (rc == ERR_IS_OK) {
|
||||
(*stack)[stack_depth] = val;
|
||||
stack_depth++;
|
||||
|
||||
|
||||
}
|
||||
|
||||
return (rc);
|
||||
@@ -192,7 +192,25 @@ int_leq_sizet (int a,
|
||||
} else {
|
||||
result = false;
|
||||
}
|
||||
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns true iff the specified int is >= the size_t.
|
||||
*/
|
||||
bool
|
||||
int_geq_sizet (int a,
|
||||
size_t b)
|
||||
{
|
||||
bool result;
|
||||
|
||||
if (a < 0) {
|
||||
result = false;
|
||||
} else if ((size_t)(a) >= b) {
|
||||
result = true;
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
@@ -228,7 +246,7 @@ execute_program (const char *const program,
|
||||
int val_to_push;
|
||||
int *stack;
|
||||
int memory[MEMORY_SIZE]; /* HVM interpreted program's memory buffer */
|
||||
|
||||
|
||||
/*
|
||||
* A stack of depth 32 is a reasonable start.
|
||||
*/
|
||||
@@ -237,9 +255,9 @@ execute_program (const char *const program,
|
||||
if (stack == NULL) {
|
||||
rc = ERR_OTHER;
|
||||
}
|
||||
|
||||
|
||||
set_memory(initial_mem, memory, mem_len);
|
||||
|
||||
|
||||
/*
|
||||
* The result of program_counter < end
|
||||
*/
|
||||
@@ -253,7 +271,7 @@ execute_program (const char *const program,
|
||||
*/
|
||||
rc = ERR_PC_EOB;
|
||||
}
|
||||
|
||||
|
||||
if (rc == ERR_IS_OK) {
|
||||
switch (program[program_counter]) {
|
||||
case ' ':
|
||||
@@ -406,7 +424,7 @@ execute_program (const char *const program,
|
||||
case '^':
|
||||
rc = pop(&s0, stack);
|
||||
if (rc == ERR_IS_OK) {
|
||||
if (s0 < 0 || s0 >= stack_depth) {
|
||||
if (s0 < 0 || int_geq_sizet(s0, stack_depth)) {
|
||||
rc = ERR_STACK;
|
||||
}
|
||||
}
|
||||
@@ -418,7 +436,7 @@ execute_program (const char *const program,
|
||||
case 'v':
|
||||
rc = pop(&s0, stack);
|
||||
if (rc == ERR_IS_OK) {
|
||||
if (s0 < 0 || s0 >= stack_depth) {
|
||||
if (s0 < 0 || int_geq_sizet(s0, stack_depth)) {
|
||||
rc = ERR_STACK;
|
||||
}
|
||||
}
|
||||
@@ -443,8 +461,8 @@ execute_program (const char *const program,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
free(stack);
|
||||
|
||||
|
||||
return (rc);
|
||||
}
|
||||
|
142
hvm/main.c
142
hvm/main.c
@@ -7,16 +7,144 @@
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "hvm.h"
|
||||
|
||||
int main(int argc, const char * argv[]) {
|
||||
/*
|
||||
* Example program from www.hacker.org/hvm, should print out 945321
|
||||
*/
|
||||
execute_program("123451^2v5:4?9p2g8pppppp",
|
||||
NULL,
|
||||
0);
|
||||
void
|
||||
usage () {
|
||||
printf("%s\n", "Usage: hvm \"program\" \"comma,separated,list,of,memory\"");
|
||||
}
|
||||
|
||||
/*
|
||||
* is_digit
|
||||
*
|
||||
* Tests whether a character is one of '0', ..., '9'.
|
||||
*/
|
||||
bool
|
||||
is_digit (const char testing) {
|
||||
return ('0' <= testing && testing <= '9');
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* validate_intlist
|
||||
*
|
||||
* Check that a given string is a comma-separated list of integers.
|
||||
*
|
||||
* Argument: intlist
|
||||
* IN - string to validate
|
||||
*
|
||||
* Argument: num_of_elts
|
||||
* OUT - number of elements in the list
|
||||
*
|
||||
* Return: bool true if the string passes validation; false otherwise.
|
||||
* If returns false, num_of_elts is meaningless.
|
||||
*/
|
||||
bool
|
||||
validate_intlist (const char *const intlist,
|
||||
size_t *num_of_elts) {
|
||||
|
||||
size_t num_memory = 0;
|
||||
size_t len = strlen(intlist);
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
if (intlist[i] == ',') {
|
||||
num_memory++;
|
||||
} else if (!is_digit(intlist[i]) && intlist[i] != '-') {
|
||||
/*
|
||||
* We weren't given an integer; bail out now
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
else if (intlist[i] == '-') {
|
||||
/*
|
||||
* The only acceptable place to have a minus sign in a number is at the start
|
||||
*/
|
||||
if (i != 0 && intlist[i-1] != ',') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*num_of_elts = num_memory;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* is_integer
|
||||
*
|
||||
* Tests whether a string contains an integer represented in base 10.
|
||||
*/
|
||||
bool
|
||||
is_integer (const char *const string) {
|
||||
size_t len = strlen(string);
|
||||
|
||||
if (len == 0) {
|
||||
return false;
|
||||
}
|
||||
if (string[0] != '-' && !is_digit(string[0])) {
|
||||
return false;
|
||||
}
|
||||
for (size_t i = 1; i < len; i++) {
|
||||
if (!is_digit(string[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[]) {
|
||||
if (argc == 1 || argc > 3) {
|
||||
/*
|
||||
* Wrong number of arguments; print usage message
|
||||
*/
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char *program = argv[1];
|
||||
int *initial_memory = NULL;
|
||||
size_t memory_length = 0; /* number of memory integers passed in */
|
||||
|
||||
if (argc >= 2 && strlen(argv[2]) > 0) {
|
||||
/*
|
||||
* We were passed in a list of memory locations; parse it
|
||||
*/
|
||||
char *initial_memstr = argv[2];
|
||||
bool valid = validate_intlist(argv[2], &memory_length);
|
||||
if (!valid) {
|
||||
usage();
|
||||
printf("%s\n", "List of integers was not formatted correctly.");
|
||||
return 2;
|
||||
}
|
||||
/*
|
||||
* The above has guaranteed that we have a list of integers.
|
||||
*/
|
||||
initial_memory = malloc(sizeof(int) * memory_length);
|
||||
if (initial_memory == NULL) {
|
||||
printf("%s\n", "Malloc failed.");
|
||||
return 255;
|
||||
}
|
||||
|
||||
char *single_mem_int;
|
||||
|
||||
single_mem_int = strtok(initial_memstr, ",");
|
||||
|
||||
while (single_mem_int != NULL) {
|
||||
atoi(single_mem_int);
|
||||
single_mem_int = strtok(NULL, ",");
|
||||
}
|
||||
}
|
||||
|
||||
execute_program(program,
|
||||
initial_memory,
|
||||
memory_length);
|
||||
|
||||
free(initial_memory);
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user