mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-04-07 01:42:04 +00:00
[qfcc] Implement glsl's contructors for math types
I don't think this includes bools yet, and matrices aren't supported yet, but float vectors work quite nicely.
This commit is contained in:
parent
d0064c6c46
commit
ee6e38e2f9
5 changed files with 153 additions and 10 deletions
|
@ -658,6 +658,9 @@ float expr_float (const expr_t *e) __attribute__((pure));
|
|||
const expr_t *new_vector_expr (const float *vector_val);
|
||||
const float *expr_vector (const expr_t *e) __attribute__((pure));
|
||||
const expr_t *new_vector_list (const expr_t *e);
|
||||
const expr_t *new_vector_value (const type_t *ele_type, int width,
|
||||
int count, const expr_t **elements,
|
||||
bool implicit);
|
||||
|
||||
/** Create a new entity constant expression node.
|
||||
|
||||
|
@ -895,6 +898,7 @@ void vararg_integer (const expr_t *e);
|
|||
const expr_t *build_function_call (const expr_t *fexpr, const type_t *ftype,
|
||||
const expr_t *params);
|
||||
const expr_t *function_expr (const expr_t *e1, const expr_t *e2);
|
||||
const expr_t *constructor_expr (const expr_t *e, const expr_t *params);
|
||||
struct function_s;
|
||||
const expr_t *branch_expr (int op, const expr_t *test, const expr_t *label);
|
||||
const expr_t *goto_expr (const expr_t *label);
|
||||
|
|
|
@ -32,6 +32,7 @@ qfcc_SOURCES = \
|
|||
tools/qfcc/source/expr_bool.c \
|
||||
tools/qfcc/source/expr_cast.c \
|
||||
tools/qfcc/source/expr_compound.c \
|
||||
tools/qfcc/source/expr_construct.c \
|
||||
tools/qfcc/source/expr_dag.c \
|
||||
tools/qfcc/source/expr_obj.c \
|
||||
tools/qfcc/source/expr_optimize.c \
|
||||
|
|
|
@ -2341,6 +2341,10 @@ function_expr (const expr_t *fexpr, const expr_t *params)
|
|||
}
|
||||
}
|
||||
|
||||
if (fexpr->type == ex_symbol && fexpr->symbol->sy_type == sy_type) {
|
||||
return constructor_expr (fexpr, params);
|
||||
}
|
||||
|
||||
fexpr = find_function (fexpr, params);
|
||||
fexpr = convert_name (fexpr);
|
||||
if (is_error (fexpr)) {
|
||||
|
|
125
tools/qfcc/source/expr_construct.c
Normal file
125
tools/qfcc/source/expr_construct.c
Normal file
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
expr_construct.c
|
||||
|
||||
type constructor expressions
|
||||
|
||||
Copyright (C) 2024 Bill Currie <bill@taniwha.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
#include "tools/qfcc/include/algebra.h"
|
||||
#include "tools/qfcc/include/diagnostic.h"
|
||||
#include "tools/qfcc/include/expr.h"
|
||||
#include "tools/qfcc/include/rua-lang.h"
|
||||
#include "tools/qfcc/include/symtab.h"
|
||||
#include "tools/qfcc/include/type.h"
|
||||
#include "tools/qfcc/include/value.h"
|
||||
|
||||
static const expr_t *
|
||||
get_value (const expr_t *e, int i, int j)
|
||||
{
|
||||
auto t = get_type (e);
|
||||
|
||||
if (i < 0 || i >= type_cols (t) || j < 0 || j >= type_rows (t)) {
|
||||
internal_error (e, "invalid index");
|
||||
}
|
||||
if (type_cols (t) > 1) {
|
||||
auto ind = new_int_expr (i, false);
|
||||
e = array_expr (e, ind);
|
||||
}
|
||||
if (type_rows (t) > 1) {
|
||||
auto ind = new_int_expr (j, false);
|
||||
e = array_expr (e, ind);
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
static const expr_t *
|
||||
math_constructor (const type_t *type, const expr_t *params, const expr_t *e)
|
||||
{
|
||||
auto base = base_type (type);
|
||||
int num_comp = type->width;
|
||||
const expr_t *components[num_comp] = {};
|
||||
|
||||
int num_param = list_count (¶ms->list);
|
||||
const expr_t *param_exprs[num_param + 1] = {};
|
||||
list_scatter_rev (¶ms->list, param_exprs);
|
||||
bool all_constant = true;
|
||||
bool all_implicit = true;
|
||||
|
||||
int p = 0;
|
||||
for (int c = 0; c < num_comp; ) {
|
||||
if (p < num_param) {
|
||||
auto pexpr = param_exprs[p++];
|
||||
auto ptype = get_type (pexpr);
|
||||
if (!is_math (ptype)) {
|
||||
components[c++] = error (pexpr, "invalid type for conversion");
|
||||
continue;
|
||||
}
|
||||
for (int i = 0; i < type_cols (ptype) && c < num_comp; i++) {
|
||||
for (int j = 0; j < type_rows (ptype) && c < num_comp; j++) {
|
||||
auto val = get_value (pexpr, i, j);
|
||||
all_implicit = all_implicit && val->implicit;
|
||||
all_constant = all_constant && is_constant (val);
|
||||
components[c++] = cast_expr (base, val);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
components[c++] = new_nil_expr ();
|
||||
}
|
||||
}
|
||||
if (p < num_param) {
|
||||
return error (e, "too may parameters for %s", type->name);
|
||||
}
|
||||
if (num_comp == 1) {
|
||||
return components[0];
|
||||
}
|
||||
if (all_constant) {
|
||||
return new_vector_value (base, num_comp, num_comp, components,
|
||||
all_implicit);
|
||||
}
|
||||
|
||||
auto vec = new_expr ();
|
||||
vec->type = ex_vector;
|
||||
vec->vector.type = vector_type (base, num_comp);
|
||||
list_gather (&vec->vector.list, components, num_comp);
|
||||
return vec;
|
||||
}
|
||||
|
||||
const expr_t *
|
||||
constructor_expr (const expr_t *e, const expr_t *params)
|
||||
{
|
||||
auto type = e->symbol->type;
|
||||
if (is_algebra (type)) {
|
||||
return error (e, "algebra not implemented");
|
||||
}
|
||||
if (is_matrix (type)) {
|
||||
return error (e, "matrix not implemented");
|
||||
}
|
||||
if (is_math (type)) {
|
||||
return math_constructor (type, params, e);
|
||||
}
|
||||
return error (e, "not implemented");
|
||||
}
|
|
@ -36,6 +36,23 @@
|
|||
#include "tools/qfcc/include/type.h"
|
||||
#include "tools/qfcc/include/value.h"
|
||||
|
||||
const expr_t *
|
||||
new_vector_value (const type_t *ele_type, int width, int count,
|
||||
const expr_t **elements, bool implicit)
|
||||
{
|
||||
const type_t *vec_type = vector_type (ele_type, width);
|
||||
pr_type_t value[type_size (vec_type)];
|
||||
|
||||
for (int i = 0, offs = 0; i < count; i++) {
|
||||
auto src_type = get_type (elements[i]);
|
||||
value_store (value + offs, src_type, elements[i]);
|
||||
offs += type_size (src_type);
|
||||
}
|
||||
|
||||
return new_value_expr (new_type_value (vec_type, value), implicit);
|
||||
}
|
||||
|
||||
|
||||
const expr_t *
|
||||
new_vector_list (const expr_t *expr_list)
|
||||
{
|
||||
|
@ -118,16 +135,8 @@ new_vector_list (const expr_t *expr_list)
|
|||
}
|
||||
|
||||
if (all_constant) {
|
||||
const type_t *vec_type = vector_type (ele_type, width);
|
||||
pr_type_t value[type_size (vec_type)];
|
||||
|
||||
for (int i = 0, offs = 0; i < count; i++) {
|
||||
auto src_type = get_type (elements[i]);
|
||||
value_store (value + offs, src_type, elements[i]);
|
||||
offs += type_size (src_type);
|
||||
}
|
||||
|
||||
return new_value_expr (new_type_value (vec_type, value), all_implicit);
|
||||
return new_vector_value (ele_type, width, count, elements,
|
||||
all_implicit);
|
||||
}
|
||||
|
||||
expr_t *vec = new_expr ();
|
||||
|
|
Loading…
Reference in a new issue