<commit_before>/*
 *
 * predef.c
 *
 * Created at:  01/17/2013 07:20:24 PM
 *
 * Author:  <NAME> <<EMAIL>>
 *
 * License: the MIT license
 *
 */

#include "nemo.h"
#include "predef.h"
#include "exec.h"
#include "nodes.h"
#include "cast.h"
#include "handy.h"

struct PredefFunction predefs[] =
{
  { "print",  predef_print  },
  { "assert", predef_assert },
};

unsigned int predefs_size = 2;

Value predef_print(struct ParamList *params, int paramcount)
{
  Value ret;

  if (params){
    for (struct ParamList *p = params; p != NULL; p = p->next){
      if (p->pos == paramcount - 1)
        printf("%s\n", vtos(dispatchNode(p->param)));
      else
        printf("%s, ", vtos(dispatchNode(p->param)));
    }
  }

  ret.v.i = 1;
  ret.type = TYPE_INTEGER;

  return ret;
}

Value predef_assert(struct ParamList *params, int paramcount)
{
  if (paramcount > 2){
    cerror("too many arguments for function 'assert' (%d when 2 expected)", paramcount);
    exit(1);
  }

  Value ret;
  bool  res = false;

  // 2 arguments
  //
  // comparing them, if they are equal, that's good
  // if not, aborting
  if (paramcount == 2){
    Value first  = dispatchNode(params->param);
    params = params->next;
    Value second = dispatchNode(params->param);

    if (first.type == TYPE_INTEGER){
      if (second.type == TYPE_INTEGER){
        res = first.v.i == second.v.i;
      } else if (second.type == TYPE_FLOATING){
        res = vtof(first) == second.v.f;
      }
    } else if (first.type == TYPE_FLOATING){
      if (second.type == TYPE_INTEGER){
        res = first.v.f == vtof(second);
      } else if (second.type == TYPE_FLOATING){
        res = first.v.f == second.v.f;
      }
    }
  // 1 argument
  //
  // casting that to "bool", if 0, abort, else, that's good
  } else {
    Value first = dispatchNode(params->param);
    res = vtob(first);
  }

  if (!res){
    cerror("assertion failed");
    exit(1);
  }

  ret.v.i = 1;
  ret.type = TYPE_INTEGER;
<commit_msg>Make 'assert' work with strings.<commit_after>/*
 *
 * predef.c
 *
 * Created at:  01/17/2013 07:20:24 PM
 *
 * Author:  <NAME> <<EMAIL>>
 *
 * License: the MIT license
 *
 */

#include "nemo.h"
#include "predef.h"
#include "exec.h"
#include "nodes.h"
#include "cast.h"
#include "handy.h"

struct PredefFunction predefs[] =
{
  { "print",  predef_print  },
  { "assert", predef_assert },
};

unsigned int predefs_size = 2;

Value predef_print(struct ParamList *params, int paramcount)
{
  Value ret;

  if (params){
    for (struct ParamList *p = params; p != NULL; p = p->next){
      if (p->pos == paramcount - 1)
        printf("%s\n", vtos(dispatchNode(p->param)));
      else
        printf("%s, ", vtos(dispatchNode(p->param)));
    }
  }

  ret.v.i = 1;
  ret.type = TYPE_INTEGER;

  return ret;
}

Value predef_assert(struct ParamList *params, int paramcount)
{
  if (paramcount > 2){
    cerror("too many arguments for function 'assert' (%d when 2 expected)", paramcount);
    exit(1);
  }

  Value ret;
  bool  res = false;

  // 2 arguments
  //
  // comparing them, if they are equal, that's good
  // if not, aborting
  if (paramcount == 2){
    Value first  = dispatchNode(params->param);
    params = params->next;
    Value second = dispatchNode(params->param);

    if (first.type == TYPE_INTEGER){
      if (second.type == TYPE_INTEGER){
        res = first.v.i == second.v.i;
      } else if (second.type == TYPE_FLOATING){
        res = vtof(first) == second.v.f;
      }
    } else if (first.type == TYPE_FLOATING){
      if (second.type == TYPE_INTEGER){
        res = first.v.f == vtof(second);
      } else if (second.type == TYPE_FLOATING){
        res = first.v.f == second.v.f;
      }
    } else if (first.type == TYPE_STRING){
      res = true;
      char *str_left = first.v.s;
      char *str_right = vtos(second);
      size_t longer = (strlen(str_left) > strlen(str_right)) ? strlen(str_left) : strlen(str_right);
      for (size_t i = 0; i < longer; i++){
        if (str_left[i] != str_right[i]){
          res = false;
          break;
        }
      }
    }
  // 1 argument
  //
  // casting that to "bool", if 0, abort, else, that's good
  } else {
    Value first = dispatchNode(params->param);
    res = vtob(first);
  }

  if (!res){
    cerror("assertion failed");
    exit(1);
  }

  ret.v.i = 1;
  ret.type = TYPE_INTEGER;

{'fraction_non_alphanumeric': 0.16175115207373272, 'fraction_numerical': 0.012211981566820277, 'mean_word_length': 2.5494685200327063, 'pattern_counts': {'":': 0, '<': 10, '<?xml version=': 0, '>': 28, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1928245', 'n_tokens_mistral': 1619, 'n_tokens_neox': 1567, 'n_words': 397}