1/** 2 * \file 3 * \brief This file contains functions to generate Eclipse CLP terms based on 4 * the AST of a given record. 5 */ 6 7/* 8 * Copyright (c) 2011, ETH Zurich. 9 * All rights reserved. 10 * 11 * This file is distributed under the terms in the attached LICENSE file. 12 * If you do not find this file, copies can be found by writing to: 13 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group. 14 */ 15 16#include <stdlib.h> 17#include <stdio.h> 18#include <string.h> 19#include <assert.h> 20#include <stdarg.h> 21 22#include <barrelfish/barrelfish.h> 23 24#include "code_generator.h" 25 26// forward decl 27static inline struct pword_pair create_constraint(struct ast_object*); 28 29struct pword_pair { 30 bool is_attribute; 31 pword value; 32 pword op; 33}; 34 35static inline struct pword_pair visit_attribute_right(struct ast_object* p) 36{ 37 struct pword_pair terms; 38 terms.is_attribute = true; 39 40 switch (p->type) { 41 case nodeType_Ident: 42 terms.value = ec_atom(ec_did(p->u.in.str, 0)); 43 break; 44 45 case nodeType_String: 46 assert(p->u.sn.str != NULL); 47 terms.value = ec_string(p->u.sn.str); 48 break; 49 50 case nodeType_Float: 51 terms.value = ec_double(p->u.fn.value); 52 break; 53 54 case nodeType_Constant: 55 terms.value = ec_long(p->u.cn.value); 56 break; 57 58 case nodeType_Variable: 59 terms.value = ec_newvar(); 60 break; 61 62 case nodeType_Constraint: 63 terms = create_constraint(p); 64 break; 65 66 default: 67 assert(!"Should not happen, check your parser!"); 68 break; 69 70 } 71 72 return terms; 73} 74 75static inline struct pword_pair create_constraint(struct ast_object* p) 76{ 77 assert(p != NULL); 78 assert(p->type == nodeType_Constraint); 79 80 struct pword_pair terms = visit_attribute_right(p->u.cnsn.value); 81 terms.is_attribute = false; 82 83 switch (p->u.cnsn.op) { 84 case constraint_GT: 85 terms.op = ec_atom(ec_did(">", 2)); 86 break; 87 88 case constraint_GE: 89 terms.op = ec_atom(ec_did(">=", 2)); 90 break; 91 92 case constraint_LT: 93 terms.op = ec_atom(ec_did("<", 2)); 94 break; 95 96 case constraint_LE: 97 terms.op = ec_atom(ec_did("<=", 2)); 98 break; 99 100 case constraint_EQ: 101 terms.op = ec_atom(ec_did("==", 2)); 102 break; 103 104 case constraint_NE: 105 terms.op = ec_atom(ec_did("!=", 2)); 106 break; 107 108 case constraint_REGEX: 109 terms.op = ec_atom(ec_did("match", 0)); 110 break; 111 112 default: 113 assert(!"OP code not supported"); 114 break; 115 } 116 117 return terms; 118} 119 120static void translate(struct ast_object* p, struct skb_ec_terms* ss) 121{ 122 assert(p != NULL); 123 assert(p->type == nodeType_Object); 124 125 ss->attribute_list = ec_nil(); 126 ss->constraint_list = ec_nil(); 127 128 struct ast_object* name = p->u.on.name; 129 130 if (name->type == nodeType_Ident) { 131 dident name_id = ec_did(name->u.in.str, 0); 132 ss->name = ec_atom(name_id); 133 } else if (name->type == nodeType_Variable) { 134 ss->name = ec_newvar(); 135 } else if (name->type == nodeType_Constraint) { 136 assert(name->u.cnsn.op == constraint_REGEX); 137 // Construct match term for name regex 138 dident constraint = ec_did("name_constraint", 1); 139 pword regex = ec_string(name->u.cnsn.value->u.sn.str); 140 pword constraint_term = ec_term(constraint, regex); 141 ss->name = constraint_term; 142 } 143 else { 144 assert(!"Scan types not allowed here"); 145 } 146 147 148 struct ast_object* iter = p->u.on.attrs; 149 for (; iter != NULL; iter = iter->u.an.next) { 150 assert(iter->type == nodeType_Attribute); 151 struct ast_object* left = iter->u.an.attr->u.pn.left; 152 struct ast_object* right = iter->u.an.attr->u.pn.right; 153 154 dident attr_id = ec_did(left->u.in.str, 0); 155 pword left_term = ec_atom(attr_id); 156 157 struct pword_pair right_terms = visit_attribute_right(right); 158 159 if (right_terms.is_attribute) { 160 pword entry = ec_term(ec_did("val", 2), left_term, 161 right_terms.value); 162 ss->attribute_list = ec_list(entry, ss->attribute_list); 163 } else { // is constraint 164 dident constraint = ec_did("constraint", 3); 165 pword entry = ec_term(constraint, left_term, right_terms.op, 166 right_terms.value); 167 ss->constraint_list = ec_list(entry, ss->constraint_list); 168 } 169 } 170 171} 172 173errval_t transform_record(struct ast_object* ast, struct skb_ec_terms* record) 174{ 175 assert(ast != NULL); 176 translate(ast, record); 177 178 return SYS_ERR_OK; 179} 180 181