<commit_before>#include "llvm_offline_cache.h"

#include "llvm/AsmParser/Parser.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_os_ostream.h"
#include "llvm/IR/Module.h"
#include "taichi/ir/transforms.h"

#include "picosha2.h"

namespace taichi {
namespace lang {

static TI_FORCE_INLINE std::vector<std::uint8_t>
get_offline_cache_key_of_compile_config(CompileConfig *config) {
  TI_ASSERT(config);
  BinaryOutputSerializer serializer;
  serializer.initialize();
  serializer(config->arch);
  serializer(config->debug);
  serializer(config->cfg_optimization);
  serializer(config->check_out_of_bound);
  serializer(config->simd_width);
  serializer(config->opt_level);
  serializer(config->external_optimization_level);
  serializer(config->max_vector_width);
  serializer(config->packed);
  serializer(config->serial_schedule);
  serializer(config->move_loop_invariant_outside_if);
  serializer(config->demote_dense_struct_fors);
  serializer(config->advanced_optimization);
  serializer(config->constant_folding);
  serializer(config->use_llvm);
  serializer(config->fast_math);
  serializer(config->dynamic_index);
  serializer(config->flatten_if);
  serializer(config->make_thread_local);
  serializer(config->make_block_local);
  serializer(config->detect_read_only);
  serializer(config->default_fp->to_string());
  serializer(config->default_ip.to_string());
  serializer(config->extra_flags);
  if (arch_is_cpu(config->arch)) {
    serializer(config->default_cpu_block_dim);
    serializer(config->cpu_max_num_threads);
  } else if (arch_is_gpu(config->arch)) {
    serializer(config->default_gpu_block_dim);
    serializer(config->gpu_max_reg);
    serializer(config->saturating_grid_dim);
    serializer(config->cpu_max_num_threads);
  }
  serializer(config->ad_stack_size);
  serializer(config->default_ad_stack_size);
  serializer(config->random_seed);
  if (config->arch == Arch::cc) {
    serializer(config->cc_compile_cmd);
    serializer(config->cc_link_cmd);
  } else if (config->arch == Arch::opengl) {
    serializer(config->allow_nv_shader_extension);
    serializer(config->use_gles);
  }
  serializer(config->make_mesh_block_local);
  serializer(config->optimize_mesh_reordered_mapping);
  serializer(config->mesh_localize_to_end_mapping);
  serializer(config->mesh_localize_from_end_mapping);
  serializer(config->mesh_localize_all_attr_mappings);
  serializer(config->demote_no_access_mesh_fors);
  serializer(config->experimental_auto_mesh_local);
  serializer(config->auto_mesh_local_default_occupacy);
  serializer.finalize();

  return serializer.data;
}

std::string get_offline_cache_key(CompileConfig *config, Kernel *kernel) {
  std::string kernel_ast_string;
  if (kernel) {
    irpass::re_id(kernel->ir.get());
    irpass::print(kernel->ir.get(), &kernel_ast_string);
  }

  std::vector<std::uint8_t> compile_config_key;
  if (config) {
    compile_config_key = get_offline_cache_key_of_compile_config(config);
  }

  picosha2::hash256_one_by_one hasher;
  hasher.process(compile_config_key.begin(), compile_config_key.end());
  hasher.process(kernel_ast_string.begin(), kernel_ast_string.end());
  hasher.finish();

  auto res = picosha2::get_hash_hex_string(hasher);
  res.insert(res.begin(), kernel->grad ? 'g' : 'n');
  return res;
}

bool LlvmOfflineCacheFileReader::get_kernel_cache(
    LlvmOfflineCache::KernelCacheData &res,
    const std::string &key,
    llvm::LLVMContext &llvm_ctx) {
  res.kernel_key = key;
  std::string filename_prefix = path_ + "/" + key;
  {
    std::string filename = filename_prefix + ".ll";
    llvm::SMDiagnostic err;
    res.owned_module = llvm::parseAssemblyFile(filename, err, llvm_ctx);
    res.module = res.owned_module.get();
    if (!res.module)
      return false;
  }
  {
    std::string filename = filename_prefix + "_otnl.txt";
    std::ifstream in(filename, std::ios::in | std::ios::binary);
    if (!in.is_open())
      return false;
    while (true) {
      std::string line;
      std::getline(in, line, '\n');
      if (line.empty())
        break;
      std::istringstream iss(line);
      auto &task = res.offloaded_task_list.emplace_back();
      iss >> task.name >> task.block_dim >> task.grid_dim;
    }
  }
  return true;
}

void LlvmOfflineCacheFileWriter::dump() {
  for (auto &[k, v] : data_.kernels) {
    std::string filename_prefix = path_ + "/" + k;
    {
      std::string filename = filename_prefix + ".ll";
      std::ofstream os(filename, std::ios::out | std::ios::binary);
      TI_ERROR_IF(!os.is_open(), "File {} open failed", filename);
      llvm::SMDiagnostic err;
      llvm::LLVMContext ctx;
      llvm::raw_os_ostream llvm_os(os);
      if (v.module) {
        mangle_offloaded_task_name(k, v.module, v.offloaded_task_list);
        v.module->print(llvm_os, nullptr);
      } else if (v.owned_module) {
        mangle_offloaded_task_name(k, v.owned_module.get(),
                                   v.offloaded_task_list);
        v.owned_module->print(llvm_os, nullptr);
      } else
        TI_ASSERT(false);
    }
    {
      std::string filename = filename_prefix + "_otnl.txt";
      std::ofstream os(filename, std::ios::out | std::ios::binary);
      TI_ERROR_IF(!os.is_open(), "File {} open failed", filename);
      for (const auto &task : v.offloaded_task_list) {
        os << task.name << ' ' << task.block_dim << ' ' << task.grid_dim
           << '\n';
      }
    }
  }
}

void LlvmOfflineCacheFileWriter::mangle_offloaded_task_name(
    const std::string &kernel_key,
    llvm::Module *module,
    std::vector<LlvmOfflineCache::OffloadedTaskCacheData>
        &offloaded_task_list) {
  if (!mangled_) {
    std::size_t cnt = 0;
    for (auto &e : offloaded_task_list) {
      std::string mangled_name = kernel_key + std::to_string(cnt++);
      auto func = module->getFunction(e.name);
      TI_ASSERT(func != nullptr);
      func->setName(mangled_name);
      e.name = mangled_name;
    }
  }
}

}  // namespace lang
}  // namespace taichi
<commit_msg>[misc] Remove some unnecessary attributes from offline-cache key of compile-config (#4770)<commit_after>#include "llvm_offline_cache.h"

#include "llvm/AsmParser/Parser.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_os_ostream.h"
#include "llvm/IR/Module.h"
#include "taichi/ir/transforms.h"

#include "picosha2.h"

namespace taichi {
namespace lang {

static TI_FORCE_INLINE std::vector<std::uint8_t>
get_offline_cache_key_of_compile_config(CompileConfig *config) {
  TI_ASSERT(config);
  BinaryOutputSerializer serializer;
  serializer.initialize();
  serializer(config->arch);
  serializer(config->debug);
  serializer(config->cfg_optimization);
  serializer(config->check_out_of_bound);
  serializer(config->opt_level);
  serializer(config->external_optimization_level);
  serializer(config->packed);
  serializer(config->move_loop_invariant_outside_if);
  serializer(config->demote_dense_struct_fors);
  serializer(config->advanced_optimization);
  serializer(config->constant_folding);
  serializer(config->fast_math);
  serializer(config->flatten_if);
  serializer(config->make_thread_local);
  serializer(config->make_block_local);
  serializer(config->detect_read_only);
  serializer(config->default_fp->to_string());
  serializer(config->default_ip.to_string());
  if (arch_is_cpu(config->arch)) {
    serializer(config->default_cpu_block_dim);
    serializer(config->cpu_max_num_threads);
  } else if (arch_is_gpu(config->arch)) {
    serializer(config->default_gpu_block_dim);
    serializer(config->gpu_max_reg);
    serializer(config->saturating_grid_dim);
    serializer(config->cpu_max_num_threads);
  }
  serializer(config->ad_stack_size);
  serializer(config->default_ad_stack_size);
  serializer(config->random_seed);
  if (config->arch == Arch::cc) {
    serializer(config->cc_compile_cmd);
    serializer(config->cc_link_cmd);
  } else if (config->arch == Arch::opengl) {
    serializer(config->allow_nv_shader_extension);
    serializer(config->use_gles);
  }
  serializer(config->make_mesh_block_local);
  serializer(config->optimize_mesh_reordered_mapping);
  serializer(config->mesh_localize_to_end_mapping);
  serializer(config->mesh_localize_from_end_mapping);
  serializer(config->mesh_localize_all_attr_mappings);
  serializer(config->demote_no_access_mesh_fors);
  serializer(config->experimental_auto_mesh_local);
  serializer(config->auto_mesh_local_default_occupacy);
  serializer.finalize();

  return serializer.data;
}

std::string get_offline_cache_key(CompileConfig *config, Kernel *kernel) {
  std::string kernel_ast_string;
  if (kernel) {
    irpass::re_id(kernel->ir.get());
    irpass::print(kernel->ir.get(), &kernel_ast_string);
  }

  std::vector<std::uint8_t> compile_config_key;
  if (config) {
    compile_config_key = get_offline_cache_key_of_compile_config(config);
  }

  picosha2::hash256_one_by_one hasher;
  hasher.process(compile_config_key.begin(), compile_config_key.end());
  hasher.process(kernel_ast_string.begin(), kernel_ast_string.end());
  hasher.finish();

  auto res = picosha2::get_hash_hex_string(hasher);
  res.insert(res.begin(), kernel->grad ? 'g' : 'n');
  return res;
}

bool LlvmOfflineCacheFileReader::get_kernel_cache(
    LlvmOfflineCache::KernelCacheData &res,
    const std::string &key,
    llvm::LLVMContext &llvm_ctx) {
  res.kernel_key = key;
  std::string filename_prefix = path_ + "/" + key;
  {
    std::string filename = filename_prefix + ".ll";
    llvm::SMDiagnostic err;
    res.owned_module = llvm::parseAssemblyFile(filename, err, llvm_ctx);
    res.module = res.owned_module.get();
    if (!res.module)
      return false;
  }
  {
    std::string filename = filename_prefix + "_otnl.txt";
    std::ifstream in(filename, std::ios::in | std::ios::binary);
    if (!in.is_open())
      return false;
    while (true) {
      std::string line;
      std::getline(in, line, '\n');
      if (line.empty())
        break;
      std::istringstream iss(line);
      auto &task = res.offloaded_task_list.emplace_back();
      iss >> task.name >> task.block_dim >> task.grid_dim;
    }
  }
  return true;
}

void LlvmOfflineCacheFileWriter::dump() {
  for (auto &[k, v] : data_.kernels) {
    std::string filename_prefix = path_ + "/" + k;
    {
      std::string filename = filename_prefix + ".ll";
      std::ofstream os(filename, std::ios::out | std::ios::binary);
      TI_ERROR_IF(!os.is_open(), "File {} open failed", filename);
      llvm::SMDiagnostic err;
      llvm::LLVMContext ctx;
      llvm::raw_os_ostream llvm_os(os);
      if (v.module) {
        mangle_offloaded_task_name(k, v.module, v.offloaded_task_list);
        v.module->print(llvm_os, nullptr);
      } else if (v.owned_module) {
        mangle_offloaded_task_name(k, v.owned_module.get(),
                                   v.offloaded_task_list);
        v.owned_module->print(llvm_os, nullptr);
      } else
        TI_ASSERT(false);
    }
    {
      std::string filename = filename_prefix + "_otnl.txt";
      std::ofstream os(filename, std::ios::out | std::ios::binary);
      TI_ERROR_IF(!os.is_open(), "File {} open failed", filename);
      for (const auto &task : v.offloaded_task_list) {
        os << task.name << ' ' << task.block_dim << ' ' << task.grid_dim
           << '\n';
      }
    }
  }
}

void LlvmOfflineCacheFileWriter::mangle_offloaded_task_name(
    const std::string &kernel_key,
    llvm::Module *module,
    std::vector<LlvmOfflineCache::OffloadedTaskCacheData>
        &offloaded_task_list) {
  if (!mangled_) {
    std::size_t cnt = 0;
    for (auto &e : offloaded_task_list) {
      std::string mangled_name = kernel_key + std::to_string(cnt++);
      auto func = module->getFunction(e.name);
      TI_ASSERT(func != nullptr);
      func->setName(mangled_name);
      e.name = mangled_name;
    }
  }
}

}  // namespace lang
}  // namespace taichi
<|endoftext|>


<commit_before>#include "../src/alm.h"
#include "../src/memory.h"
#include "alm_wrapper.h"
#include <cstdlib>
#include <string>
#include <iostream>

extern "C" {

    #define MAX_NUM_ALM 10

    static const std::string atom_name[] = {
        "X", "H", "He", "Li", "Be", "B", "C", "N", "O", "F",
        "Ne", "Na", "Mg", "Al", "Si", "P", "S", "Cl", "Ar", "K",
        "Ca", "Sc", "Ti", "V", "Cr", "Mn", "Fe", "Co", "Ni", "Cu",
        "Zn", "Ga", "Ge", "As", "Se", "Br", "Kr", "Rb", "Sr", "Y",
        "Zr", "Nb", "Mo", "Tc", "Ru", "Rh", "Pd", "Ag", "Cd", "In",
        "Sn", "Sb", "Te", "I", "Xe", "Cs", "Ba", "La", "Ce", "Pr",
        "Nd", "Pm", "Sm", "Eu", "Gd", "Tb", "Dy", "Ho", "Er", "Tm",
        "Yb", "Lu", "Hf", "Ta", "W", "Re", "Os", "Ir", "Pt", "Au",
        "Hg", "Tl", "Pb", "Bi", "Po", "At", "Rn", "Fr", "Ra", "Ac",
        "Th", "Pa", "U", "Np", "Pu", "Am", "Cm", "Bk", "Cf", "Es",
        "Fm", "Md", "No", "Lr", "Rf", "Db", "Sg", "Bh", "Hs", "Mt",
        "Ds", "Rg", "Cn", "Uut", "Uuq", "Uup", "Uuh", "Uus", "Uuo"};

    static ALM_NS::ALM *alm[MAX_NUM_ALM];
    static int is_alm_used[MAX_NUM_ALM];
    static int is_alm_init = 0;

    void alm_init(void)
    {
        int id;
        for (id = 0; id < MAX_NUM_ALM; id++) {
            if (alm[id]) {
                delete alm[id];
            }
            alm[id] = NULL;
            is_alm_used[id] = 0;
        }
        is_alm_init = 1;
    }

    int alm_new(void)
    {
        int id;

        if (!is_alm_init) {
            alm_init();
        }

        for (id = 0; id < MAX_NUM_ALM; id++) {
            if (!is_alm_used[id]) {
                alm[id] = new ALM_NS::ALM();
                is_alm_used[id] = 1;
                break;
            }
        }

        if (id == MAX_NUM_ALM) {
            return -1;
        } else {
            return id;
        }
    }

    void alm_delete(const int id)
    {
        if (alm[id]) {
            delete alm[id];
            alm[id] = NULL;
            is_alm_used[id] = 0;
        }
    }

    // void set_output_filename_prefix(const std::string prefix);
    // void set_is_print_symmetry(const int is_printsymmetry);
    // void set_is_print_hessians(const bool print_hessian);
    // void set_symmetry_param(const int nsym);
    // void set_symmetry_tolerance(const double tolerance);
    // void set_displacement_param(const bool trim_dispsign_for_evenfunc);
    // void set_displacement_basis(const std::string str_disp_basis);
    // void set_periodicity(const int is_periodic[3]);

    void alm_set_cell(const int id,
                      const int nat,
                      const double lavec[3][3],
                      const double xcoord[][3],
                      const int kd[])
    {
        int i, j, nkd;
        int nkd_vals[nat], kd_new[nat];
        bool kd_exist;

        nkd_vals[0] = kd[0];
        kd_new[0] = 1;
        nkd = 1;
        for (i = 1; i < nat; ++i) {
            kd_exist = false;
            for (j = 0; j < nkd; ++j) {
                if (nkd_vals[j] == kd[i]) {
                    kd_exist = true;
                    kd_new[i] = j + 1;
                    break;
                }
            }
            if (!kd_exist) {
                nkd_vals[nkd] = kd[i];
                kd_new[i] = nkd + 1;
                ++nkd;
            }
        }
        std::string *kdname = new std::string[nkd];
        //std::string kdname[nkd];
        for (int i = 0; i < nkd; i++) {
            kdname[i] = atom_name[abs(nkd_vals[i]) % 118];
        }

        alm[id]->set_cell(nat, lavec, xcoord, kd_new, kdname);
        delete [] kdname;
    }

    void alm_set_verbosity(const int id, const int verbosity)
    {
        alm[id]->set_verbosity(verbosity);
    }

    // void set_magnetic_params(const unsigned int nat,
    //                          const double* const * magmom,
    //                          const bool lspin,
    //                          const int noncollinear,
    //                          const int trev_sym_mag,
    //                          const std::string str_magmom);

    void alm_set_displacement_and_force(const int id,
                                        const double* u_in,
                                        const double* f_in,
                                        const int nat,
                                        const int ndata_used)
    {
        alm[id]->set_displacement_and_force(u_in, f_in, nat, ndata_used);
    }

    int alm_get_ndata_used(const int id)
    {
        return alm[id]->get_ndata_used();
    }

    void alm_set_constraint_type(const int id,
                                 const int constraint_flag) // ICONST
    {
        alm[id]->set_constraint_type(constraint_flag);
    }

    // void set_fitting_constraint_rotation_axis(const std::string rotation_axis) // ROTAXIS
    // void set_fitting_filenames(const std::string dfile,
    //                            const std::string ffile);

    void alm_define(const int id,
                    const int maxorder,
                    const unsigned int nkd,
                    const int *nbody_include,
                    const double *cutoff_radii_in)
    {
        double ***cutoff_radii;
        int count;

        if (nkd > 0) {
            ALM_NS::allocate(cutoff_radii, maxorder, nkd, nkd);
            count = 0;
            for (int i = 0; i < maxorder; i++) {
                for (unsigned int j = 0; j < nkd; j++) {
                    for (unsigned int k = 0; k < nkd; k++) {
                        cutoff_radii[i][j][k] = cutoff_radii_in[count];
                        count++;
                    }
                }
            }
        } else {
            cutoff_radii = nullptr;
        }

        alm[id]->define(maxorder,
                        nkd,
                        nbody_include,
                        cutoff_radii);

        if (nkd > 0) {
            ALM_NS::deallocate(cutoff_radii);
        }
    }

    void alm_generate_force_constant(const int id)
    {
        alm[id]->generate_force_constant();
    }

    int alm_get_atom_mapping_by_pure_translations(const int id,
                                                  int *map_p2s)
    {
        unsigned int count = 0;

        const std::vector<std::vector<int>> map_p2s_vv = alm[id]->get_atom_mapping_by_pure_translations();

        for (const auto &map_p2s_at_nat_prim : map_p2s_vv) {
            for (const auto trans : map_p2s_at_nat_prim) {
                map_p2s[count] = trans;
            }
        }

        return map_p2s_vv[0].size();
    }

    int alm_get_number_of_displacement_patterns(const int id,
                                                const int fc_order) // harmonic=1,
    {
        return alm[id]->get_number_of_displacement_patterns(fc_order);
    }

    void alm_get_number_of_displaced_atoms(const int id,
                                           int *numbers,
                                           const int fc_order) // harmonic=1,
    {
        alm[id]->get_number_of_displaced_atoms(numbers, fc_order);
    }

    int alm_get_displacement_patterns(const int id,
                                      int *atom_indices,
                                      double *disp_patterns,
                                      const int fc_order) // harmonic=1,
    {
        return alm[id]->get_displacement_patterns(atom_indices,
                                                  disp_patterns,
                                                  fc_order);
    }

    int alm_get_number_of_fc_elements(const int id,
                                      const int fc_order)  // harmonic=1, ...
    {
        return alm[id]->get_number_of_fc_elements(fc_order);
    }

    int alm_get_number_of_irred_fc_elements(const int id,
                                            const int fc_order)
    {
        return alm[id]->get_number_of_irred_fc_elements(fc_order);
    }

    void alm_get_fc_origin(const int id,
                           double *fc_values,
                           int *elem_indices, // (len(fc_values), fc_order + 1) is flatten.
                           const int fc_order)
    {
        alm[id]->get_fc_origin(fc_values, elem_indices, fc_order);
    }

    void alm_get_fc_irreducible(const int id,
                                double *fc_values,
                                int *elem_indices, // (len(fc_values), fc_order + 1) is flatten.
                                const int fc_order)
    {
        alm[id]->get_fc_irreducible(fc_values, elem_indices, fc_order);
    }

    void alm_get_fc_all(const int id,
                        double *fc_values,
                        int *elem_indices, // (len(fc_values), fc_order + 1) is flatten.
                        const int fc_order)
    {
        alm[id]->get_fc_all(fc_values, elem_indices, fc_order);
    }

    void alm_set_fc(const int id, double *fc_in)
    {
        alm[id]->set_fc(fc_in);
    }

    void alm_get_matrix_elements(const int id,
                                 const int ndata_used,
                                 double *amat,
                                 double *bvec)
    {
        alm[id]->get_matrix_elements(ndata_used, amat, bvec);
    }

    void alm_run_suggest(const int id)
    {
        alm[id]->set_run_mode("suggest");
        alm[id]->run_suggest();
    }

    int alm_optimize(const int id, const char *solver)
    {
        alm[id]->set_run_mode("fitting");
        std::string str_solver = std::string(solver);

        int info;

        if (str_solver == "dense") {

            alm[id]->set_sparse_mode(0);
            info = alm[id]->optimize();

        } else if (str_solver == "SimplicialLDLT") {

            alm[id]->set_sparse_mode(1);
            info = alm[id]->optimize();

        } else {
            std::cerr << " Unsupported solver type : " << str_solver << std::endl;
            return EXIT_FAILURE;
        }
        return info;
    }
}
<commit_msg>Fix alm_get_atom_mapping_by_pure_translations about forgetting incrementing count<commit_after>#include "../src/alm.h"
#include "../src/memory.h"
#include "alm_wrapper.h"
#include <cstdlib>
#include <string>
#include <iostream>

extern "C" {

    #define MAX_NUM_ALM 10

    static const std::string atom_name[] = {
        "X", "H", "He", "Li", "Be", "B", "C", "N", "O", "F",
        "Ne", "Na", "Mg", "Al", "Si", "P", "S", "Cl", "Ar", "K",
        "Ca", "Sc", "Ti", "V", "Cr", "Mn", "Fe", "Co", "Ni", "Cu",
        "Zn", "Ga", "Ge", "As", "Se", "Br", "Kr", "Rb", "Sr", "Y",
        "Zr", "Nb", "Mo", "Tc", "Ru", "Rh", "Pd", "Ag", "Cd", "In",
        "Sn", "Sb", "Te", "I", "Xe", "Cs", "Ba", "La", "Ce", "Pr",
        "Nd", "Pm", "Sm", "Eu", "Gd", "Tb", "Dy", "Ho", "Er", "Tm",
        "Yb", "Lu", "Hf", "Ta", "W", "Re", "Os", "Ir", "Pt", "Au",
        "Hg", "Tl", "Pb", "Bi", "Po", "At", "Rn", "Fr", "Ra", "Ac",
        "Th", "Pa", "U", "Np", "Pu", "Am", "Cm", "Bk", "Cf", "Es",
        "Fm", "Md", "No", "Lr", "Rf", "Db", "Sg", "Bh", "Hs", "Mt",
        "Ds", "Rg", "Cn", "Uut", "Uuq", "Uup", "Uuh", "Uus", "Uuo"};

    static ALM_NS::ALM *alm[MAX_NUM_ALM];
    static int is_alm_used[MAX_NUM_ALM];
    static int is_alm_init = 0;

    void alm_init(void)
    {
        int id;
        for (id = 0; id < MAX_NUM_ALM; id++) {
            if (alm[id]) {
                delete alm[id];
            }
            alm[id] = NULL;
            is_alm_used[id] = 0;
        }
        is_alm_init = 1;
    }

    int alm_new(void)
    {
        int id;

        if (!is_alm_init) {
            alm_init();
        }

        for (id = 0; id < MAX_NUM_ALM; id++) {
            if (!is_alm_used[id]) {
                alm[id] = new ALM_NS::ALM();
                is_alm_used[id] = 1;
                break;
            }
        }

        if (id == MAX_NUM_ALM) {
            return -1;
        } else {
            return id;
        }
    }

    void alm_delete(const int id)
    {
        if (alm[id]) {
            delete alm[id];
            alm[id] = NULL;
            is_alm_used[id] = 0;
        }
    }

    // void set_output_filename_prefix(const std::string prefix);
    // void set_is_print_symmetry(const int is_printsymmetry);
    // void set_is_print_hessians(const bool print_hessian);
    // void set_symmetry_param(const int nsym);
    // void set_symmetry_tolerance(const double tolerance);
    // void set_displacement_param(const bool trim_dispsign_for_evenfunc);
    // void set_displacement_basis(const std::string str_disp_basis);
    // void set_periodicity(const int is_periodic[3]);

    void alm_set_cell(const int id,
                      const int nat,
                      const double lavec[3][3],
                      const double xcoord[][3],
                      const int kd[])
    {
        int i, j, nkd;
        int nkd_vals[nat], kd_new[nat];
        bool kd_exist;

        nkd_vals[0] = kd[0];
        kd_new[0] = 1;
        nkd = 1;
        for (i = 1; i < nat; ++i) {
            kd_exist = false;
            for (j = 0; j < nkd; ++j) {
                if (nkd_vals[j] == kd[i]) {
                    kd_exist = true;
                    kd_new[i] = j + 1;
                    break;
                }
            }
            if (!kd_exist) {
                nkd_vals[nkd] = kd[i];
                kd_new[i] = nkd + 1;
                ++nkd;
            }
        }
        std::string *kdname = new std::string[nkd];
        //std::string kdname[nkd];
        for (int i = 0; i < nkd; i++) {
            kdname[i] = atom_name[abs(nkd_vals[i]) % 118];
        }

        alm[id]->set_cell(nat, lavec, xcoord, kd_new, kdname);
        delete [] kdname;
    }

    void alm_set_verbosity(const int id, const int verbosity)
    {
        alm[id]->set_verbosity(verbosity);
    }

    // void set_magnetic_params(const unsigned int nat,
    //                          const double* const * magmom,
    //                          const bool lspin,
    //                          const int noncollinear,
    //                          const int trev_sym_mag,
    //                          const std::string str_magmom);

    void alm_set_displacement_and_force(const int id,
                                        const double* u_in,
                                        const double* f_in,
                                        const int nat,
                                        const int ndata_used)
    {
        alm[id]->set_displacement_and_force(u_in, f_in, nat, ndata_used);
    }

    int alm_get_ndata_used(const int id)
    {
        return alm[id]->get_ndata_used();
    }

    void alm_set_constraint_type(const int id,
                                 const int constraint_flag) // ICONST
    {
        alm[id]->set_constraint_type(constraint_flag);
    }

    // void set_fitting_constraint_rotation_axis(const std::string rotation_axis) // ROTAXIS
    // void set_fitting_filenames(const std::string dfile,
    //                            const std::string ffile);

    void alm_define(const int id,
                    const int maxorder,
                    const unsigned int nkd,
                    const int *nbody_include,
                    const double *cutoff_radii_in)
    {
        double ***cutoff_radii;
        int count;

        if (nkd > 0) {
            ALM_NS::allocate(cutoff_radii, maxorder, nkd, nkd);
            count = 0;
            for (int i = 0; i < maxorder; i++) {
                for (unsigned int j = 0; j < nkd; j++) {
                    for (unsigned int k = 0; k < nkd; k++) {
                        cutoff_radii[i][j][k] = cutoff_radii_in[count];
                        count++;
                    }
                }
            }
        } else {
            cutoff_radii = nullptr;
        }

        alm[id]->define(maxorder,
                        nkd,
                        nbody_include,
                        cutoff_radii);

        if (nkd > 0) {
            ALM_NS::deallocate(cutoff_radii);
        }
    }

    void alm_generate_force_constant(const int id)
    {
        alm[id]->generate_force_constant();
    }

    int alm_get_atom_mapping_by_pure_translations(const int id,
                                                  int *map_p2s)
    {
        unsigned int count = 0;

        const std::vector<std::vector<int>> map_p2s_vv = alm[id]->get_atom_mapping_by_pure_translations();

        for (const auto &map_p2s_at_nat_prim : map_p2s_vv) {
            for (const auto trans : map_p2s_at_nat_prim) {
                map_p2s[count] = trans;
                count++;
            }
        }

        return map_p2s_vv[0].size();
    }

    int alm_get_number_of_displacement_patterns(const int id,
                                                const int fc_order) // harmonic=1,
    {
        return alm[id]->get_number_of_displacement_patterns(fc_order);
    }

    void alm_get_number_of_displaced_atoms(const int id,
                                           int *numbers,
                                           const int fc_order) // harmonic=1,
    {
        alm[id]->get_number_of_displaced_atoms(numbers, fc_order);
    }

    int alm_get_displacement_patterns(const int id,
                                      int *atom_indices,
                                      double *disp_patterns,
                                      const int fc_order) // harmonic=1,
    {
        return alm[id]->get_displacement_patterns(atom_indices,
                                                  disp_patterns,
                                                  fc_order);
    }

    int alm_get_number_of_fc_elements(const int id,
                                      const int fc_order)  // harmonic=1, ...
    {
        return alm[id]->get_number_of_fc_elements(fc_order);
    }

    int alm_get_number_of_irred_fc_elements(const int id,
                                            const int fc_order)
    {
        return alm[id]->get_number_of_irred_fc_elements(fc_order);
    }

    void alm_get_fc_origin(const int id,
                           double *fc_values,
                           int *elem_indices, // (len(fc_values), fc_order + 1) is flatten.
                           const int fc_order)
    {
        alm[id]->get_fc_origin(fc_values, elem_indices, fc_order);
    }

    void alm_get_fc_irreducible(const int id,
                                double *fc_values,
                                int *elem_indices, // (len(fc_values), fc_order + 1) is flatten.
                                const int fc_order)
    {
        alm[id]->get_fc_irreducible(fc_values, elem_indices, fc_order);
    }

    void alm_get_fc_all(const int id,
                        double *fc_values,
                        int *elem_indices, // (len(fc_values), fc_order + 1) is flatten.
                        const int fc_order)
    {
        alm[id]->get_fc_all(fc_values, elem_indices, fc_order);
    }

    void alm_set_fc(const int id, double *fc_in)
    {
        alm[id]->set_fc(fc_in);
    }

    void alm_get_matrix_elements(const int id,
                                 const int ndata_used,
                                 double *amat,
                                 double *bvec)
    {
        alm[id]->get_matrix_elements(ndata_used, amat, bvec);
    }

    void alm_run_suggest(const int id)
    {
        alm[id]->set_run_mode("suggest");
        alm[id]->run_suggest();
    }

    int alm_optimize(const int id, const char *solver)
    {
        alm[id]->set_run_mode("fitting");
        std::string str_solver = std::string(solver);

        int info;

        if (str_solver == "dense") {

            alm[id]->set_sparse_mode(0);
            info = alm[id]->optimize();

        } else if (str_solver == "SimplicialLDLT") {

            alm[id]->set_sparse_mode(1);
            info = alm[id]->optimize();

        } else {
            std::cerr << " Unsupported solver type : " << str_solver << std::endl;
            return EXIT_FAILURE;
        }
        return info;
    }
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: stylematrixreferencecontext.cxx,v $
 *
 * $Revision: 1.2 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#include "oox/drawingml/stylematrixreferencecontext.hxx"
#include "oox/drawingml/colorchoicecontext.hxx"
#include "oox/core/namespaces.hxx"
#include "tokens.hxx"

using rtl::OUString;
using namespace ::oox::core;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::xml::sax;

namespace oox { namespace drawingml {

StyleMatrixReferenceContext::StyleMatrixReferenceContext( ContextHandler& rParent,
    const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& rxAttribs,
        rtl::OUString& rIdentifier, Color& rColor )
: ContextHandler( rParent )
, mrColor( rColor )
{
    rIdentifier = rxAttribs->getOptionalValue( XML_idx );
}

Reference< XFastContextHandler > StyleMatrixReferenceContext::createFastChildContext( sal_Int32 /* aElementToken */, const Reference< XFastAttributeList >& /* xAttribs */ ) throw (SAXException, RuntimeException)
{
    return new colorChoiceContext( *this, mrColor );
}

} }
<commit_msg>INTEGRATION: CWS xmlfilter06 (1.2.8); FILE MERGED 2008/06/30 14:50:17 dr 1.2.8.1: #i10000# resync additions<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: stylematrixreferencecontext.cxx,v $
 *
 * $Revision: 1.3 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#include "oox/drawingml/stylematrixreferencecontext.hxx"
#include "oox/drawingml/colorchoicecontext.hxx"
#include "oox/core/namespaces.hxx"
#include "tokens.hxx"

using ::rtl::OUString;
using namespace ::oox::core;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::xml::sax;

namespace oox { namespace drawingml {

StyleMatrixReferenceContext::StyleMatrixReferenceContext( ContextHandler& rParent, Color& rColor )
: ContextHandler( rParent )
, mrColor( rColor )
{
}

Reference< XFastContextHandler > StyleMatrixReferenceContext::createFastChildContext( sal_Int32 /* aElementToken */, const Reference< XFastAttributeList >& /* rxAttributes */ ) throw (SAXException, RuntimeException)
{
    return new colorChoiceContext( *this, mrColor );
}

} }
<|endoftext|>


<commit_before>//
//  main.cpp
//  dixon
//
//  Created by Tobias Wood on 25/03/2014.
//
//

#include <time.h>
#include <getopt.h>
#include <iostream>
#include <atomic>
#include "Eigen/Dense"

#include "Nifti/Nifti.h"
#include "QUIT/QUIT.h"

using namespace std;
using namespace Eigen;
using namespace QUIT;

//******************************************************************************
// Arguments / Usage
//******************************************************************************
const string usage {
"Usage is: dixon [options] magnitude phase \n\
\
Options:\n\
	--help, -h        : Print this message\n\
	--verbose, -v     : Print more information\n\
	--out, -o path    : Add a prefix to the output filenames\n"
};

static bool verbose = false;
static string outPrefix;
static struct option long_options[] =
{
	{"help", no_argument, 0, 'h'},
	{"verbose", no_argument, 0, 'v'},
	{"mask", required_argument, 0, 'm'},
	{"out", required_argument, 0, 'o'},
	{0, 0, 0, 0}
};
//******************************************************************************
// Main
//******************************************************************************
int main(int argc, char **argv)
{
	//**************************************************************************
	// Argument Processing
	//**************************************************************************
	Nifti::File maskFile;
	MultiArray<int8_t, 3> maskVol;
	int indexptr = 0, c;
	while ((c = getopt_long(argc, argv, "hvm:o:", long_options, &indexptr)) != -1) {
		switch (c) {
			case 'v': verbose = true; break;
			case 'm':
				cout << "Reading mask file " << optarg << endl;
				maskFile.open(optarg, Nifti::Mode::Read);
				maskVol.resize(maskFile.dims());
				maskFile.readVolumes(maskVol.begin(), maskVol.end(), 0, 1);
				break;
			case 'o':
				outPrefix = optarg;
				cout << "Output prefix will be: " << outPrefix << endl;
				break;
			case 'h':
			case '?': // getopt will print an error message
				return EXIT_FAILURE;
		}
	}
	//**************************************************************************
	#pragma mark Gather data
	//**************************************************************************
	if ((argc - optind) != 2) {
		cout << "Requires 1 magnitude file and 1 phase file with 3 echos each as input." << endl << usage << endl;
		return EXIT_FAILURE;
	}

	cout << "Opening magnitude file: " << argv[optind] << endl;
	Nifti::File inputFile;
	inputFile.open(argv[optind++], Nifti::Mode::Read);
	Nifti::Header templateHdr = inputFile.header();
	MultiArray<float, 4> mag{inputFile.dims().head(4)};
	inputFile.readVolumes(mag.begin(), mag.end());
	inputFile.close();

	cout << "Opening phase file: " << argv[optind] << endl;
	inputFile.open(argv[optind++], Nifti::Mode::Read);
	MultiArray<float, 4> phase{inputFile.dims().head(4)};
	inputFile.readVolumes(phase.begin(), phase.end());
	if (!templateHdr.matchesSpace(inputFile.header()) || (maskFile.isOpen() && !templateHdr.matchesSpace(maskFile.header()))) {
		cerr << "Input file dimensions or orientations do not match." << endl;
		return EXIT_FAILURE;
	}
	inputFile.close();

	const auto dims = templateHdr.matrix();
	MultiArray<float, 3> Wv(dims), Fv(dims), Av(dims);
	//**************************************************************************
	// Do the fitting
	//**************************************************************************
	ThreadPool pool;
	cout << "Starting processing..." << endl;
	auto S0 = mag.slice<3>({0,0,0,0},{-1,-1,-1,0});
	auto S1 = mag.slice<3>({0,0,0,1},{-1,-1,-1,0});
	auto S2 = mag.slice<3>({0,0,0,2},{-1,-1,-1,0});
	auto phi0 = phase.slice<3>({0,0,0,0},{-1,-1,-1,0});
	auto phi1 = phase.slice<3>({0,0,0,1},{-1,-1,-1,0});
	auto phi2 = phase.slice<3>({0,0,0,2},{-1,-1,-1,0});
	for (size_t k = 0; k < S0.dims()[2]; k++) {
		clock_t loopStart;
		// Read in data
		if (verbose)
			cout << "Starting slice " << k << "..." << flush;
		loopStart = clock();
		atomic<int> voxCount{0};
		//cout << endl << I0s << endl << I1s << endl << I2s << endl;
		//cout << Ws << endl << Fs << endl << As << endl;
		function<void (const size_t)> processVox = [&] (const size_t j) {
			for (size_t i = 0; i < S0.dims()[0]; i++)
				if (!maskFile.isOpen() || maskVol[{i,j,k}]) {
					// From Ma et al JMR 1997
					Av[{i,j,k}] = sqrt(S2[{i,j,k}] / S0[{i,j,k}]);
					float phi = (phi2[{i,j,k}] - phi0[{i,j,k}]) / 2.;
					float psi = cos((phi1[{i,j,k}] - phi0[{i,j,k}]) - phi);
					float frac = S1[{i,j,k}] / sqrt(S0[{i,j,k}]*S2[{i,j,k}]);
					Wv[{i,j,k}] = (1 + psi * frac) * S0[{i,j,k}] / 2.;
					Fv[{i,j,k}] = (1 - psi * frac) * S0[{i,j,k}] / 2.;
				}
		};
		pool.for_loop(processVox, S0.dims()[1]);

		if (verbose) {
			clock_t loopEnd = clock();
			if (voxCount > 0)
				cout << voxCount << " unmasked voxels, CPU time per voxel was "
				          << ((loopEnd - loopStart) / ((float)voxCount * CLOCKS_PER_SEC)) << " s, ";
			cout << "finished." << endl;
		}
	}

	if (verbose)
		cout << "Writing results." << endl;
	templateHdr.setDim(4,1);
	templateHdr.setDatatype(Nifti::DataType::FLOAT32);
	Nifti::File outW(templateHdr, outPrefix + "W" + OutExt());
	outW.writeVolumes(Wv.begin(), Wv.end());
	Nifti::File outF(templateHdr, outPrefix + "F" + OutExt());
	outF.writeVolumes(Fv.begin(), Fv.end());
	Nifti::File outA(templateHdr, outPrefix + "A" + OutExt());
	outA.writeVolumes(Av.begin(), Av.end());
	return EXIT_SUCCESS;
}

<commit_msg>Changed a .dims() to .matrix().<commit_after>//
//  main.cpp
//  dixon
//
//  Created by Tobias Wood on 25/03/2014.
//
//

#include <time.h>
#include <getopt.h>
#include <iostream>
#include <atomic>
#include "Eigen/Dense"

#include "Nifti/Nifti.h"
#include "QUIT/QUIT.h"

using namespace std;
using namespace Eigen;
using namespace QUIT;

//******************************************************************************
// Arguments / Usage
//******************************************************************************
const string usage {
"Usage is: dixon [options] magnitude phase \n\
\
Options:\n\
	--help, -h        : Print this message\n\
	--verbose, -v     : Print more information\n\
	--out, -o path    : Add a prefix to the output filenames\n"
};

static bool verbose = false;
static string outPrefix;
static struct option long_options[] =
{
	{"help", no_argument, 0, 'h'},
	{"verbose", no_argument, 0, 'v'},
	{"mask", required_argument, 0, 'm'},
	{"out", required_argument, 0, 'o'},
	{0, 0, 0, 0}
};
//******************************************************************************
// Main
//******************************************************************************
int main(int argc, char **argv)
{
	//**************************************************************************
	// Argument Processing
	//**************************************************************************
	Nifti::File maskFile;
	MultiArray<int8_t, 3> maskVol;
	int indexptr = 0, c;
	while ((c = getopt_long(argc, argv, "hvm:o:", long_options, &indexptr)) != -1) {
		switch (c) {
			case 'v': verbose = true; break;
			case 'm':
				cout << "Reading mask file " << optarg << endl;
				maskFile.open(optarg, Nifti::Mode::Read);
				maskVol.resize(maskFile.matrix());
				maskFile.readVolumes(maskVol.begin(), maskVol.end(), 0, 1);
				break;
			case 'o':
				outPrefix = optarg;
				cout << "Output prefix will be: " << outPrefix << endl;
				break;
			case 'h':
			case '?': // getopt will print an error message
				return EXIT_FAILURE;
		}
	}
	//**************************************************************************
	#pragma mark Gather data
	//**************************************************************************
	if ((argc - optind) != 2) {
		cout << "Requires 1 magnitude file and 1 phase file with 3 echos each as input." << endl << usage << endl;
		return EXIT_FAILURE;
	}

	cout << "Opening magnitude file: " << argv[optind] << endl;
	Nifti::File inputFile;
	inputFile.open(argv[optind++], Nifti::Mode::Read);
	Nifti::Header templateHdr = inputFile.header();
	MultiArray<float, 4> mag{inputFile.dims().head(4)};
	inputFile.readVolumes(mag.begin(), mag.end());
	inputFile.close();

	cout << "Opening phase file: " << argv[optind] << endl;
	inputFile.open(argv[optind++], Nifti::Mode::Read);
	MultiArray<float, 4> phase{inputFile.dims().head(4)};
	inputFile.readVolumes(phase.begin(), phase.end());
	if (!templateHdr.matchesSpace(inputFile.header()) || (maskFile.isOpen() && !templateHdr.matchesSpace(maskFile.header()))) {
		cerr << "Input file dimensions or orientations do not match." << endl;
		return EXIT_FAILURE;
	}
	inputFile.close();

	const auto dims = templateHdr.matrix();
	MultiArray<float, 3> Wv(dims), Fv(dims), Av(dims);
	//**************************************************************************
	// Do the fitting
	//**************************************************************************
	ThreadPool pool;
	cout << "Starting processing..." << endl;
	auto S0 = mag.slice<3>({0,0,0,0},{-1,-1,-1,0});
	auto S1 = mag.slice<3>({0,0,0,1},{-1,-1,-1,0});
	auto S2 = mag.slice<3>({0,0,0,2},{-1,-1,-1,0});
	auto phi0 = phase.slice<3>({0,0,0,0},{-1,-1,-1,0});
	auto phi1 = phase.slice<3>({0,0,0,1},{-1,-1,-1,0});
	auto phi2 = phase.slice<3>({0,0,0,2},{-1,-1,-1,0});
	for (size_t k = 0; k < S0.dims()[2]; k++) {
		clock_t loopStart;
		// Read in data
		if (verbose)
			cout << "Starting slice " << k << "..." << flush;
		loopStart = clock();
		atomic<int> voxCount{0};
		//cout << endl << I0s << endl << I1s << endl << I2s << endl;
		//cout << Ws << endl << Fs << endl << As << endl;
		function<void (const size_t)> processVox = [&] (const size_t j) {
			for (size_t i = 0; i < S0.dims()[0]; i++)
				if (!maskFile.isOpen() || maskVol[{i,j,k}]) {
					// From Ma et al JMR 1997
					Av[{i,j,k}] = sqrt(S2[{i,j,k}] / S0[{i,j,k}]);
					float phi = (phi2[{i,j,k}] - phi0[{i,j,k}]) / 2.;
					float psi = cos((phi1[{i,j,k}] - phi0[{i,j,k}]) - phi);
					float frac = S1[{i,j,k}] / sqrt(S0[{i,j,k}]*S2[{i,j,k}]);
					Wv[{i,j,k}] = (1 + psi * frac) * S0[{i,j,k}] / 2.;
					Fv[{i,j,k}] = (1 - psi * frac) * S0[{i,j,k}] / 2.;
				}
		};
		pool.for_loop(processVox, S0.dims()[1]);

		if (verbose) {
			clock_t loopEnd = clock();
			if (voxCount > 0)
				cout << voxCount << " unmasked voxels, CPU time per voxel was "
				          << ((loopEnd - loopStart) / ((float)voxCount * CLOCKS_PER_SEC)) << " s, ";
			cout << "finished." << endl;
		}
	}

	if (verbose)
		cout << "Writing results." << endl;
	templateHdr.setDim(4,1);
	templateHdr.setDatatype(Nifti::DataType::FLOAT32);
	Nifti::File outW(templateHdr, outPrefix + "W" + OutExt());
	outW.writeVolumes(Wv.begin(), Wv.end());
	Nifti::File outF(templateHdr, outPrefix + "F" + OutExt());
	outF.writeVolumes(Fv.begin(), Fv.end());
	Nifti::File outA(templateHdr, outPrefix + "A" + OutExt());
	outA.writeVolumes(Av.begin(), Av.end());
	return EXIT_SUCCESS;
}

<|endoftext|>


<commit_before>#include "llvm/ADT/APInt.h"
#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/NoFolder.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Verifier.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <iostream>

using namespace llvm;
using namespace std;

static LLVMContext C;
static IRBuilder<NoFolder> Builder(C);
static std::unique_ptr<Module> M = llvm::make_unique<Module>("calc", C);

//===----------------------------------------------------------------------===//
// Lexer
//===----------------------------------------------------------------------===//
// The lexer returns tokens [0-255] if it is an unknown character, otherwise one
// of these for known things.

enum Token {
  tok_eof = -1,

  tok_if = -2,

  tok_arg = -3,
  tok_number = -4,

  tok_lparan = -5,
  tok_rparan = -6,

  tok_comment = -7, // we don't need a token!
  tok_true = -8,
  tok_false = -9,
  tok_add = -10,
  tok_sub = -11,
  tok_mul = -12,
  tok_div = -13,
  tok_mod = -14,
  tok_gt = -15,
  tok_gte = -16,
  tok_lt = -17,
  tok_lte = -18,
  tok_eq = -19,
  tok_neq = -20
};

static std::string IdentifierStr; // Filled in if tok_identifier
static double NumVal;             // Filled in if tok_number
static std::string ArgName;		// a0, a1,...

/// gettok - Return the next token from standard input.
static int gettok() {
  static int LastChar = ' ';

  // Skip any whitespace.
  while (isspace(LastChar))
    LastChar = getchar();

  if (isalpha(LastChar)) { // arg: a[0-5]
    IdentifierStr = LastChar;
    while (isalnum((LastChar = getchar())))
      IdentifierStr += LastChar;

    if (IdentifierStr == "if")
      return tok_if;
	if(IdentifierStr == "true")
		return tok_true;
	if(IdentifierStr=="false")
		return tok_false;
    if (IdentifierStr == "a0"|| IdentifierStr == "a1"|| IdentifierStr == "a2"|| IdentifierStr == "a3" || IdentifierStr == "a4"|| IdentifierStr == "a5") {
	  ArgName = IdentifierStr;
		return tok_arg;
	}
  }

  if (isdigit(LastChar)) { // Number: [0-9]+ only integers
    std::string NumStr;
    do {
      NumStr += LastChar;
      LastChar = getchar();
    } while (isdigit(LastChar));

    NumVal = strtod(NumStr.c_str(), nullptr);
    return tok_number;
  }

  if (LastChar == '#') {
    // Comment until end of line.
    do
      LastChar = getchar();
    while (LastChar != EOF && LastChar != '\n' && LastChar != '\r');

    if (LastChar != EOF)
      return gettok();
  }
	if(last_char=='(') return tok_lparan;
	if(last_char==')') return tok_rparan;
	if(last_char=='+') return tok_add;
	if(last_char=='-'){
		last_char= getchar();
		if(last_char==' ') return tok_sub;
		if(isdigit(last_char)){
			std::string neg=last_char;
			while(isdigit(last_char=getchar())){
				neg+= last_char;
			}
			NumVal = -1*strtod(neg.c_str(),nullptr);
			return tok_number;
		}
	}
	if(last_char=='*') return tok_mul;
	if(last_char=='/') return tok_div;
	if(last_char=='%') return tok_mod;
	if(last_char=='>'){
		match=last_char;
		last_char=getchar();
		match+=last_char;
		if(match==">="){
			match=""; //reset
		   	return tok_gte;
		}
		match="";
		return tok_gt;
	}
	if(last_char=='<'){
		match=last_char;
		last_char=getchar();
		match+=last_char;
		if(match=="<="){
			match="";
			return tok_lte;
		}
		match="";
		return tok_lt;
	}
	if(last_char=='='){
		match=last_char;
		last_char=getchar();
		match+= last_char;
		if(match=="=="){
			match="";
			return tok_eq;
		}
		match = "";
		cout << "SCANNER ERROR NEAR =" << endl;
	}
	if(last_char == '!'){
		match= last_char;
		last_char = getchar();
		match+= last_char;
		if(match=="!="){
			match = "";
			return tok_neq;
		}
		match = "";
		cout << "SCANNER ERROR NEAR =" << endl;
	}
  // Check for end of file.  Don't eat the EOF.
  if (LastChar == EOF)
    return tok_eof;
  // Otherwise, just return the character as its ascii value.
  int ThisChar = LastChar;
  LastChar = getchar();
  return ThisChar;
}

//===----------------------------------------------------------------------===//
// Abstract Syntax Tree (aka Parse Tree)
//===----------------------------------------------------------------------===//
namespace {
/// ExprAST - Base class for all expression nodes.
class ExprAST {
public:
  virtual ~ExprAST() {}
  virtual Value *codegen() = 0;
};

/// NumberExprAST - Expression class for numeric literals like "1", only integers
class NumberExprAST : public ExprAST {
  int Val; // convert to APInt(64,Val) during codegen

public:
  NumberExprAST(int Val) : Val(Val) {}
  Value *codegen() override;
};

/// ArgExprAST - Expression class for referencing an argument, like "a0,a1,..,a5".
class ArgExprAST : public ExprAST {
   std::string Name;
public:
  ArgExprAST(const std::string &Name) : Name(Name) {}
  Value *codegen() override;
};

/// ConditionaConsAST - true | false
class ConditionConstExprAST : public ExprAST{
	unsigned int val; // either 1 or 0, convert to i1 when generating code
	public:
		ConditionConstExprAST(unsigned int val) : val(val){}
		Value *codegen() override;

}
/// BinaryExprAST - Expression class for a binary operator. eg. + 1 1
class BinaryExprAST : public ExprAST {
  int Op; //hold the token
  std::unique_ptr<ExprAST> First, Second;

public:
  BinaryExprAST(int Op, std::unique_ptr<ExprAST> First,
                std::unique_ptr<ExprAST> Second)
      : Op(Op), First(std::move(First)), Second(std::move(Second)) {}
  Value *codegen() override;
};

/// ConditionExprAST - Expression class for a conditional operator, i.e., 'if'
class ConditionExprAST : public ExprAST{
	std::unique_prt<ExprAST> Branch, Then,Else;

public:
	ConditionExprAST(std::unique_prt<ExprAST> Branch, std::unique_prt<ExprAST> Then,std::unique_prt<ExprAST> Else):Branch(std::move(Branch)), Then(std::move(Then)), Else(std::move(Else)){}
	Value *codegen() override;
}

} // end anonymous namespace

//===----------------------------------------------------------------------===//
// Parser
//===----------------------------------------------------------------------===//

/// CurTok/getNextToken - Provide a simple token buffer.  CurTok is the current
/// token the parser is looking at.  getNextToken reads another token from the
/// lexer and updates CurTok with its results.
static int CurTok;
static int getNextToken() { return CurTok = gettok(); }

/// LogError* - These are little helper functions for error handling.
std::unique_ptr<ExprAST> LogError(const char *Str) {
  fprintf(stderr, "Error: %s\n", Str);
  return nullptr;
}

// Behold! Real parsing begins here
static std::unique_ptr<ExprAST> ParseExpression();

/// numberexpr ::= number
static std::unique_ptr<ExprAST> ParseNumberExpr() {
  auto Result = llvm::make_unique<NumberExprAST>(NumVal);
  getNextToken(); // consume the number
  return std::move(Result);
}

/// numberexpr ::= Arg
static std::unique_ptr<ExprAST> ParseArgExpr(){
	auto Result = llvm::make_unique<ArgExprAST>(ArgName);
	getNextToken();
	return std::move(Result);
}
/// branch ::= true | false
static std::unique_ptr<ExprAST> ParseBranchConsExpr(){

	unsigned int val;
	if(CurTok == tok_true){
	   	val =1;
		return llvm::make_unique<ConditionConstExprAST>(val);
	}
	if(CurTok == tok_false){
	   	val = 0;
		return llvm::make_unique<ConditionConstExprAST>(val);
	}
	return LogError("Conditional Constant Parsing Error");
}

// expression ::= '(' expression ')'
static std::unique_ptr<ExprAST> ParseParenExpr() {
  getNextToken(); // eat (.
  auto V = ParseExpression();
  if (!V)
    return nullptr;
  getNextToken(); // eat ).
  return V;
}

//	expression::= '(' op expression expression ')'
static std::unique_ptr<ExprAST> ParseBinExpr(){
	int op = CurTok;
	getNextToken();
	auto first = ParseExpression();
	if(!first) return LogError("Binary Expression Parsing Error, first operand");
	getNextToken();
	auto second = ParseExpression();
	if(!second) return LogError("Binary Expression Parsing Error, second operand");

	first = llvm::make_unique<BinaryExprAST>(op,std::move(first),std::move(second));
	return first;
}

// expression::= '(' if condition expression expression ')'
static std::unique_ptr<ExprAST> ParseConditionExpr(){
	//CurTok = 'if'
	getNextToken();

	auto condition = ParseExpression();
	if(!condition) LogError("Conditional Expression Parsing Error");
	auto first = ParseExpression();
	if(!first) LogError("Then Expression Parsing Error");
	auto second = ParseExpression();
	if(!second) LogError("Else Expression Parsing Error");

	return llvm::make_unique<ConditionExprAST>(std::move(condition),std::move(first),std::move(second));

}

/// primary parser
static std::unique_ptr<ExprAST> ParseExpression() {
  switch (CurTok) {
  default:
    return LogError("unknown token when expecting an expression");
  case tok_arg:
	return ParseArgExpr();
  case tok_number:
    return ParseNumberExpr();
  case tok_lparan:
    return ParseParenExpr();
  case tok_add:
  case tok_sub:
  case tok_mul:
  case tok_div:
  case tok_mod:
  case tok_gt:
  case tok_gte:
  case tok_lt:
  case tok_lte:
  case tok_eq:
  case tok_neq:
	return ParseBinExpr();
  }
}

//===----------------------------------------------------------------------===//
// Code Generation
//===----------------------------------------------------------------------===//

Value *LogErrorV(const char *Str) {
  LogError(Str);
  return nullptr;
}

Value *NumberExprAST::codegen() {
  return ConstantInt::get(C, APInt(64,Val));
}

Value *ArgExprAST::codegen(){
	Value *V = ArgName;
	if(!V){
		return nullptr;
	}
	return V;
}

Value *BinaryExprAST::codegen() {
  Value *First = First->codegen();
  Value *Second = Second->codegen();
  if (!First || !Second)
    return nullptr;
	switch(op){
	case tok_add:
		return Builder.CreateAdd(First, Second, "addtmp");
   case tok_sub:
    return Builder.CreateSub(First, Second, "subtmp");
   case tok_mul:
    return Builder.CreateMul(First, Second, "multmp");
  case tok_div:
	return Builder.CreateDiv(First,Second,"divtmp");
  case tok_mod:
	return Builder.CreateURem(First, Second, "modtmp");
  case tok_gt:
	return Builder.CreateFCmpUGT(First,Second,"gttmp");
  case tok_gte:
	return Builder.CreateFCmpUGE(First,Second,"gtetmp");
  case tok_lt:
	return Builder.CreateFCmpLGT(First,Second,"lttmp");
  case tok_lte:
	return Builder.CreateFCmpLGE(First,Second,"ltetmp");
  case tok_eq:
	return Builder.CreateFCmpUEQ(First,Second,"eqtmp");
  case tok_neq:
	return Builder.CreateFCmpUNE(First,Second,"neqtmp");
 }
    return LogErrorV("invalid binary operator");
}

Value *ConditionExprAST::codegen(){
	Value *Br = Branch->codegen();
	if(!BranchRes) return nullptr;
Br = Builder.CreateFCmpONE(Br,ConstantInt::get(C,APInt(1,0)),""); //i1

	Function *f = Builder.GetInsterBlock()->getParent();

	BasicBlock *ThenBB = BasicBlock::Create(C,"then",f);
	BasicBlock *ElseBB = BasicBlock::Create(C,"else");
	BasicBlock *MergeBB = BasicBlock::Create(C,"");

	Builder.CreateCondBr(Br, ThenBB, ElseBB);

	Builder.SetInsertPoint(ThenBB);

	Value *then_val = Then->codegen();
	if(!then_val) return nullptr;

	Builder.CreateBr(MergeBB);

	ThenBB = Builder.GetInsertBlock();
	f->getBasicBlockList().push_back(ElseBB);
	Builder.SetInsertPoint(ElseBB);

	Value *else_val = Else->codegen();
	if(!else_val) return nullptr;

	Builder.CreateBr(MergeBB);
	ElseBB = Builder.GetInsertBlock();

	f->getBasicBlockList().push_back(MergeBB);
	Builder.SetInsertPoint(MergeBB);
	PHINode *PN = Builder.CreatePHI(Type::getInt64Ty(C),2,"iftmp");

	PN->addIncoming(then_val,ThenBB);
	PN->addIncoming(else_val,ElseBB);

	return PN;
}

static int compile() {
  M->setTargetTriple(llvm::sys::getProcessTriple());
  std::vector<Type *> SixInts(6, Type::getInt64Ty(C));
  FunctionType *FT = FunctionType::get(Type::getInt64Ty(C), SixInts, false);
  Function *F = Function::Create(FT, Function::ExternalLinkage, "f", &*M);
  BasicBlock *BB = BasicBlock::Create(C, "entry", F);
  Builder.SetInsertPoint(BB);

  // codegen

  Value *RetVal = ConstantInt::get(C, APInt(64, 0));
  Builder.CreateRet(RetVal);
  assert(!verifyModule(*M, &outs()));
  M->dump();
  return 0;
}

int main(void) { return compile(); }
<commit_msg>compiling parser, needs debugging for runtime issues<commit_after>/*
 *	References:
 *	[1] LLVM Cookbook - Mayur Pandey, Suyog Sarda
 *	[2] LLVM tutorial - http://llvm.org/docs/tutorial/index.html
 */

#include "llvm/ADT/APInt.h"
#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/NoFolder.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Verifier.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <iostream>

using namespace llvm;
using namespace std;

static LLVMContext C;
static IRBuilder<NoFolder> Builder(C);
static std::unique_ptr<Module> M = llvm::make_unique<Module>("calc", C);
static std::map<std::string, Value*> ArgValues;
//===----------------------------------------------------------------------===//
// Lexer
//===----------------------------------------------------------------------===//
// The lexer returns tokens [0-255] if it is an unknown character, otherwise one
// of these for known things.

enum Token {
  tok_eof = -1,
  tok_if = -2,
  tok_arg = -3,
  tok_number = -4,
  tok_lparan = -5,
  tok_rparan = -6,
  tok_comment = -7, // we don't need a token!
  tok_true = -8,
  tok_false = -9,
  tok_add = -10,
  tok_sub = -11,
  tok_mul = -12,
  tok_div = -13,
  tok_mod = -14,
  tok_gt = -15,
  tok_gte = -16,
  tok_lt = -17,
  tok_lte = -18,
  tok_eq = -19,
  tok_neq = -20
};

static std::string IdentifierStr; // Filled in if tok_identifier
static double NumVal;             // Filled in if tok_number
static std::string ArgName;		// a0, a1,...
static std::string match;
/// gettok - Return the next token from standard input.
static int gettok() {
  static char LastChar = ' ';

  // Skip any whitespace.
  while (isspace(LastChar))
    LastChar = getchar();

  if (isalpha(LastChar)) { // arg: a[0-5]
    IdentifierStr = LastChar;
    while (isalnum((LastChar = getchar())))
      IdentifierStr += LastChar;

    if (IdentifierStr == "if")
      return tok_if;
	if(IdentifierStr == "true")
		return tok_true;
	if(IdentifierStr=="false")
		return tok_false;
    if (IdentifierStr == "a0"|| IdentifierStr == "a1"|| IdentifierStr == "a2"|| IdentifierStr == "a3" || IdentifierStr == "a4"|| IdentifierStr == "a5") {
	  ArgName = IdentifierStr;
		return tok_arg;
	}
  }

  if (isdigit(LastChar)) { // Number: [0-9]+ only integers
    std::string NumStr;
    do {
      NumStr += LastChar;
      LastChar = getchar();
    } while (isdigit(LastChar));

    NumVal = strtod(NumStr.c_str(), nullptr);
    return tok_number;
  }

  if (LastChar == '#') {
    // Comment until end of line.
    do
      LastChar = getchar();
    while (LastChar != EOF && LastChar != '\n' && LastChar != '\r');

    if (LastChar != EOF)
      return gettok();
  }
	if(LastChar=='(') return tok_lparan;
	if(LastChar==')') return tok_rparan;
	if(LastChar=='+') return tok_add;
	if(LastChar=='-'){
		LastChar= getchar();
		if(LastChar==' ') return tok_sub;
		if(isdigit(LastChar)){
			std::string neg;
			neg+=LastChar;
			while(isdigit(LastChar=getchar())){
				neg+= LastChar;
			}
			NumVal = -1*strtod(neg.c_str(),nullptr);
			return tok_number;
		}
	}
	if(LastChar=='*') return tok_mul;
	if(LastChar=='/') return tok_div;
	if(LastChar=='%') return tok_mod;
	if(LastChar=='>'){
		LastChar=getchar();
		if(LastChar=='='){
		   	return tok_gte;
		}
		return tok_gt;
	}
	if(LastChar=='<'){
		LastChar=getchar();
		if(LastChar=='='){
			return tok_lte;
		}
		return tok_lt;
	}
	if(LastChar=='='){
		LastChar=getchar();
		if(LastChar=='='){
			return tok_eq;
		}
		cout << "SCANNER ERROR NEAR =" << endl;
	}
	if(LastChar == '!'){
		LastChar = getchar();
		if(LastChar == '='){
			return tok_neq;
		}
		cout << "SCANNER ERROR NEAR =" << endl;
	}
  // Check for end of file.  Don't eat the EOF.
  if (LastChar == EOF)
    return tok_eof;
  // Otherwise, just return the character as its ascii value.
  int ThisChar = LastChar;
  LastChar = getchar();
  return ThisChar;
}

//===----------------------------------------------------------------------===//
// Abstract Syntax Tree (aka Parse Tree)
//===----------------------------------------------------------------------===//
namespace {
/// ExprAST - Base class for all expression nodes.
class ExprAST {
public:
  virtual ~ExprAST() {}
  virtual Value *codegen() = 0;
};

/// NumberExprAST - Expression class for numeric literals like "1", only integers
class NumberExprAST : public ExprAST {
  int Val; // convert to APInt(64,Val) during codegen

public:
  NumberExprAST(int Val) : Val(Val) {}
  Value *codegen() override;
};

/// ArgExprAST - Expression class for referencing an argument, like "a0,a1,..,a5".
class ArgExprAST : public ExprAST {
   std::string Name;
public:
  ArgExprAST(const std::string &Name) : Name(Name) {}
  Value *codegen() override;
};

/// ConditionaConsAST - true | false
class ConditionConstExprAST : public ExprAST{
	unsigned int val; // either 1 or 0, convert to i1 when generating code
	public:
		ConditionConstExprAST(unsigned int val) : val(val){}
		Value *codegen() override;

};
/// BinaryExprAST - Expression class for a binary operator. eg. + 1 1
class BinaryExprAST : public ExprAST {
  int Op; //hold the token
  std::unique_ptr<ExprAST> First, Second;

public:
  BinaryExprAST(int Op, std::unique_ptr<ExprAST> First,
                std::unique_ptr<ExprAST> Second)
      : Op(Op), First(std::move(First)), Second(std::move(Second)) {}
  Value *codegen() override;
};

/// ConditionExprAST - Expression class for a conditional operator, i.e., 'if'
class ConditionExprAST : public ExprAST{
	std::unique_ptr<ExprAST> Branch, Then,Else;

public:
	ConditionExprAST(std::unique_ptr<ExprAST> Branch, std::unique_ptr<ExprAST> Then,std::unique_ptr<ExprAST> Else):Branch(std::move(Branch)), Then(std::move(Then)), Else(std::move(Else)){}
	Value *codegen() override;
};

} // end anonymous namespace

//===----------------------------------------------------------------------===//
// Parser
//===----------------------------------------------------------------------===//

/// CurTok/getNextToken - Provide a simple token buffer.  CurTok is the current
/// token the parser is looking at.  getNextToken reads another token from the
/// lexer and updates CurTok with its results.
static int CurTok;
static int getNextToken() { return CurTok = gettok(); }

/// LogError* - These are little helper functions for error handling.
std::unique_ptr<ExprAST> LogError(const char *Str) {
  fprintf(stderr, "Error: %s\n", Str);
  return nullptr;
}

// Behold! Real parsing begins here
static std::unique_ptr<ExprAST> ParseExpression();

/// numberexpr ::= number
static std::unique_ptr<ExprAST> ParseNumberExpr() {
  auto Result = llvm::make_unique<NumberExprAST>(NumVal);
  return std::move(Result);
}

/// numberexpr ::= Arg
static std::unique_ptr<ExprAST> ParseArgExpr(){
	auto Result = llvm::make_unique<ArgExprAST>(ArgName);
	getNextToken();
	return std::move(Result);
}
/// branch ::= true | false
static std::unique_ptr<ExprAST> ParseBranchConsExpr(){

	unsigned int val;
	if(CurTok == tok_true){
	   	val =1;
		return llvm::make_unique<ConditionConstExprAST>(val);
	}
	if(CurTok == tok_false){
	   	val = 0;
		return llvm::make_unique<ConditionConstExprAST>(val);
	}
	return LogError("Conditional Constant Parsing Error");
}

// expression ::= '(' expression ')'
static std::unique_ptr<ExprAST> ParseParenExpr() {
  getNextToken(); // eat (.
  auto V = ParseExpression();
  if (!V)
    return nullptr;
  getNextToken(); // eat ).
  return V;
}

//	expression::= '(' op expression expression ')'
static std::unique_ptr<ExprAST> ParseBinExpr(){
	int op = CurTok;
	getNextToken();
	auto first = ParseExpression();
	if(!first) return LogError("Binary Expression Parsing Error, first operand");
	getNextToken();
	auto second = ParseExpression();
	if(!second) return LogError("Binary Expression Parsing Error, second operand");

	first = llvm::make_unique<BinaryExprAST>(op,std::move(first),std::move(second));
	return first;
}

// expression::= '(' if condition expression expression ')'
static std::unique_ptr<ExprAST> ParseConditionExpr(){
	//CurTok = 'if'
	getNextToken();

	auto condition = ParseExpression();
	if(!condition) LogError("Conditional Expression Parsing Error");
	auto first = ParseExpression();
	if(!first) LogError("Then Expression Parsing Error");
	auto second = ParseExpression();
	if(!second) LogError("Else Expression Parsing Error");

	return llvm::make_unique<ConditionExprAST>(std::move(condition),std::move(first),std::move(second));

}

/// primary parser
static std::unique_ptr<ExprAST> ParseExpression() {
  switch (CurTok) {
  default:
    return LogError("unknown token when expecting an expression");
  case tok_arg:
	return ParseArgExpr();
  case tok_number:
    return ParseNumberExpr();
  case tok_lparan:
    return ParseParenExpr();
  case tok_add:
  case tok_sub:
  case tok_mul:
  case tok_div:
  case tok_mod:
  case tok_gt:
  case tok_gte:
  case tok_lt:
  case tok_lte:
  case tok_eq:
  case tok_neq:
	return ParseBinExpr();
  }
}

//===----------------------------------------------------------------------===//
// Code Generation
//===----------------------------------------------------------------------===//

Value *LogErrorV(const char *Str) {
  LogError(Str);
  return nullptr;
}

Value *NumberExprAST::codegen() {
  return ConstantInt::get(C, APInt(64,Val));
}

Value *ArgExprAST::codegen(){
	Value *V = ArgValues[ArgName];
	if(!V){
		return nullptr;
	}
	return V;
}

Value *BinaryExprAST::codegen() {
  Value *first = First->codegen();
  Value *second = Second->codegen();
  if (!First || !Second)
    return nullptr;
	switch(Op){
	case tok_add:
		return Builder.CreateAdd(first, second, "addtmp");
   case tok_sub:
    return Builder.CreateSub(first, second, "subtmp");
   case tok_mul:
    return Builder.CreateMul(first, second, "multmp");
  case tok_div:
	return Builder.CreateUDiv(first,second,"divtmp");
  case tok_mod:
	return Builder.CreateURem(first, second, "modtmp");
  case tok_gt:
	return Builder.CreateFCmpUGT(first,second,"gttmp");
  case tok_gte:
	return Builder.CreateFCmpUGE(first,second,"gtetmp");
  case tok_lt:
	return Builder.CreateFCmpULT(first,second,"lttmp");
  case tok_lte:
	return Builder.CreateFCmpULE(first,second,"ltetmp");
  case tok_eq:
	return Builder.CreateFCmpUEQ(first,second,"eqtmp");
  case tok_neq:
	return Builder.CreateFCmpUNE(first,second,"neqtmp");
 }
    return LogErrorV("invalid binary operator");
}

Value *ConditionExprAST::codegen(){
	Value *Br = Branch->codegen();
	if(!Br) return nullptr;
Br = Builder.CreateFCmpONE(Br,ConstantInt::get(C,APInt(1,0)),""); //i1

	Function *f = Builder.GetInsertBlock()->getParent();

	BasicBlock *ThenBB = BasicBlock::Create(C,"then",f);
	BasicBlock *ElseBB = BasicBlock::Create(C,"else");
	BasicBlock *MergeBB = BasicBlock::Create(C,"");

	Builder.CreateCondBr(Br, ThenBB, ElseBB);

	Builder.SetInsertPoint(ThenBB);

	Value *then_val = Then->codegen();
	if(!then_val) return nullptr;

	Builder.CreateBr(MergeBB);

	ThenBB = Builder.GetInsertBlock();
	f->getBasicBlockList().push_back(ElseBB);
	Builder.SetInsertPoint(ElseBB);

	Value *else_val = Else->codegen();
	if(!else_val) return nullptr;

	Builder.CreateBr(MergeBB);
	ElseBB = Builder.GetInsertBlock();

	f->getBasicBlockList().push_back(MergeBB);
	Builder.SetInsertPoint(MergeBB);
	PHINode *PN = Builder.CreatePHI(Type::getInt64Ty(C),2,"iftmp");

	PN->addIncoming(then_val,ThenBB);
	PN->addIncoming(else_val,ElseBB);

	return PN;
}

static int compile() {
  M->setTargetTriple(llvm::sys::getProcessTriple());
  std::vector<Type *> SixInts(6, Type::getInt64Ty(C));
  FunctionType *FT = FunctionType::get(Type::getInt64Ty(C), SixInts, false);
  Function *F = Function::Create(FT, Function::ExternalLinkage, "f", &*M);
  BasicBlock *BB = BasicBlock::Create(C, "entry", F);
  Builder.SetInsertPoint(BB);

  while(true){
	getNextToken();
	if(CurTok == EOF) return 0;
	auto V = ParseExpression();
	if(!V) return 1;
	Value *generated = V->codegen();
  }

  Value *RetVal = ConstantInt::get(C, APInt(64, 0));
  Builder.CreateRet(RetVal);
  assert(!verifyModule(*M, &outs()));
  M->dump();
  return 0;
}

int main(void) { return compile(); }
<|endoftext|>


<commit_before>#include "globals.hpp"
#include "PortalItem.hpp"
#include <cmath>
PortalItem::PortalItem(sf::Sprite* sprite):Item(sprite,0,16,16,16){
}
PortalItem::~PortalItem(){
}

void PortalItem::applyEffect()
{
	sceneManager.getCurrentScene().leave();
};

void PortalItem::update (sf::Time deltaTime) {
	if (mySprite != 0)
	{
		int index = (1+std::sin(deltaTime.asMilliseconds()/400))/2;
		mySprite->setTextureRect(sf::IntRect(0,16*index,16,32));
		window.draw(*mySprite);
	}
};
<commit_msg>correct portal position<commit_after>#include "globals.hpp"
#include "PortalItem.hpp"
#include <cmath>
PortalItem::PortalItem(sf::Sprite* sprite):Item(sprite,0,0,16,32){
}
PortalItem::~PortalItem(){
}

void PortalItem::applyEffect()
{
	sceneManager.getCurrentScene().leave();
};

void PortalItem::update (sf::Time deltaTime) {
	if (mySprite != 0)
	{
		int index = (1+std::sin(deltaTime.asMilliseconds()/400))/2;
		mySprite->setTextureRect(sf::IntRect(0,16*index,16,32));
		window.draw(*mySprite);
	}
};
<|endoftext|>


<commit_before>/*
  HarwareSerial.cpp - Hardware serial library for Wiring
  Copyright (c) 2006 Nicholas Zambetti.  All right reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

extern "C" {
  #include <stdio.h>
  #include <string.h>
  #include <inttypes.h>
  #include "Serial.h"
}

#include "HardwareSerial.h"

// Constructors ////////////////////////////////////////////////////////////////

HardwareSerial::HardwareSerial(uint8_t uart)
{
  if(uart == 0){
    _uart = 0;
  }else{
    _uart = 1;
  }
}

// Public Methods //////////////////////////////////////////////////////////////

void HardwareSerial::begin(long speed)
{
  uart_init(_uart, speed);
}

uint8_t HardwareSerial::available(void)
{
  return uart_available(_uart);
}

int HardwareSerial::read(void)
{
  return uart_read(_uart);
}

void HardwareSerial::print(char c)
{
  uart_write(_uart, &c, 1);
}

void HardwareSerial::print(char c[])
{
  uart_write(_uart, c, strlen(c));
}

void HardwareSerial::print(uint8_t b)
{
  char c = b;
  uart_write(_uart, &c, 1);
}

void HardwareSerial::print(int n)
{
  print((long) n);
}

void HardwareSerial::print(long n)
{
  if (n < 0) {
    print('-');
    n = -n;
  }
  printNumber(n, 10);
}

void HardwareSerial::print(unsigned long n)
{
  printNumber(n, 10);
}

void HardwareSerial::print(long n, int base)
{
  if (base == 0)
    print((char) n);
  else if (base == 10)
    print(n);
  else
    printNumber(n, base);
}

void HardwareSerial::println(void)
{
  print('\n');
}

void HardwareSerial::println(char c)
{
  print(c);
  println();
}

void HardwareSerial::println(char c[])
{
  uart_write(_uart, c, strlen(c));
  println();
}

void HardwareSerial::println(uint8_t b)
{
  print(b);
  println();
}

void HardwareSerial::println(int n)
{
  println((long) n);
}

void HardwareSerial::println(long n)
{
  print(n);
  println();
}

void HardwareSerial::println(unsigned long n)
{
  print(n);
  println();
}

void HardwareSerial::println(long n, int base)
{
  print(n, base);
  println();
}

// Private Methods /////////////////////////////////////////////////////////////

void HardwareSerial::printNumber(unsigned long n, uint8_t base)
{
  uint8_t buf[8 * sizeof(long)]; // Assumes 8-bit chars.
  int i = 0;
  if (n == 0) {
    print('0');
    return;
  }
  while (n > 0) {
    buf[i++] = n % base;
    n /= base;
  }
  for (i--; i >= 0; i--){
    print((char)(buf[i] < 10 ? '0' + buf[i] : 'A' + buf[i] - 10));
  }
}

// Preinstantiate Objects //////////////////////////////////////////////////////

HardwareSerial Serial = HardwareSerial(0);
//HardwareSerial Serial1 = HardwareSerial(1);

<commit_msg>Serial.println() now sends '\r', '\n' (instead of just '\n')<commit_after>/*
  HarwareSerial.cpp - Hardware serial library for Wiring
  Copyright (c) 2006 Nicholas Zambetti.  All right reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

extern "C" {
  #include <stdio.h>
  #include <string.h>
  #include <inttypes.h>
  #include "Serial.h"
}

#include "HardwareSerial.h"

// Constructors ////////////////////////////////////////////////////////////////

HardwareSerial::HardwareSerial(uint8_t uart)
{
  if(uart == 0){
    _uart = 0;
  }else{
    _uart = 1;
  }
}

// Public Methods //////////////////////////////////////////////////////////////

void HardwareSerial::begin(long speed)
{
  uart_init(_uart, speed);
}

uint8_t HardwareSerial::available(void)
{
  return uart_available(_uart);
}

int HardwareSerial::read(void)
{
  return uart_read(_uart);
}

void HardwareSerial::print(char c)
{
  uart_write(_uart, &c, 1);
}

void HardwareSerial::print(char c[])
{
  uart_write(_uart, c, strlen(c));
}

void HardwareSerial::print(uint8_t b)
{
  char c = b;
  uart_write(_uart, &c, 1);
}

void HardwareSerial::print(int n)
{
  print((long) n);
}

void HardwareSerial::print(long n)
{
  if (n < 0) {
    print('-');
    n = -n;
  }
  printNumber(n, 10);
}

void HardwareSerial::print(unsigned long n)
{
  printNumber(n, 10);
}

void HardwareSerial::print(long n, int base)
{
  if (base == 0)
    print((char) n);
  else if (base == 10)
    print(n);
  else
    printNumber(n, base);
}

void HardwareSerial::println(void)
{
  print('\r');
  print('\n');
}

void HardwareSerial::println(char c)
{
  print(c);
  println();
}

void HardwareSerial::println(char c[])
{
  uart_write(_uart, c, strlen(c));
  println();
}

void HardwareSerial::println(uint8_t b)
{
  print(b);
  println();
}

void HardwareSerial::println(int n)
{
  println((long) n);
}

void HardwareSerial::println(long n)
{
  print(n);
  println();
}

void HardwareSerial::println(unsigned long n)
{
  print(n);
  println();
}

void HardwareSerial::println(long n, int base)
{
  print(n, base);
  println();
}

// Private Methods /////////////////////////////////////////////////////////////

void HardwareSerial::printNumber(unsigned long n, uint8_t base)
{
  uint8_t buf[8 * sizeof(long)]; // Assumes 8-bit chars.
  int i = 0;
  if (n == 0) {
    print('0');
    return;
  }
  while (n > 0) {
    buf[i++] = n % base;
    n /= base;
  }
  for (i--; i >= 0; i--){
    print((char)(buf[i] < 10 ? '0' + buf[i] : 'A' + buf[i] - 10));
  }
}

// Preinstantiate Objects //////////////////////////////////////////////////////

HardwareSerial Serial = HardwareSerial(0);
//HardwareSerial Serial1 = HardwareSerial(1);

<|endoftext|>