root/native.c
/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- check_argument_count
- print_value
- crb_nv_print_proc
- crb_nv_fopen_proc
- crb_nv_fclose_proc
- crb_nv_fgets_proc
- crb_nv_fputs_proc
- new_array_sub
- crb_nv_new_array_proc
#include <stdio.h>
#include <string.h>
#include "MEM.h"
#include "DBG.h"
#include "crowbar.h"
static void
check_argument_count(int arg_count, int true_count)
{
if (arg_count < true_count) {
crb_runtime_error(0, ARGUMENT_TOO_FEW_ERR,
MESSAGE_ARGUMENT_END);
} else if (arg_count > true_count) {
crb_runtime_error(0, ARGUMENT_TOO_MANY_ERR,
MESSAGE_ARGUMENT_END);
}
}
static void
print_value(CRB_Value *value)
{
int i;
switch (value->type) {
case CRB_BOOLEAN_VALUE:
if (value->u.boolean_value) {
printf("true");
} else {
printf("false");
}
break;
case CRB_INT_VALUE:
printf("%d", value->u.int_value);
break;
case CRB_DOUBLE_VALUE:
printf("%f", value->u.double_value);
break;
case CRB_STRING_VALUE:
printf("%s", value->u.object->u.string.string);
break;
case CRB_NATIVE_POINTER_VALUE:
printf("(%p)", value->u.native_pointer_value);
break;
case CRB_NULL_VALUE:
printf("null");
break;
case CRB_ARRAY_VALUE:
printf("(");
for (i = 0; i < value->u.object->u.array.size; i++) {
if (i > 0) {
printf(", ");
}
print_value(&value->u.object->u.array.array[i]);
}
printf(")");
break;
}
}
CRB_Value
crb_nv_print_proc(CRB_Interpreter *interpreter,
int arg_count, CRB_Value *args)
{
CRB_Value value;
value.type = CRB_NULL_VALUE;
check_argument_count(arg_count, 1);
print_value(&args[0]);
return value;
}
CRB_Value
crb_nv_fopen_proc(CRB_Interpreter *interpreter,
int arg_count, CRB_Value *args)
{
CRB_Value value;
FILE *fp;
check_argument_count(arg_count, 2);
if (args[0].type != CRB_STRING_VALUE
|| args[1].type != CRB_STRING_VALUE) {
crb_runtime_error(0, FOPEN_ARGUMENT_TYPE_ERR,
MESSAGE_ARGUMENT_END);
}
fp = fopen(args[0].u.object->u.string.string,
args[1].u.object->u.string.string);
if (fp == NULL) {
value.type = CRB_NULL_VALUE;
} else {
value.type = CRB_NATIVE_POINTER_VALUE;
value.u.native_pointer_value = fp;
}
return value;
}
CRB_Value
crb_nv_fclose_proc(CRB_Interpreter *interpreter,
int arg_count, CRB_Value *args)
{
CRB_Value value;
FILE *fp;
check_argument_count(arg_count, 1);
value.type = CRB_NULL_VALUE;
if (args[0].type != CRB_NATIVE_POINTER_VALUE) {
crb_runtime_error(0, FCLOSE_ARGUMENT_TYPE_ERR,
MESSAGE_ARGUMENT_END);
}
fp = args[0].u.native_pointer_value;
fclose(fp);
return value;
}
CRB_Value
crb_nv_fgets_proc(CRB_Interpreter *interpreter,
int arg_count, CRB_Value *args)
{
CRB_Value value;
FILE *fp;
char buf[LINE_BUF_SIZE];
char *ret_buf = NULL;
int ret_len = 0;
check_argument_count(arg_count, 1);
if (args[0].type != CRB_NATIVE_POINTER_VALUE) {
crb_runtime_error(0, FGETS_ARGUMENT_TYPE_ERR,
MESSAGE_ARGUMENT_END);
}
fp = args[0].u.native_pointer_value;
while (fgets(buf, LINE_BUF_SIZE, fp)) {
int new_len;
new_len = ret_len + strlen(buf);
ret_buf = MEM_realloc(ret_buf, new_len + 1);
if (ret_len == 0) {
strcpy(ret_buf, buf);
} else {
strcat(ret_buf, buf);
}
ret_len = new_len;
if (ret_buf[ret_len-1] == '\n')
break;
}
if (ret_len > 0) {
value.type = CRB_STRING_VALUE;
value.u.object = crb_create_crowbar_string(interpreter, ret_buf);
} else {
value.type = CRB_NULL_VALUE;
}
return value;
}
CRB_Value
crb_nv_fputs_proc(CRB_Interpreter *interpreter,
int arg_count, CRB_Value *args)
{
CRB_Value value;
FILE *fp;
check_argument_count(arg_count, 2);
value.type = CRB_NULL_VALUE;
if (args[0].type != CRB_STRING_VALUE
|| args[1].type != CRB_NATIVE_POINTER_VALUE) {
crb_runtime_error(0, FPUTS_ARGUMENT_TYPE_ERR,
MESSAGE_ARGUMENT_END);
}
fp = args[1].u.native_pointer_value;
fputs(args[0].u.object->u.string.string, fp);
return value;
}
CRB_Value
new_array_sub(CRB_Interpreter *inter,
int arg_count, CRB_Value *args, int arg_idx)
{
CRB_Value ret;
int size;
int i;
if (args[arg_idx].type != CRB_INT_VALUE) {
crb_runtime_error(0, NEW_ARRAY_ARGUMENT_TYPE_ERR,
MESSAGE_ARGUMENT_END);
}
size = args[arg_idx].u.int_value;
ret.type = CRB_ARRAY_VALUE;
ret.u.object = crb_create_array(inter, size);
CRB_push_value(inter, &ret);
if (arg_idx == arg_count-1) {
for (i = 0; i < size; i++) {
ret.u.object->u.array.array[i].type = CRB_NULL_VALUE;
}
} else {
for (i = 0; i < size; i++) {
ret.u.object->u.array.array[i]
= new_array_sub(inter, arg_count, args, arg_idx+1);
}
}
CRB_pop_value(inter);
return ret;
}
CRB_Value
crb_nv_new_array_proc(CRB_Interpreter *interpreter,
int arg_count, CRB_Value *args)
{
CRB_Value value;
if (arg_count < 1) {
crb_runtime_error(0, ARGUMENT_TOO_FEW_ERR,
MESSAGE_ARGUMENT_END);
}
value = new_array_sub(interpreter, arg_count, args, 0);
return value;
}