Commit deb92e73 authored by Chris Müller's avatar Chris Müller
Browse files

Add runtime methods for MD5 bruteforce script.

parent 9248b8fb
......@@ -11,4 +11,4 @@ set(BOOTSTRAP_SOURCES
add_executable(bootstrap-cherry ${BOOTSTRAP_SOURCES})
target_link_libraries(bootstrap-cherry readline gc)
target_link_libraries(bootstrap-cherry readline gc ssl crypto)
......@@ -214,6 +214,7 @@ struct cherry_value* cherry_core_make_tuple(struct cherry_environment* env, s
struct cherry_value* cherry_core_string_to_list(struct cherry_environment* env, struct cherry_value* args);
struct cherry_value* cherry_core_string_to_fixnum(struct cherry_environment* env, struct cherry_value* args);
struct cherry_value* cherry_core_string_to_tuple(struct cherry_environment* env, struct cherry_value* args);
struct cherry_value* cherry_core_string_equal(struct cherry_environment* env, struct cherry_value* args);
struct cherry_value* cherry_core_tuple(struct cherry_environment* env, struct cherry_value* args);
......@@ -231,11 +232,16 @@ struct cherry_value* cherry_core_greater_equal(struct cherry_environment* env
struct cherry_value* cherry_core_less_equal(struct cherry_environment* env, struct cherry_value* args);
struct cherry_value* cherry_core_equal(struct cherry_environment* env, struct cherry_value* args);
// org.cherry.io
struct cherry_value* cherry_io_println(struct cherry_environment* env, struct cherry_value* args);
// org.cherry.crypto
struct cherry_value* cherry_crypto_md5(struct cherry_environment* env, struct cherry_value* args);
// org.cherry.system
struct cherry_value* cherry_system_exit(struct cherry_environment* env, struct cherry_value* args);
struct cherry_value* cherry_system_time(struct cherry_environment* env, struct cherry_value* args);
// ----------------------------------------------------------------------------
......
......@@ -18,6 +18,8 @@
#include "bootstrap.h"
#include <gc.h>
#include <time.h>
#include <openssl/md5.h>
struct cherry_value*
......@@ -54,165 +56,6 @@ cherry_core_type(struct cherry_environment* env, struct cherry_value* args)
struct cherry_value*
cherry_core_add(struct cherry_environment* env, struct cherry_value* args)
{
struct cherry_value* v = cherry_fixnum(0);
while(!IS_NULL(args)) {
struct cherry_value* x = HEAD(args);
switch(x->tag) {
case FIXNUM:
if(IS_FIXNUM(v))
v->fixnum_value += x->fixnum_value;
else
v->float_value += x->fixnum_value;
break;
case FLOAT:
if(IS_FIXNUM(v)) {
v->float_value = v->fixnum_value + x->float_value;
v->tag = FLOAT;
} else {
v->float_value += x->float_value;
}
break;
default:
cherry_env_raise(env, cherry_string("Addition performed with a non-numerical datatype"));
}
args = TAIL(args);
}
return v;
}
struct cherry_value*
cherry_core_sub(struct cherry_environment* env, struct cherry_value* args)
{
if(IS_NULL(args))
return cherry_fixnum(0);
else if(!IS_FIXNUM(HEAD(args)) && !IS_FLOAT(HEAD(args)))
cherry_env_raise(env, cherry_string("First operand in Subtraction is not a numerical datatype"));
struct cherry_value* v = cherry_value_dup(HEAD(args));
args = TAIL(args);
while(!IS_NULL(args)) {
struct cherry_value* x = HEAD(args);
switch(x->tag) {
case FIXNUM:
if(IS_FIXNUM(v))
v->fixnum_value -= x->fixnum_value;
else
v->float_value -= x->fixnum_value;
break;
case FLOAT:
if(IS_FIXNUM(v)) {
v->float_value = v->fixnum_value - x->float_value;
v->tag = FLOAT;
} else {
v->float_value -= x->float_value;
}
break;
default:
cherry_env_raise(env, cherry_string("Subtraction performed with a non-numerical datatype"));
}
args = TAIL(args);
}
return v;
}
struct cherry_value*
cherry_core_mul(struct cherry_environment* env, struct cherry_value* args)
{
struct cherry_value* v = cherry_fixnum(1);
while(!IS_NULL(args)) {
struct cherry_value* x = HEAD(args);
switch(x->tag) {
case FIXNUM:
if(IS_FIXNUM(v))
v->fixnum_value *= x->fixnum_value;
else
v->float_value *= x->fixnum_value;
break;
case FLOAT:
if(IS_FIXNUM(v)) {
v->float_value = v->fixnum_value * x->float_value;
v->tag = FLOAT;
} else {
v->float_value *= x->float_value;
}
break;
default:
cherry_env_raise(env, cherry_string("Multiplication performed with a non-numerical datatype"));
}
args = TAIL(args);
}
return v;
}
struct cherry_value*
cherry_core_div(struct cherry_environment* env, struct cherry_value* args)
{
if(IS_NULL(args))
return cherry_fixnum(0);
else if(!IS_FIXNUM(HEAD(args)) && !IS_FLOAT(HEAD(args)))
cherry_env_raise(env, cherry_string("First operand in Division is not a numerical datatype"));
struct cherry_value* v = cherry_value_dup(HEAD(args));
args = TAIL(args);
while(!IS_NULL(args)) {
struct cherry_value* x = HEAD(args);
switch(x->tag) {
case FIXNUM:
if(x->fixnum_value == 0)
cherry_env_raise(env, cherry_string("Division by Zero"));
if(IS_FIXNUM(v))
v->fixnum_value /= x->fixnum_value;
else
v->float_value /= x->fixnum_value;
break;
case FLOAT:
if(x->float_value == 0.0)
cherry_env_raise(env, cherry_string("Division by Zero"));
if(IS_FIXNUM(v)) {
v->float_value = v->fixnum_value / x->float_value;
v->tag = FLOAT;
} else {
v->float_value /= x->float_value;
}
break;
default:
cherry_env_raise(env, cherry_string("Subtraction performed with a non-numerical datatype"));
}
args = TAIL(args);
}
return v;
}
struct cherry_value*
cherry_core_raise(struct cherry_environment* env, struct cherry_value* args)
{
......@@ -551,6 +394,183 @@ cherry_core_string_to_fixnum(struct cherry_environment* env, struct cherry_value
struct cherry_value*
cherry_core_string_equal(struct cherry_environment* env, struct cherry_value* args)
{
if(IS_NULL(args) || IS_NULL(TAIL(args)) || !IS_STRING(HEAD(args)) || !IS_STRING(HEAD(TAIL(args))))
cherry_env_raise(env, cherry_string("string-equal? expects only two strings"));
struct cherry_value* a = HEAD(args);
struct cherry_value* b = HEAD(TAIL(args));
return (cherry_utf8_compare(a->string_value, b->string_value) == 0)
? cherry_true
: cherry_false;
}
struct cherry_value*
cherry_core_add(struct cherry_environment* env, struct cherry_value* args)
{
struct cherry_value* v = cherry_fixnum(0);
while(!IS_NULL(args)) {
struct cherry_value* x = HEAD(args);
switch(x->tag) {
case FIXNUM:
if(IS_FIXNUM(v))
v->fixnum_value += x->fixnum_value;
else
v->float_value += x->fixnum_value;
break;
case FLOAT:
if(IS_FIXNUM(v)) {
v->float_value = v->fixnum_value + x->float_value;
v->tag = FLOAT;
} else {
v->float_value += x->float_value;
}
break;
default:
cherry_env_raise(env, cherry_string("Addition performed with a non-numerical datatype"));
}
args = TAIL(args);
}
return v;
}
struct cherry_value*
cherry_core_sub(struct cherry_environment* env, struct cherry_value* args)
{
if(IS_NULL(args))
return cherry_fixnum(0);
else if(!IS_FIXNUM(HEAD(args)) && !IS_FLOAT(HEAD(args)))
cherry_env_raise(env, cherry_string("First operand in Subtraction is not a numerical datatype"));
struct cherry_value* v = cherry_value_dup(HEAD(args));
args = TAIL(args);
while(!IS_NULL(args)) {
struct cherry_value* x = HEAD(args);
switch(x->tag) {
case FIXNUM:
if(IS_FIXNUM(v))
v->fixnum_value -= x->fixnum_value;
else
v->float_value -= x->fixnum_value;
break;
case FLOAT:
if(IS_FIXNUM(v)) {
v->float_value = v->fixnum_value - x->float_value;
v->tag = FLOAT;
} else {
v->float_value -= x->float_value;
}
break;
default:
cherry_env_raise(env, cherry_string("Subtraction performed with a non-numerical datatype"));
}
args = TAIL(args);
}
return v;
}
struct cherry_value*
cherry_core_mul(struct cherry_environment* env, struct cherry_value* args)
{
struct cherry_value* v = cherry_fixnum(1);
while(!IS_NULL(args)) {
struct cherry_value* x = HEAD(args);
switch(x->tag) {
case FIXNUM:
if(IS_FIXNUM(v))
v->fixnum_value *= x->fixnum_value;
else
v->float_value *= x->fixnum_value;
break;
case FLOAT:
if(IS_FIXNUM(v)) {
v->float_value = v->fixnum_value * x->float_value;
v->tag = FLOAT;
} else {
v->float_value *= x->float_value;
}
break;
default:
cherry_env_raise(env, cherry_string("Multiplication performed with a non-numerical datatype"));
}
args = TAIL(args);
}
return v;
}
struct cherry_value*
cherry_core_div(struct cherry_environment* env, struct cherry_value* args)
{
if(IS_NULL(args))
return cherry_fixnum(0);
else if(!IS_FIXNUM(HEAD(args)) && !IS_FLOAT(HEAD(args)))
cherry_env_raise(env, cherry_string("First operand in Division is not a numerical datatype"));
struct cherry_value* v = cherry_value_dup(HEAD(args));
args = TAIL(args);
while(!IS_NULL(args)) {
struct cherry_value* x = HEAD(args);
switch(x->tag) {
case FIXNUM:
if(x->fixnum_value == 0)
cherry_env_raise(env, cherry_string("Division by Zero"));
if(IS_FIXNUM(v))
v->fixnum_value /= x->fixnum_value;
else
v->float_value /= x->fixnum_value;
break;
case FLOAT:
if(x->float_value == 0.0)
cherry_env_raise(env, cherry_string("Division by Zero"));
if(IS_FIXNUM(v)) {
v->float_value = v->fixnum_value / x->float_value;
v->tag = FLOAT;
} else {
v->float_value /= x->float_value;
}
break;
default:
cherry_env_raise(env, cherry_string("Subtraction performed with a non-numerical datatype"));
}
args = TAIL(args);
}
return v;
}
struct cherry_value*
cherry_core_not(struct cherry_environment* env, struct cherry_value* args)
{
......@@ -887,6 +907,16 @@ cherry_io_println(struct cherry_environment* env, struct cherry_value* args)
return cherry_true;
}
struct cherry_value*
cherry_system_time(struct cherry_environment* env, struct cherry_value* args)
{
time_t t = time(0);
return cherry_fixnum(t);
}
struct cherry_value*
cherry_system_exit(struct cherry_environment* env, struct cherry_value* args)
{
......@@ -900,4 +930,16 @@ cherry_system_exit(struct cherry_environment* env, struct cherry_value* args)
return cherry_false;
}
struct cherry_value*
cherry_crypto_md5(struct cherry_environment* env, struct cherry_value* args)
{
if(IS_NULL(args) || !IS_STRING(HEAD(args)))
cherry_env_raise(env, cherry_string("md5 expects a string"));
byte_t* buffer = GC_MALLOC(17 * sizeof(byte_t));
size_t hashlen = cherry_utf8_size(HEAD(args)->string_value);
MD5(HEAD(args)->string_value, hashlen, buffer);
return cherry_string(buffer);
}
......@@ -120,7 +120,11 @@ cherry_environment(void)
proc_to_env(env, "string->list", cherry_core_string_to_list);
proc_to_env(env, "string->tuple", cherry_core_string_to_tuple);
proc_to_env(env, "string->fixnum", cherry_core_string_to_fixnum);
proc_to_env(env, "string-equal?", cherry_core_string_equal);
proc_to_env(env, "md5", cherry_crypto_md5);
proc_to_env(env, "time", cherry_system_time);
proc_to_env(env, "exit", cherry_system_exit);
return env;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment