Пример #1
0
void CpDo( void )
{
// Compile a DO statement.

    signed_32   term;

    AddCSNode( CS_DO );
    term = DoLabel();
    if( term == 0 ) {
        Extension( DO_DO_EXT );
    }
    InitDo( term );
    ColonLabel();
}
Пример #2
0
void CpDoWhile( void )
{
// Compile a DO WHILE statement.

    Extension( DO_DO_EXT );
    InitLoop( CS_DO_WHILE );
    CSHead->cs_info.do_term = DoLabel();
    if( RecKeyWord( "WHILE" ) ) {
        RemKeyword( CITNode, 5 );
        CSCond( CSHead->bottom );
        BlockLabel();
    } else {
        if( ReqNOpn() ) {
            BlockLabel();
        }
    }
}
Пример #3
0
std::ostream &
	TKTry::
	Release(std::ostream & s) const
{
	DoLabel(s);
	// try must have braces
	switch (GetChildCount())
	{
		case 2:
		{
			// try-finally
			s << "try";
			Token &
				what = GetFirstChild();
			// Add braces
			if (what.GetType() == TokenType::TO_BRACE_O)
			{
				what.Release(s);
			}
			else
			{
				s << '{';
				what.Release(s);
				s << '}';
			}
			s << "finally";
			Token &
				final = GetChild(1);
			// Add braces
			if (final.GetType() == TokenType::TO_BRACE_O)
			{
				final.Release(s);
			}
			else
			{
				s << '{';
				final.Release(s);
				s << '}';
			}
Пример #4
0
int Statement (int* PendingToken)
/* Statement parser. Returns 1 if the statement does a return/break, returns
** 0 otherwise. If the PendingToken pointer is not NULL, the function will
** not skip the terminating token of the statement (closing brace or
** semicolon), but store true if there is a pending token, and false if there
** is none. The token is always checked, so there is no need for the caller to
** check this token, it must be skipped, however. If the argument pointer is
** NULL, the function will skip the token.
*/
{
    ExprDesc Expr;
    int GotBreak;
    CodeMark Start, End;

    /* Assume no pending token */
    if (PendingToken) {
        *PendingToken = 0;
    }

    /* Check for a label. A label is always part of a statement, it does not
    ** replace one.
    */
    while (CurTok.Tok == TOK_IDENT && NextTok.Tok == TOK_COLON) {
        /* Handle the label */
        DoLabel ();
        if (CheckLabelWithoutStatement ()) {
            return 0;
        }
    }

    switch (CurTok.Tok) {

        case TOK_LCURLY:
            NextToken ();
            GotBreak = CompoundStatement ();
            CheckTok (TOK_RCURLY, "`{' expected", PendingToken);
            return GotBreak;

        case TOK_IF:
            return IfStatement ();

        case TOK_WHILE:
            WhileStatement ();
            break;

        case TOK_DO:
            DoStatement ();
            break;

        case TOK_SWITCH:
            SwitchStatement ();
            break;

        case TOK_RETURN:
            ReturnStatement ();
            CheckSemi (PendingToken);
            return 1;

        case TOK_BREAK:
            BreakStatement ();
            CheckSemi (PendingToken);
            return 1;

        case TOK_CONTINUE:
            ContinueStatement ();
            CheckSemi (PendingToken);
            return 1;

        case TOK_FOR:
            ForStatement ();
            break;

        case TOK_GOTO:
            GotoStatement ();
            CheckSemi (PendingToken);
            return 1;

        case TOK_SEMI:
            /* Ignore it */
            CheckSemi (PendingToken);
            break;

        case TOK_PRAGMA:
            DoPragma ();
            break;

        case TOK_CASE:
            CaseLabel ();
            CheckLabelWithoutStatement ();
            break;

        case TOK_DEFAULT:
            DefaultLabel ();
            CheckLabelWithoutStatement ();
            break;

        default:
            /* Remember the current code position */
            GetCodePos (&Start);
            /* Actual statement */
            ExprWithCheck (hie0, &Expr);
            /* Load the result only if it is an lvalue and the type is
            ** marked as volatile. Otherwise the load is useless.
            */
            if (ED_IsLVal (&Expr) && IsQualVolatile (Expr.Type)) {
                LoadExpr (CF_NONE, &Expr);
            }
            /* If the statement didn't generate code, and is not of type
            ** void, emit a warning.
            */
            GetCodePos (&End);
            if (CodeRangeIsEmpty (&Start, &End) &&
                !IsTypeVoid (Expr.Type)         &&
                IS_Get (&WarnNoEffect)) {
                Warning ("Statement has no effect");
            }
            CheckSemi (PendingToken);
    }
    return 0;
}
Пример #5
0
void Constraint::DrawOrGetDistance(Vector *labelPos) {
    if(!SS.GW.showConstraints) return;
    Group *g = SK.GetGroup(group);
    // If the group is hidden, then the constraints are hidden and not
    // able to be selected.
    if(!(g->visible)) return;
    // And likewise if the group is not the active group; except for comments
    // with an assigned style.
    if(g->h.v != SS.GW.activeGroup.v && !(type == COMMENT && disp.style.v)) {
        return;
    }
    if(disp.style.v) {
        Style *s = Style::Get(disp.style);
        if(!s->visible) return;
    }

    // Unit vectors that describe our current view of the scene. One pixel
    // long, not one actual unit.
    Vector gr = SS.GW.projRight.ScaledBy(1/SS.GW.scale);
    Vector gu = SS.GW.projUp.ScaledBy(1/SS.GW.scale);
    Vector gn = (gr.Cross(gu)).WithMagnitude(1/SS.GW.scale);

    switch(type) {
        case PT_PT_DISTANCE: {
            Vector ap = SK.GetEntity(ptA)->PointGetNum();
            Vector bp = SK.GetEntity(ptB)->PointGetNum();

            if(workplane.v != Entity::FREE_IN_3D.v) {
                DoProjectedPoint(&ap);
                DoProjectedPoint(&bp);
            }

            Vector ref = ((ap.Plus(bp)).ScaledBy(0.5)).Plus(disp.offset);

            DoLineWithArrows(ref, ap, bp, false);
            DoLabel(ref, labelPos, gr, gu);
            break;
        }

        case PROJ_PT_DISTANCE: {
            Vector ap = SK.GetEntity(ptA)->PointGetNum(),
                   bp = SK.GetEntity(ptB)->PointGetNum(),
                   dp = (bp.Minus(ap)),
                   pp = SK.GetEntity(entityA)->VectorGetNum();

            Vector ref = ((ap.Plus(bp)).ScaledBy(0.5)).Plus(disp.offset);

            pp = pp.WithMagnitude(1);
            double d = dp.Dot(pp);
            Vector bpp = ap.Plus(pp.ScaledBy(d));
            StippledLine(ap, bpp);
            StippledLine(bp, bpp);

            DoLineWithArrows(ref, ap, bpp, false);
            DoLabel(ref, labelPos, gr, gu);
            break;
        }

        case PT_FACE_DISTANCE:
        case PT_PLANE_DISTANCE: {
            Vector pt = SK.GetEntity(ptA)->PointGetNum();
            Entity *enta = SK.GetEntity(entityA);
            Vector n, p;
            if(type == PT_PLANE_DISTANCE) {
                n = enta->Normal()->NormalN();
                p = enta->WorkplaneGetOffset();
            } else {
                n = enta->FaceGetNormalNum();
                p = enta->FaceGetPointNum();
            }

            double d = (p.Minus(pt)).Dot(n);
            Vector closest = pt.Plus(n.WithMagnitude(d));

            Vector ref = ((closest.Plus(pt)).ScaledBy(0.5)).Plus(disp.offset);

            if(!pt.Equals(closest)) {
                DoLineWithArrows(ref, pt, closest, true);
            }

            DoLabel(ref, labelPos, gr, gu);
            break;
        }

        case PT_LINE_DISTANCE: {
            Vector pt = SK.GetEntity(ptA)->PointGetNum();
            Entity *line = SK.GetEntity(entityA);
            Vector lA = SK.GetEntity(line->point[0])->PointGetNum();
            Vector lB = SK.GetEntity(line->point[1])->PointGetNum();
            Vector dl = lB.Minus(lA);

            if(workplane.v != Entity::FREE_IN_3D.v) {
                lA = lA.ProjectInto(workplane);
                lB = lB.ProjectInto(workplane);
                DoProjectedPoint(&pt);
            }

            // Find the closest point on the line
            Vector closest = pt.ClosestPointOnLine(lA, dl);

            Vector ref = ((closest.Plus(pt)).ScaledBy(0.5)).Plus(disp.offset);
            DoLabel(ref, labelPos, gr, gu);

            if(!pt.Equals(closest)) {
                DoLineWithArrows(ref, pt, closest, true);
            }

            if(workplane.v != Entity::FREE_IN_3D.v) {
                // Draw the projection marker from the closest point on the
                // projected line to the projected point on the real line.
                Vector lAB = (lA.Minus(lB));
                double t = (lA.Minus(closest)).DivPivoting(lAB);

                Vector lA = SK.GetEntity(line->point[0])->PointGetNum();
                Vector lB = SK.GetEntity(line->point[1])->PointGetNum();

                Vector c2 = (lA.ScaledBy(1-t)).Plus(lB.ScaledBy(t));
                DoProjectedPoint(&c2);
            }
            break;
        }

        case DIAMETER: {
            Entity *circle = SK.GetEntity(entityA);
            Vector center = SK.GetEntity(circle->point[0])->PointGetNum();
            Quaternion q = SK.GetEntity(circle->normal)->NormalGetNum();
            Vector n = q.RotationN().WithMagnitude(1);
            double r = circle->CircleGetRadiusNum();

            Vector ref = center.Plus(disp.offset);
            // Force the label into the same plane as the circle.
            ref = ref.Minus(n.ScaledBy(n.Dot(ref) - n.Dot(center)));

            Vector mark = ref.Minus(center);
            mark = mark.WithMagnitude(mark.Magnitude()-r);
            DoLineTrimmedAgainstBox(ref, ref, ref.Minus(mark));

            Vector topLeft;
            DoLabel(ref, &topLeft, gr, gu);
            if(labelPos) *labelPos = topLeft;

            // Show this as diameter or radius?
            if(!other) {
                // Draw the diameter symbol
                Vector dc = topLeft;
                dc = dc.Plus(gu.WithMagnitude(5/SS.GW.scale));
                dc = dc.Plus(gr.WithMagnitude(9/SS.GW.scale));
                double dr = 5/SS.GW.scale;
                double theta, dtheta = (2*PI)/12;
                for(theta = 0; theta < 2*PI-0.01; theta += dtheta) {
                    LineDrawOrGetDistance(
                        dc.Plus(gu.WithMagnitude(cos(theta)*dr)).Plus(
                                gr.WithMagnitude(sin(theta)*dr)),
                        dc.Plus(gu.WithMagnitude(cos(theta+dtheta)*dr)).Plus(
                                gr.WithMagnitude(sin(theta+dtheta)*dr)));
                }
                theta = 25*(PI/180);
                dr *= 1.7;
                dtheta = PI;
                LineDrawOrGetDistance(
                    dc.Plus(gu.WithMagnitude(cos(theta)*dr)).Plus(
                            gr.WithMagnitude(sin(theta)*dr)),
                    dc.Plus(gu.WithMagnitude(cos(theta+dtheta)*dr)).Plus(
                            gr.WithMagnitude(sin(theta+dtheta)*dr)));
            }
            break;
        }

        case POINTS_COINCIDENT: {
            if(!dogd.drawing) {
                for(int i = 0; i < 2; i++) {
                    Vector p = SK.GetEntity(i == 0 ? ptA : ptB)-> PointGetNum();
                    Point2d pp = SS.GW.ProjectPoint(p);
                    // The point is selected within a radius of 7, from the
                    // same center; so if the point is visible, then this
                    // constraint cannot be selected. But that's okay.
                    dogd.dmin = min(dogd.dmin, pp.DistanceTo(dogd.mp) - 3);
                    dogd.refp = p;
                }
                break;
            }

            if(dogd.drawing) {
                // Let's adjust the color of this constraint to have the same
                // rough luma as the point color, so that the constraint does not
                // stand out in an ugly way.
                RgbaColor cd = Style::Color(Style::DATUM),
                         cc = Style::Color(Style::CONSTRAINT);
                // convert from 8-bit color to a vector
                Vector vd = Vector::From(cd.redF(), cd.greenF(), cd.blueF()),
                       vc = Vector::From(cc.redF(), cc.greenF(), cc.blueF());
                // and scale the constraint color to have the same magnitude as
                // the datum color, maybe a bit dimmer
                vc = vc.WithMagnitude(vd.Magnitude()*0.9);
                // and set the color to that.
                ssglColorRGB(RGBf(vc.x, vc.y, vc.z));

                for(int a = 0; a < 2; a++) {
                    Vector r = SS.GW.projRight.ScaledBy((a+1)/SS.GW.scale);
                    Vector d = SS.GW.projUp.ScaledBy((2-a)/SS.GW.scale);
                    for(int i = 0; i < 2; i++) {
                        Vector p = SK.GetEntity(i == 0 ? ptA : ptB)-> PointGetNum();
                        glBegin(GL_QUADS);
                            ssglVertex3v(p.Plus (r).Plus (d));
                            ssglVertex3v(p.Plus (r).Minus(d));
                            ssglVertex3v(p.Minus(r).Minus(d));
                            ssglVertex3v(p.Minus(r).Plus (d));
                        glEnd();
                    }

                }
            }
            break;
        }

        case PT_ON_CIRCLE:
        case PT_ON_LINE:
        case PT_ON_FACE:
        case PT_IN_PLANE: {
            double s = 8/SS.GW.scale;
            Vector p = SK.GetEntity(ptA)->PointGetNum();
            Vector r, d;
            if(type == PT_ON_FACE) {
                Vector n = SK.GetEntity(entityA)->FaceGetNormalNum();
                r = n.Normal(0);
                d = n.Normal(1);
            } else if(type == PT_IN_PLANE) {
                EntityBase *n = SK.GetEntity(entityA)->Normal();
                r = n->NormalU();
                d = n->NormalV();
            } else {
                r = gr;
                d = gu;
                s *= (6.0/8); // draw these a little smaller
            }
            r = r.WithMagnitude(s); d = d.WithMagnitude(s);
            LineDrawOrGetDistance(p.Plus (r).Plus (d), p.Plus (r).Minus(d));
            LineDrawOrGetDistance(p.Plus (r).Minus(d), p.Minus(r).Minus(d));
            LineDrawOrGetDistance(p.Minus(r).Minus(d), p.Minus(r).Plus (d));
            LineDrawOrGetDistance(p.Minus(r).Plus (d), p.Plus (r).Plus (d));
            break;
        }

        case WHERE_DRAGGED: {
            Vector p = SK.GetEntity(ptA)->PointGetNum(),
                   u = p.Plus(gu.WithMagnitude(8/SS.GW.scale)).Plus(
                              gr.WithMagnitude(8/SS.GW.scale)),
                   uu = u.Minus(gu.WithMagnitude(5/SS.GW.scale)),
                   ur = u.Minus(gr.WithMagnitude(5/SS.GW.scale));
            // Draw four little crop marks, uniformly spaced (by ninety
            // degree rotations) around the point.
            int i;
            for(i = 0; i < 4; i++) {
                LineDrawOrGetDistance(u, uu);
                LineDrawOrGetDistance(u, ur);
                u = u.RotatedAbout(p, gn, PI/2);
                ur = ur.RotatedAbout(p, gn, PI/2);
                uu = uu.RotatedAbout(p, gn, PI/2);
            }
            break;
        }

        case SAME_ORIENTATION: {
            for(int i = 0; i < 2; i++) {
                Entity *e = SK.GetEntity(i == 0 ? entityA : entityB);
                Quaternion q = e->NormalGetNum();
                Vector n = q.RotationN().WithMagnitude(25/SS.GW.scale);
                Vector u = q.RotationU().WithMagnitude(6/SS.GW.scale);
                Vector p = SK.GetEntity(e->point[0])->PointGetNum();
                p = p.Plus(n.WithMagnitude(10/SS.GW.scale));

                LineDrawOrGetDistance(p.Plus(u), p.Minus(u).Plus(n));
                LineDrawOrGetDistance(p.Minus(u), p.Plus(u).Plus(n));
            }
            break;
        }

        case EQUAL_ANGLE: {
            Vector ref;
            Entity *a = SK.GetEntity(entityA);
            Entity *b = SK.GetEntity(entityB);
            Entity *c = SK.GetEntity(entityC);
            Entity *d = SK.GetEntity(entityD);

            Vector a0 = a->VectorGetRefPoint();
            Vector b0 = b->VectorGetRefPoint();
            Vector c0 = c->VectorGetRefPoint();
            Vector d0 = d->VectorGetRefPoint();
            Vector da = a->VectorGetNum();
            Vector db = b->VectorGetNum();
            Vector dc = c->VectorGetNum();
            Vector dd = d->VectorGetNum();

            if(other) da = da.ScaledBy(-1);

            DoArcForAngle(a0, da, b0, db,
                da.WithMagnitude(40/SS.GW.scale), &ref);
            DoArcForAngle(c0, dc, d0, dd,
                dc.WithMagnitude(40/SS.GW.scale), &ref);

            break;
        }

        case ANGLE: {
            Entity *a = SK.GetEntity(entityA);
            Entity *b = SK.GetEntity(entityB);

            Vector a0 = a->VectorGetRefPoint();
            Vector b0 = b->VectorGetRefPoint();
            Vector da = a->VectorGetNum();
            Vector db = b->VectorGetNum();
            if(other) da = da.ScaledBy(-1);

            Vector ref;
            DoArcForAngle(a0, da, b0, db, disp.offset, &ref);
            DoLabel(ref, labelPos, gr, gu);
            break;
        }

        case PERPENDICULAR: {
            Vector u = Vector::From(0, 0, 0), v = Vector::From(0, 0, 0);
            Vector rn, ru;
            if(workplane.v == Entity::FREE_IN_3D.v) {
                rn = gn;
                ru = gu;
            } else {
                EntityBase *normal = SK.GetEntity(workplane)->Normal();
                rn = normal->NormalN();
                ru = normal->NormalV(); // ru meaning r_up, not u/v
            }

            for(int i = 0; i < 2; i++) {
                Entity *e = SK.GetEntity(i == 0 ? entityA : entityB);

                if(i == 0) {
                    // Calculate orientation of perpendicular sign only
                    // once, so that it's the same both times it's drawn
                    u = e->VectorGetNum();
                    u = u.WithMagnitude(16/SS.GW.scale);
                    v = (rn.Cross(u)).WithMagnitude(16/SS.GW.scale);
                    // a bit of bias to stop it from flickering between the
                    // two possibilities
                    if(fabs(u.Dot(ru)) < fabs(v.Dot(ru)) + LENGTH_EPS) {
                        SWAP(Vector, u, v);
                    }
                    if(u.Dot(ru) < 0) u = u.ScaledBy(-1);
                }

                Vector p = e->VectorGetRefPoint();
                Vector s = p.Plus(u).Plus(v);
                LineDrawOrGetDistance(s, s.Plus(v));

                Vector m = s.Plus(v.ScaledBy(0.5));
                LineDrawOrGetDistance(m, m.Plus(u));
            }
            break;
        }

        case CURVE_CURVE_TANGENT:
        case CUBIC_LINE_TANGENT:
        case ARC_LINE_TANGENT: {
            Vector textAt, u, v;

            if(type == ARC_LINE_TANGENT) {
                Entity *arc = SK.GetEntity(entityA);
                Entity *norm = SK.GetEntity(arc->normal);
                Vector c = SK.GetEntity(arc->point[0])->PointGetNum();
                Vector p =
                    SK.GetEntity(arc->point[other ? 2 : 1])->PointGetNum();
                Vector r = p.Minus(c);
                textAt = p.Plus(r.WithMagnitude(14/SS.GW.scale));
                u = norm->NormalU();
                v = norm->NormalV();
            } else if(type == CUBIC_LINE_TANGENT) {
                Vector n;
                if(workplane.v == Entity::FREE_IN_3D.v) {
                    u = gr;
                    v = gu;
                    n = gn;
                } else {
                    EntityBase *wn = SK.GetEntity(workplane)->Normal();
                    u = wn->NormalU();
                    v = wn->NormalV();
                    n = wn->NormalN();
                }

                Entity *cubic = SK.GetEntity(entityA);
                Vector p = other ? cubic->CubicGetFinishNum() :
                                   cubic->CubicGetStartNum();
                Vector dir = SK.GetEntity(entityB)->VectorGetNum();
                Vector out = n.Cross(dir);
                textAt = p.Plus(out.WithMagnitude(14/SS.GW.scale));
            } else {
                Vector n, dir;
                EntityBase *wn = SK.GetEntity(workplane)->Normal();
                u = wn->NormalU();
                v = wn->NormalV();
                n = wn->NormalN();
                EntityBase *eA = SK.GetEntity(entityA);
                // Big pain; we have to get a vector tangent to the curve
                // at the shared point, which could be from either a cubic
                // or an arc.
                if(other) {
                    textAt = eA->EndpointFinish();
                    if(eA->type == Entity::CUBIC) {
                        dir = eA->CubicGetFinishTangentNum();
                    } else {
                        dir = SK.GetEntity(eA->point[0])->PointGetNum().Minus(
                              SK.GetEntity(eA->point[2])->PointGetNum());
                        dir = n.Cross(dir);
                    }
                } else {
                    textAt = eA->EndpointStart();
                    if(eA->type == Entity::CUBIC) {
                        dir = eA->CubicGetStartTangentNum();
                    } else {
                        dir = SK.GetEntity(eA->point[0])->PointGetNum().Minus(
                              SK.GetEntity(eA->point[1])->PointGetNum());
                        dir = n.Cross(dir);
                    }
                }
                dir = n.Cross(dir);
                textAt = textAt.Plus(dir.WithMagnitude(14/SS.GW.scale));
            }

            if(dogd.drawing) {
                ssglWriteTextRefCenter("T", DEFAULT_TEXT_HEIGHT,
                    textAt, u, v, LineCallback, this);
            } else {
                dogd.refp = textAt;
                Point2d ref = SS.GW.ProjectPoint(dogd.refp);
                dogd.dmin = min(dogd.dmin, ref.DistanceTo(dogd.mp)-10);
            }
            break;
        }

        case PARALLEL: {
            for(int i = 0; i < 2; i++) {
                Entity *e = SK.GetEntity(i == 0 ? entityA : entityB);
                Vector n = e->VectorGetNum();
                n = n.WithMagnitude(25/SS.GW.scale);
                Vector u = (gn.Cross(n)).WithMagnitude(4/SS.GW.scale);
                Vector p = e->VectorGetRefPoint();

                LineDrawOrGetDistance(p.Plus(u), p.Plus(u).Plus(n));
                LineDrawOrGetDistance(p.Minus(u), p.Minus(u).Plus(n));
            }
            break;
        }

        case EQUAL_RADIUS: {
            for(int i = 0; i < 2; i++) {
                DoEqualRadiusTicks(i == 0 ? entityA : entityB);
            }
            break;
        }

        case EQUAL_LINE_ARC_LEN: {
            Entity *line = SK.GetEntity(entityA);
            DoEqualLenTicks(
                SK.GetEntity(line->point[0])->PointGetNum(),
                SK.GetEntity(line->point[1])->PointGetNum(),
                gn);

            DoEqualRadiusTicks(entityB);
            break;
        }

        case LENGTH_RATIO:
        case EQUAL_LENGTH_LINES: {
            Vector a, b = Vector::From(0, 0, 0);
            for(int i = 0; i < 2; i++) {
                Entity *e = SK.GetEntity(i == 0 ? entityA : entityB);
                a = SK.GetEntity(e->point[0])->PointGetNum();
                b = SK.GetEntity(e->point[1])->PointGetNum();

                if(workplane.v != Entity::FREE_IN_3D.v) {
                    DoProjectedPoint(&a);
                    DoProjectedPoint(&b);
                }

                DoEqualLenTicks(a, b, gn);
            }
            if(type == LENGTH_RATIO) {
                Vector ref = ((a.Plus(b)).ScaledBy(0.5)).Plus(disp.offset);
                DoLabel(ref, labelPos, gr, gu);
            }
            break;
        }

        case EQ_LEN_PT_LINE_D: {
            Entity *forLen = SK.GetEntity(entityA);
            Vector a = SK.GetEntity(forLen->point[0])->PointGetNum(),
                   b = SK.GetEntity(forLen->point[1])->PointGetNum();
            if(workplane.v != Entity::FREE_IN_3D.v) {
                DoProjectedPoint(&a);
                DoProjectedPoint(&b);
            }
            DoEqualLenTicks(a, b, gn);

            Entity *ln = SK.GetEntity(entityB);
            Vector la = SK.GetEntity(ln->point[0])->PointGetNum(),
                   lb = SK.GetEntity(ln->point[1])->PointGetNum();
            Vector pt = SK.GetEntity(ptA)->PointGetNum();
            if(workplane.v != Entity::FREE_IN_3D.v) {
                DoProjectedPoint(&pt);
                la = la.ProjectInto(workplane);
                lb = lb.ProjectInto(workplane);
            }

            Vector closest = pt.ClosestPointOnLine(la, lb.Minus(la));
            LineDrawOrGetDistance(pt, closest);
            DoEqualLenTicks(pt, closest, gn);
            break;
        }

        case EQ_PT_LN_DISTANCES: {
            for(int i = 0; i < 2; i++) {
                Entity *ln = SK.GetEntity(i == 0 ? entityA : entityB);
                Vector la = SK.GetEntity(ln->point[0])->PointGetNum(),
                       lb = SK.GetEntity(ln->point[1])->PointGetNum();
                Entity *pte = SK.GetEntity(i == 0 ? ptA : ptB);
                Vector pt = pte->PointGetNum();

                if(workplane.v != Entity::FREE_IN_3D.v) {
                    DoProjectedPoint(&pt);
                    la = la.ProjectInto(workplane);
                    lb = lb.ProjectInto(workplane);
                }

                Vector closest = pt.ClosestPointOnLine(la, lb.Minus(la));

                LineDrawOrGetDistance(pt, closest);
                DoEqualLenTicks(pt, closest, gn);
            }
            break;
        }

        {
        case SYMMETRIC:
            Vector n;
            n = SK.GetEntity(entityA)->Normal()->NormalN(); goto s;
        case SYMMETRIC_HORIZ:
            n = SK.GetEntity(workplane)->Normal()->NormalU(); goto s;
        case SYMMETRIC_VERT:
            n = SK.GetEntity(workplane)->Normal()->NormalV(); goto s;
        case SYMMETRIC_LINE: {
            Entity *ln = SK.GetEntity(entityA);
            Vector la = SK.GetEntity(ln->point[0])->PointGetNum(),
                   lb = SK.GetEntity(ln->point[1])->PointGetNum();
            la = la.ProjectInto(workplane);
            lb = lb.ProjectInto(workplane);
            n = lb.Minus(la);
            Vector nw = SK.GetEntity(workplane)->Normal()->NormalN();
            n = n.RotatedAbout(nw, PI/2);
            goto s;
        }
s:
            Vector a = SK.GetEntity(ptA)->PointGetNum();
            Vector b = SK.GetEntity(ptB)->PointGetNum();

            for(int i = 0; i < 2; i++) {
                Vector tail = (i == 0) ? a : b;
                Vector d = (i == 0) ? b : a;
                d = d.Minus(tail);
                // Project the direction in which the arrow is drawn normal
                // to the symmetry plane; for projected symmetry constraints,
                // they might not be in the same direction, even when the
                // constraint is fully solved.
                d = n.ScaledBy(d.Dot(n));
                d = d.WithMagnitude(20/SS.GW.scale);
                Vector tip = tail.Plus(d);

                LineDrawOrGetDistance(tail, tip);
                d = d.WithMagnitude(9/SS.GW.scale);
                LineDrawOrGetDistance(tip, tip.Minus(d.RotatedAbout(gn,  0.6)));
                LineDrawOrGetDistance(tip, tip.Minus(d.RotatedAbout(gn, -0.6)));
            }
            break;
        }

        case AT_MIDPOINT:
        case HORIZONTAL:
        case VERTICAL:
            if(entityA.v) {
                Vector r, u, n;
                if(workplane.v == Entity::FREE_IN_3D.v) {
                    r = gr; u = gu; n = gn;
                } else {
                    r = SK.GetEntity(workplane)->Normal()->NormalU();
                    u = SK.GetEntity(workplane)->Normal()->NormalV();
                    n = r.Cross(u);
                }
                // For "at midpoint", this branch is always taken.
                Entity *e = SK.GetEntity(entityA);
                Vector a = SK.GetEntity(e->point[0])->PointGetNum();
                Vector b = SK.GetEntity(e->point[1])->PointGetNum();
                Vector m = (a.ScaledBy(0.5)).Plus(b.ScaledBy(0.5));
                Vector offset = (a.Minus(b)).Cross(n);
                offset = offset.WithMagnitude(13/SS.GW.scale);
                // Draw midpoint constraint on other side of line, so that
                // a line can be midpoint and horizontal at same time.
                if(type == AT_MIDPOINT) offset = offset.ScaledBy(-1);

                if(dogd.drawing) {
                    const char *s = (type == HORIZONTAL)  ? "H" : (
                                    (type == VERTICAL)    ? "V" : (
                                    (type == AT_MIDPOINT) ? "M" : NULL));

                    ssglWriteTextRefCenter(s, DEFAULT_TEXT_HEIGHT,
                        m.Plus(offset), r, u, LineCallback, this);
                } else {
                    dogd.refp = m.Plus(offset);
                    Point2d ref = SS.GW.ProjectPoint(dogd.refp);
                    dogd.dmin = min(dogd.dmin, ref.DistanceTo(dogd.mp)-10);
                }
            } else {
                Vector a = SK.GetEntity(ptA)->PointGetNum();
                Vector b = SK.GetEntity(ptB)->PointGetNum();

                Entity *w = SK.GetEntity(workplane);
                Vector cu = w->Normal()->NormalU();
                Vector cv = w->Normal()->NormalV();
                Vector cn = w->Normal()->NormalN();

                int i;
                for(i = 0; i < 2; i++) {
                    Vector o = (i == 0) ? a : b;
                    Vector oo = (i == 0) ? a.Minus(b) : b.Minus(a);
                    Vector d = (type == HORIZONTAL) ? cu : cv;
                    if(oo.Dot(d) < 0) d = d.ScaledBy(-1);

                    Vector dp = cn.Cross(d);
                    d = d.WithMagnitude(14/SS.GW.scale);
                    Vector c = o.Minus(d);
                    LineDrawOrGetDistance(o, c);
                    d = d.WithMagnitude(3/SS.GW.scale);
                    dp = dp.WithMagnitude(2/SS.GW.scale);
                    if(dogd.drawing) {
                        glBegin(GL_QUADS);
                            ssglVertex3v((c.Plus(d)).Plus(dp));
                            ssglVertex3v((c.Minus(d)).Plus(dp));
                            ssglVertex3v((c.Minus(d)).Minus(dp));
                            ssglVertex3v((c.Plus(d)).Minus(dp));
                        glEnd();
                    } else {
                        Point2d ref = SS.GW.ProjectPoint(c);
                        dogd.dmin = min(dogd.dmin, ref.DistanceTo(dogd.mp)-6);
                    }
                }
            }
            break;

        case COMMENT: {
            if(dogd.drawing && disp.style.v) {
                ssglLineWidth(Style::Width(disp.style));
                ssglColorRGB(Style::Color(disp.style));
            }
            Vector u, v;
            if(workplane.v == Entity::FREE_IN_3D.v) {
                u = gr;
                v = gu;
            } else {
                EntityBase *norm = SK.GetEntity(workplane)->Normal();
                u = norm->NormalU();
                v = norm->NormalV();
            }
            DoLabel(disp.offset, labelPos, u, v);
            break;
        }

        default: oops();
    }
}
Пример #6
0
void CUI::DoLabelScaled(const CUIRect *r, const char *pText, float Size, int Align, int MaxWidth)
{
	DoLabel(r, pText, Size*Scale(), Align, MaxWidth);
}
Пример #7
0
bool AsmFile::Read()
{	
    bool rv = true;
    AsmExpr::ReInit();
    parser->Init();
    bigEndian = parser->IsBigEndian();
    FPF::SetBigEndian(bigEndian);
    Instruction::SetBigEndian(bigEndian);
    listing.SetBigEndian(bigEndian);
    while (!lexer.AtEof())
    {
        bool inInstruction = false;
        try
        {
            if (GetKeyword() == Lexer::openbr)
            {
                Directive();
                thisLabel = NULL;
            }
            else if (parser->MatchesOpcode(GetToken()->GetChars()))
            {
                NoAbsolute();
                NeedSection();
                inInstruction = true;
                int lineno = preProcessor.GetMainLineNo();
                Instruction *ins = parser->Parse(lexer.GetRestOfLine(), currentSection->GetPC());
                if (lineno >= 0)
                    listing.Add(ins, lineno, preProcessor.InMacro());
                NextToken();
                currentSection->InsertInstruction(ins);
                thisLabel = NULL;
            }
            else
            {
                int lineno = preProcessor.GetMainLineNo();
                std::string name = GetId();
                DoLabel(name, lineno);
            }
        }
        catch(std::runtime_error *e)
        {
            Errors::Error(e->what());
            delete e;
            rv = false;
            if (inInstruction)
                NextToken();
            else
                lexer.SkipPastEol();
        }
    }
    for (std::map<std::string, std::string>::iterator it = exports.begin(); it != exports.end(); ++it)
    {
        if (labels[it->first] == NULL)
        {
            Errors::Error(std::string("Undefined export symbol '") + it->first + "'");
            rv = false;
        }
        else
        {
            labels[it->first]->SetPublic(true);
        }
    }
    for (std::set<std::string>::iterator it = globals.begin(); it != globals.end(); ++it)
    {
        if (labels[*it] == NULL)
        {
            Errors::Error(std::string("Undefined public '") + *it + "'");
            rv = false;
        }
        else
        {
            labels[*it]->SetPublic(true);
        }
    }
    return rv && !Errors::ErrorCount();
}
Пример #8
0
std::ostream &
	TKSwitch::
	Release(std::ostream & s) const
{
	DoLabel(s);
	s << "switch(";
	// Thing to switch on
	GetFirstChild().Release(s);
	s << "){";
	Token::Itter
		cases = *this;
	// Skip the switch conditional
	cases.Next();
	bool
		semicolon = false;
	while (cases.HasNext())
	{
		// Don't put a semicolon
		// after the very last
		// statement in this
		// switch.
		if (semicolon)
		{
			s << ';';
		}
		semicolon = false;
		Token &
			cur = cases.Next();
		Token::Itter
			entries = cur;
		if (cur.GetType() == TokenType::TK_case)
		{
			s << "case";
			DoSpacePar(entries.Next(), s);
			s << ':';
		}
		else if (cur.GetType() == TokenType::TK_default)
		{
			s << "default:";
		}
		else
		{
			continue;
		}
		while (entries.HasNext())
		{
			if (semicolon)
			{
				s << ';';
			}
			Token &
				ent = entries.Next();
			ent.Release(s);
			if (ent.IsStatement())
			{
				// Some statements
				// need semicolons
				semicolon = ent.RequireSemicolon();
			}
			else
			{
				// All expressions
				// need semicolons
				semicolon = true;
			}
		}
	}
	s << '}';
	return s;
}