add AdventOfCodeDay2 test

This commit is contained in:
Zack Buhman 2024-12-24 02:54:06 -06:00
parent b266c6b4d3
commit 3791a78e19
6 changed files with 171 additions and 12 deletions

View File

@ -120,6 +120,10 @@ struct class_entry * class_resolver_lookup_class(int class_hash_table_length,
const uint8_t * class_name, const uint8_t * class_name,
int class_name_length) int class_name_length)
{ {
printf("class_resolver_lookup_class: ");
for (int i = 0; i < class_name_length; i++) { fputc(class_name[i], stdout); }
fputc('\n', stdout);
struct hash_table_entry * e = hash_table_find(class_hash_table_length, struct hash_table_entry * e = hash_table_find(class_hash_table_length,
class_hash_table, class_hash_table,
class_name, class_name,
@ -134,6 +138,10 @@ struct field_entry * class_resolver_lookup_field(struct class_entry * class_entr
const uint8_t * field_name, const uint8_t * field_name,
int field_name_length) int field_name_length)
{ {
printf("class_resolver_lookup_field: ");
for (int i = 0; i < field_name_length; i++) { fputc(field_name[i], stdout); }
fputc('\n', stdout);
int fields_hash_table_length = class_entry->fields.length; int fields_hash_table_length = class_entry->fields.length;
struct hash_table_entry * fields_hash_table = class_entry->fields.entry; struct hash_table_entry * fields_hash_table = class_entry->fields.entry;
@ -150,6 +158,10 @@ struct method_info * class_resolver_lookup_method(struct class_entry * class_ent
const uint8_t * method_name, const uint8_t * method_name,
int method_name_length) int method_name_length)
{ {
printf("class_resolver_lookup_method: ");
for (int i = 0; i < method_name_length; i++) { fputc(method_name[i], stdout); }
fputc('\n', stdout);
int methods_hash_table_length = class_entry->methods.length; int methods_hash_table_length = class_entry->methods.length;
struct hash_table_entry * methods_hash_table = class_entry->methods.entry; struct hash_table_entry * methods_hash_table = class_entry->methods.entry;

View File

@ -75,7 +75,6 @@ void op_astore(struct vm * vm, uint32_t index)
void op_astore_0(struct vm * vm) void op_astore_0(struct vm * vm)
{ {
printf("op_astore0 %d\n", vm->current_frame->operand_stack_ix);
uint32_t value = operand_stack_pop_u32(vm->current_frame); uint32_t value = operand_stack_pop_u32(vm->current_frame);
vm->current_frame->local_variable[0] = value; vm->current_frame->local_variable[0] = value;
} }
@ -959,14 +958,28 @@ void op_ireturn(struct vm * vm)
of the invoked method was boolean, then value is narrowed from int to of the invoked method was boolean, then value is narrowed from int to
boolean by taking the bitwise AND of value and 1. */ boolean by taking the bitwise AND of value and 1. */
uint32_t value = operand_stack_pop_u32(vm->current_frame); // The current method must have return type boolean, byte, char, short, or int
int32_t value = operand_stack_pop_u32(vm->current_frame);
switch (vm->current_frame->return_type) { switch (vm->current_frame->return_type) {
case 'I': case 'Z': // boolean
value = value & 1;
break;
case 'B': // byte
value = (int8_t)value;
break;
case 'C': // char
value = (uint16_t)value;
break;
case 'S': // short
value = (int16_t)value;
break;
case 'I': // int
value = (int32_t)value;
break; break;
default: default:
fprintf(stderr, "conversion not implemented: %c\n", vm->current_frame->return_type); fprintf(stderr, "invalid conversion: %c\n", vm->current_frame->return_type);
assert(false); assert(false);
break;
} }
operand_stack_push_u32(vm->current_frame, value); operand_stack_push_u32(vm->current_frame, value);

View File

@ -73,12 +73,17 @@ static int descriptor_nargs(struct constant * descriptor_constant)
assert(descriptor_constant->utf8.length >= 2); assert(descriptor_constant->utf8.length >= 2);
assert(descriptor_constant->utf8.bytes[0] == '('); assert(descriptor_constant->utf8.bytes[0] == '(');
printf("method descriptor: ");
print_utf8_string(descriptor_constant);
printf("\n");
int i = 1; int i = 1;
int nargs = 0; int nargs = 0;
while (i < descriptor_constant->utf8.length) { while (i < descriptor_constant->utf8.length) {
if (descriptor_constant->utf8.bytes[i] == ')') if (descriptor_constant->utf8.bytes[i] == ')')
break; break;
nargs += 1; if (descriptor_constant->utf8.bytes[i] != '[')
nargs += 1;
i += 1; i += 1;
} }
assert(i + 2 == descriptor_constant->utf8.length); assert(i + 2 == descriptor_constant->utf8.length);
@ -100,7 +105,6 @@ void vm_static_method_call(struct vm * vm, struct class_file * class_file, struc
int code_name_index = find_code_name_index(class_file); int code_name_index = find_code_name_index(class_file);
assert(code_name_index > 0); assert(code_name_index > 0);
printf("code_name_index %d\n", code_name_index);
struct Code_attribute * code = get_code_attribute(code_name_index, struct Code_attribute * code = get_code_attribute(code_name_index,
method_info->attributes_count, method_info->attributes_count,
@ -120,9 +124,10 @@ void vm_static_method_call(struct vm * vm, struct class_file * class_file, struc
printf("nargs %d\n", nargs); printf("nargs %d\n", nargs);
for (int i = 0; i < nargs; i++) { for (int i = 0; i < nargs; i++) {
uint32_t value = operand_stack_pop_u32(old_frame); uint32_t value = operand_stack_pop_u32(old_frame);
printf("local[%d] = %x\n", nargs - i - 1, value);
vm->current_frame->local_variable[nargs - i - 1] = value; vm->current_frame->local_variable[nargs - i - 1] = value;
} }
vm->current_frame->return_type = descriptor_constant->utf8.bytes[nargs + 2]; vm->current_frame->return_type = descriptor_constant->utf8.bytes[descriptor_constant->utf8.length - 1];
vm->current_frame->pc = 0; vm->current_frame->pc = 0;
vm->current_thread.current_class = class_file; vm->current_thread.current_class = class_file;
@ -140,9 +145,38 @@ void vm_method_return(struct vm * vm)
assert(vm->current_frame != old_frame); assert(vm->current_frame != old_frame);
vm->current_frame->pc = vm->current_frame->next_pc; vm->current_frame->pc = vm->current_frame->next_pc;
/*
boolean int 1
byte int 1
char int 1
short int 1
int int 1
float float 1
reference reference 1
returnAddress returnAddress 1
long long 2
double double 2
*/
/*
B byte
C char
D double
F float
I int
J long
L ClassName ; Named class or interface type
S short
Z boolean
[ ComponentType Array of given component type
*/
switch (old_frame->return_type) { switch (old_frame->return_type) {
case 'F': [[fallthrough]]; case 'Z': [[fallthrough]];
case 'I': case 'B': [[fallthrough]];
case 'C': [[fallthrough]];
case 'S': [[fallthrough]];
case 'I': [[fallthrough]];
case 'F':
uint32_t value = operand_stack_pop_u32(old_frame); uint32_t value = operand_stack_pop_u32(old_frame);
operand_stack_push_u32(vm->current_frame, value); operand_stack_push_u32(vm->current_frame, value);
break; break;

View File

@ -1,6 +1,6 @@
package p; package p;
class AdventDay1 { class AdventOfCodeDay1 {
public static int part1() { public static int part1() {
int[] input = {3, 4, int[] input = {3, 4,
4, 3, 4, 3,

View File

@ -1,6 +1,6 @@
package p; package p;
class AdventOfCode2024Day1 { class AdventOfCodeDay1_String {
public static int part1() { public static int part1() {
char[] string_input = { char[] string_input = {
'3', ' ', ' ', ' ', '4', '\n', '3', ' ', ' ', ' ', '4', '\n',

100
p/AdventOfCodeDay2.java Normal file
View File

@ -0,0 +1,100 @@
package p;
class AdventOfCodeDay2 {
static float parse_digit(char c) {
switch (c) {
case '0': return 0.0f;
case '1': return 1.0f;
case '2': return 2.0f;
case '3': return 3.0f;
case '4': return 4.0f;
case '5': return 5.0f;
case '6': return 6.0f;
case '7': return 7.0f;
case '8': return 8.0f;
case '9': return 9.0f;
default: return -1.0f;
}
}
static float fabs(float f)
{
if (f < 0)
return -f;
else
return f;
}
static float fsign(float f)
{
if (f < 0)
return -1;
else
return 1;
}
static boolean report_safe(float[] line, int length)
{
float last = line[0];
float last_sign = 0.0f;
for (int i = 1; i < length; i++) {
float cur = line[i];
float rate = last - cur;
if (fabs(rate) < 1 || fabs(rate) > 3)
return false; // unsafe
float sign = fsign(rate);
if (last_sign != 0.0f && sign != last_sign)
return false; // unsafe
last_sign = sign;
last = cur;
}
return true; // safe
}
static float solve(char[] input) {
float[] line = new float[100];
int line_ix = 0;
int input_ix = 0;
float num = 0.0f;
float safe_count = 0.0f;
while (input_ix < input.length) {
if (input[input_ix] == ' ' || input[input_ix] == '\n') {
line[line_ix] = num;
line_ix += 1;
num = 0.0f;
}
if (input[input_ix] == '\n') {
if (report_safe(line, line_ix)) {
safe_count += 1.0f;
}
line_ix = 0;
}
float digit = parse_digit(input[input_ix]);
if (!(digit < 0.0f)) {
num *= 10.0f;
num += digit;
}
input_ix += 1;
}
return safe_count;
}
public static void main() {
char[] input = {
'7', ' ', '6', ' ', '4', ' ', '2', ' ', '1', '\n',
'1', ' ', '2', ' ', '7', ' ', '8', ' ', '9', '\n',
'9', ' ', '7', ' ', '6', ' ', '2', ' ', '1', '\n',
'1', ' ', '3', ' ', '2', ' ', '4', ' ', '5', '\n',
'8', ' ', '6', ' ', '4', ' ', '4', ' ', '1', '\n',
'1', ' ', '3', ' ', '6', ' ', '7', ' ', '9', '\n',
};
solve(input);
}
}