%{ /* * lang.y - Toolpath adaptation language * * Written 2010 by Werner Almesberger * Copyright 2010 by Werner Almesberger * * 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. */ #include #include "path.h" #include "ops.h" #include "gnuplot.h" #include "gerber.h" #include "y.tab.h" static double xo = 0, yo = 0, zo = 0; static struct path *paths = NULL; static void add_paths(struct path *new) { struct path **anchor = &paths; while (*anchor) anchor = &(*anchor)->next; *anchor = new; } static void translate(double x, double y, double z) { struct path *path; struct point *p; for (path = paths; path; path = path->next) for (p = path->first; p; p = p->next) { p->x += x; p->y += y; p->z += z; } } static double ref_pick_1(int ref, double a, double b) { switch (ref) { case 0: return a; case 1: return (a+b)/2; case 2: return b; default: abort(); } } static void ref_pick_xy(int ref, double xa, double ya, double xb, double yb, double *x, double *y) { *x = ref_pick_1((ref-1) % 3, xa, xb); *y = ref_pick_1((ref-1)/3, ya, yb); } static void align(int ref, double x, double y) { const struct path *path; const struct point *p; double xa = 0, ya = 0, xb = 0, yb = 0; double xr, yr, xd, yd; int first = 1; for (path = paths; path; path = path->next) for (p = path->first; p; p = p->next) { if (first || p->x < xa) xa = p->x; if (first || p->x > xb) xb = p->x; if (first || p->y < ya) ya = p->y; if (first || p->y > yb) yb = p->y; first = 0; } ref_pick_xy(ref, xa, ya, xb, yb, &xr, &yr); xd = x-xr; yd = y-yr; translate(xd, yd, 0); xo += xd; yo += yd; } %} %union { double num; char *str; }; %token TOK_ALIGN TOK_ARRAY TOK_CLEAR TOK_RESET TOK_TOOL %token TOK_TRANSLATE TOK_Z %token TOK_GERBER TOK_GNUPLOT TOK_WRITE %token TOK_DOG %token NUMBER %token STRING %type opt_filename %% all: | command all ; command: TOK_ALIGN NUMBER NUMBER NUMBER { align((int) $2, $3, $4); } | TOK_ALIGN NUMBER NUMBER NUMBER NUMBER NUMBER { int ref = $2; double x, y; ref_pick_xy(ref, $3, $4, $5, $6, &x, &y); align(ref, x, y); } | TOK_ARRAY NUMBER NUMBER NUMBER NUMBER { double x = $2*$4; double y = $3*$5; translate(x, y, 0); } | TOK_CLEAR { struct path *next; while (paths) { next = paths->next; path_free(paths); paths = next; } } | TOK_RESET { xo = yo = 0; } | TOK_TOOL { tool_comp_paths(paths, 0); } | TOK_TOOL TOK_DOG { tool_comp_paths(paths, 1); } | TOK_TRANSLATE NUMBER NUMBER { translate($2, $3, 0); xo += $2; yo += $3; } | TOK_Z NUMBER { zo -= $2; } | TOK_Z NUMBER NUMBER { zo -= $2+$3; } | TOK_GERBER NUMBER opt_filename { add_paths(gerber_read($3, $2/2)); translate(xo, yo, 0); } | TOK_GNUPLOT NUMBER opt_filename { add_paths(gnuplot_read($3, $2/2)); translate(xo, yo, 0); } | TOK_WRITE opt_filename { translate(0, 0, zo); gnuplot_write($2, paths); translate(0, 0, -zo); } ; opt_filename: { $$ = NULL; } | STRING { $$ = $1; } ;