void AsmStatement::toIR(IRState *irs) { block *bpre; block *basm; Declaration *d; Symbol *s; Blockx *blx = irs->blx; //printf("AsmStatement::toIR(asmcode = %x)\n", asmcode); bpre = blx->curblock; block_next(blx,BCgoto,NULL); basm = blx->curblock; list_append(&bpre->Bsucc, basm); basm->Bcode = asmcode; basm->Balign = asmalign; #if 0 if (label) { block *b; b = labelToBlock(loc, blx, label); printf("AsmStatement::toIR() %p\n", b); if (b) list_append(&basm->Bsucc, b); } #endif // Loop through each instruction, fixing Dsymbols into Symbol's for (code *c = asmcode; c; c = c->next) { LabelDsymbol *label; block *b; switch (c->IFL1) { case FLblockoff: case FLblock: // FLblock and FLblockoff have LabelDsymbol's - convert to blocks label = c->IEVlsym1; b = labelToBlock(loc, blx, label); list_append(&basm->Bsucc, b); c->IEV1.Vblock = b; break; case FLdsymbol: case FLfunc: s = c->IEVdsym1->toSymbol(); if (s->Sclass == SCauto && s->Ssymnum == -1) symbol_add(s); c->IEVsym1 = s; c->IFL1 = s->Sfl ? s->Sfl : FLauto; break; } // Repeat for second operand switch (c->IFL2) { case FLblockoff: case FLblock: label = c->IEVlsym2; b = labelToBlock(loc, blx, label); list_append(&basm->Bsucc, b); c->IEV2.Vblock = b; break; case FLdsymbol: case FLfunc: d = c->IEVdsym2; s = d->toSymbol(); if (s->Sclass == SCauto && s->Ssymnum == -1) symbol_add(s); c->IEVsym2 = s; c->IFL2 = s->Sfl ? s->Sfl : FLauto; if (d->isDataseg()) s->Sflags |= SFLlivexit; break; } //c->print(); } basm->bIasmrefparam = refparam; // are parameters reference? basm->usIasmregs = regs; // registers modified block_next(blx,BCasm, NULL); list_prepend(&basm->Bsucc, blx->curblock); if (naked) { blx->funcsym->Stype->Tty |= mTYnaked; } }
void PragmaDeclaration::semantic(Scope *sc) { // Should be merged with PragmaStatement Scope sc_save; //printf("\tPragmaDeclaration::semantic '%s'\n",toChars()); if (ident == Id::msg) { if (args) { for (size_t i = 0; i < args->dim; i++) { Expression *e = (*args)[i]; e = e->semantic(sc); if (e->op != TOKerror && e->op != TOKtype) e = e->ctfeInterpret(); if (e->op == TOKerror) { errorSupplemental(loc, "while evaluating pragma(msg, %s)", (*args)[i]->toChars()); return; } StringExp *se = e->toString(); if (se) { fprintf(stdmsg, "%.*s", (int)se->len, (char *)se->string); } else fprintf(stdmsg, "%s", e->toChars()); } fprintf(stdmsg, "\n"); } goto Lnodecl; } else if (ident == Id::lib) { if (!args || args->dim != 1) error("string expected for library name"); else { Expression *e = (*args)[0]; e = e->semantic(sc); e = e->ctfeInterpret(); (*args)[0] = e; if (e->op == TOKerror) goto Lnodecl; StringExp *se = e->toString(); if (!se) error("string expected for library name, not '%s'", e->toChars()); else if (global.params.verbose) { char *name = (char *)mem.malloc(se->len + 1); memcpy(name, se->string, se->len); name[se->len] = 0; fprintf(stdmsg, "library %s\n", name); mem.free(name); } } goto Lnodecl; } #ifdef IN_GCC else if (ident == Id::GNU_asm) { if (! args || args->dim != 2) error("identifier and string expected for asm name"); else { Expression *e; Declaration *d = NULL; StringExp *s = NULL; e = (*args)[0]; e = e->semantic(sc); if (e->op == TOKvar) { d = ((VarExp *)e)->var; if (! d->isFuncDeclaration() && ! d->isVarDeclaration()) d = NULL; } if (!d) error("first argument of GNU_asm must be a function or variable declaration"); e = (*args)[1]; e = e->semantic(sc); e = e->ctfeInterpret(); e = e->toString(); if (e && ((StringExp *)e)->sz == 1) s = ((StringExp *)e); else error("second argument of GNU_asm must be a character string"); if (d && s) d->c_ident = Lexer::idPool((char*) s->string); } goto Lnodecl; } else if (ident == Id::GNU_attribute) { sc_save = *sc; // An empty list is allowed. if (args && args->dim) { Expressions * a; if (sc->attributes) a = (Expressions *) sc->attributes->copy(); else a = new Expressions; sc->attributes = a; for (unsigned i = 0; i < args->dim; i++) { Expression * e = (*args)[i]; //e = e->semantic(sc); if (e->op == TOKidentifier) ; // ok else if (e->op == TOKcall) { CallExp * c = (CallExp *) e; if (c->e1->op != TOKidentifier) error("identifier or call expression expected for attribute"); if (c->arguments) for (int unsigned ai = 0; ai < c->arguments->dim; ai++) { Expression * ea = c->arguments->tdata()[ai]; ea = ea->semantic(sc); ea = ea->optimize(WANTvalue | WANTinterpret); c->arguments->tdata()[ai] = ea; } } else { error("identifier or call expression expected for attribute"); continue; } a->push(e); } } } else if (ident == Id::GNU_set_attribute) { if (!args || args->dim < 1) error("declaration expected for setting attributes"); else { Expressions ** p_attributes = NULL; // list of existing attributes { Expression * e = (*args)[0]; e = e->semantic(sc); if (e->op == TOKvar) { Declaration * d = ((VarExp *)e)->var; if (d->isFuncDeclaration() || d->isVarDeclaration()) p_attributes = & d->attributes; } else if (e->op == TOKtype) { Type * t = ((TypeExp *)e)->type; if (t->ty == Ttypedef) p_attributes = & ((TypeTypedef *) t)->sym->attributes; else if (t->ty == Tenum) p_attributes = & ((TypeEnum *) t)->sym->attributes; else if (t->ty == Tstruct) p_attributes = & ((TypeStruct *) t)->sym->attributes; else if (t->ty == Tclass) p_attributes = & ((TypeClass *) t)->sym->attributes; } if (p_attributes == NULL) error("first argument must be a function, variable, or type declaration"); } Expressions * new_attrs = new Expressions; for (unsigned i = 1; i < args->dim; i++) { Expression * e = (*args)[i]; //e = e->semantic(sc); if (e->op == TOKidentifier) ; // ok else if (e->op == TOKcall) { CallExp * c = (CallExp *) e; if (c->e1->op != TOKidentifier) error("identifier or call expression expected for attribute"); if (c->arguments) for (int unsigned ai = 0; ai < c->arguments->dim; ai++) { Expression * ea = c->arguments->tdata()[ai]; ea = ea->semantic(sc); ea = ea->optimize(WANTvalue | WANTinterpret); c->arguments->tdata()[ai] = ea; } } else { error("identifier or call expression expected for attribute"); continue; } new_attrs->push(e); } if (p_attributes) { if (*p_attributes) { *p_attributes = (Expressions *) (*p_attributes)->copy(); (*p_attributes)->append(new_attrs); } else *p_attributes = new_attrs; } } goto Lnodecl; } #endif #if DMDV2 else if (ident == Id::startaddress) { if (!args || args->dim != 1) error("function name expected for start address"); else { Expression *e = (*args)[0]; e = e->semantic(sc); e = e->ctfeInterpret(); (*args)[0] = e; Dsymbol *sa = getDsymbol(e); if (!sa || !sa->isFuncDeclaration()) error("function name expected for start address, not '%s'", e->toChars()); } goto Lnodecl; } #endif #if TARGET_NET else if (ident == Lexer::idPool("assembly")) { } #endif // TARGET_NET else if (global.params.ignoreUnsupportedPragmas) { if (global.params.verbose) { /* Print unrecognized pragmas */ fprintf(stdmsg, "pragma %s", ident->toChars()); if (args) { for (size_t i = 0; i < args->dim; i++) { Expression *e = (*args)[i]; e = e->semantic(sc); e = e->ctfeInterpret(); if (i == 0) printf(" ("); else printf(","); printf("%s", e->toChars()); } if (args->dim) printf(")"); } printf("\n"); } goto Lnodecl; } else error("unrecognized pragma(%s)", ident->toChars()); Ldecl: if (decl) { for (size_t i = 0; i < decl->dim; i++) { Dsymbol *s = (*decl)[i]; s->semantic(sc); } } #ifdef IN_GCC if (decl) { if (ident == Id::GNU_attribute) *sc = sc_save; } #endif return; Lnodecl: if (decl) { error("pragma is missing closing ';'"); goto Ldecl; // do them anyway, to avoid segfaults. } }
static bool DeclareInner(Port &port, const Declaration &declaration, OperationEnvironment &env) { assert(declaration.size() >= 2); assert(declaration.size() <= 12); char user_data[2500]; if (!TryConnect(port, user_data) || env.IsCancelled()) return false; char *p = strstr(user_data, "USER DETAILS"); if (p != NULL) *p = 0; port.Write('\x18'); // start to upload file port.Write(user_data); port.Write("USER DETAILS\r\n--------------\r\n\r\n"); EWMicroRecorderPrintf(port, _T("%-15s %s\r\n"), _T("Pilot Name:"), declaration.PilotName.c_str()); EWMicroRecorderPrintf(port, _T("%-15s %s\r\n"), _T("Competition ID:"), declaration.CompetitionId.c_str()); EWMicroRecorderPrintf(port, _T("%-15s %s\r\n"), _T("Aircraft Type:"), declaration.AircraftType.c_str()); EWMicroRecorderPrintf(port, _T("%-15s %s\r\n"), _T("Aircraft ID:"), declaration.AircraftReg.c_str()); port.Write("\r\nFLIGHT DECLARATION\r\n-------------------\r\n\r\n"); EWMicroRecorderPrintf(port, _T("%-15s %s\r\n"), _T("Description:"), _T("XCSoar task declaration")); for (unsigned i = 0; i < 11; i++) { if (env.IsCancelled()) return false; if (i+1>= declaration.size()) { EWMicroRecorderPrintf(port, _T("%-17s %s\r\n"), _T("TP LatLon:"), _T("0000000N00000000E TURN POINT")); } else { const Waypoint &wp = declaration.get_waypoint(i); if (i == 0) { EWMicroRecorderWriteWaypoint(port, wp, _T("Take Off LatLong:")); EWMicroRecorderWriteWaypoint(port, wp, _T("Start LatLon:")); } else if (i + 1 < declaration.size()) { EWMicroRecorderWriteWaypoint(port, wp, _T("TP LatLon:")); } } } const Waypoint &wp = declaration.get_last_waypoint(); EWMicroRecorderWriteWaypoint(port, wp, _T("Finish LatLon:")); EWMicroRecorderWriteWaypoint(port, wp, _T("Land LatLon:")); if (env.IsCancelled()) return false; port.Write('\x03'); // finish sending user file return port.ExpectString("uploaded successfully"); }
void Output::operator()(Ruleset* r) { Selector* s = r->selector(); Block* b = r->block(); bool decls = false; // Filter out rulesets that aren't printable (process its children though) if (!Util::isPrintable(r, output_style())) { for (size_t i = 0, L = b->length(); i < L; ++i) { Statement* stm = (*b)[i]; if (dynamic_cast<Has_Block*>(stm)) { stm->perform(this); } } return; } if (b->has_non_hoistable()) { decls = true; if (output_style() == SASS_STYLE_NESTED) indentation += r->tabs(); if (ctx && ctx->c_options->source_comments) { std::stringstream ss; append_indentation(); ss << "/* line " << r->pstate().line + 1 << ", " << r->pstate().path << " */"; append_string(ss.str()); append_optional_linefeed(); } s->perform(this); append_scope_opener(b); for (size_t i = 0, L = b->length(); i < L; ++i) { Statement* stm = (*b)[i]; bool bPrintExpression = true; // Check print conditions if (typeid(*stm) == typeid(Declaration)) { Declaration* dec = static_cast<Declaration*>(stm); if (dec->value()->concrete_type() == Expression::STRING) { String_Constant* valConst = static_cast<String_Constant*>(dec->value()); std::string val(valConst->value()); if (auto qstr = dynamic_cast<String_Quoted*>(valConst)) { if (!qstr->quote_mark() && val.empty()) { bPrintExpression = false; } } } else if (dec->value()->concrete_type() == Expression::LIST) { List* list = static_cast<List*>(dec->value()); bool all_invisible = true; for (size_t list_i = 0, list_L = list->length(); list_i < list_L; ++list_i) { Expression* item = (*list)[list_i]; if (!item->is_invisible()) all_invisible = false; } if (all_invisible) bPrintExpression = false; } } // Print if OK if (!stm->is_hoistable() && bPrintExpression) { stm->perform(this); } } if (output_style() == SASS_STYLE_NESTED) indentation -= r->tabs(); append_scope_closer(b); } if (b->has_hoistable()) { if (decls) ++indentation; for (size_t i = 0, L = b->length(); i < L; ++i) { Statement* stm = (*b)[i]; if (stm->is_hoistable()) { stm->perform(this); } } if (decls) --indentation; } }
void Output_Nested::operator()(Ruleset* r) { Selector* s = r->selector(); Block* b = r->block(); bool decls = false; if (s->has_placeholder()) return; if (b->has_non_hoistable()) { decls = true; indent(); if (source_comments) { stringstream ss; ss << "/* line " << r->position().line << ", " << r->path() << " */" << endl; append_singleline_part_to_buffer(ss.str()); indent(); } s->perform(this); append_multiline_part_to_buffer(" {\n"); ++indentation; for (size_t i = 0, L = b->length(); i < L; ++i) { Statement* stm = (*b)[i]; bool bPrintExpression = true; // Check print conditions if (typeid(*stm) == typeid(Declaration)) { Declaration* dec = static_cast<Declaration*>(stm); if (dec->value()->concrete_type() == Expression::STRING) { String_Constant* valConst = static_cast<String_Constant*>(dec->value()); string val(valConst->value()); if (val.empty()) { bPrintExpression = false; } } else if (dec->value()->concrete_type() == Expression::LIST) { List* list = static_cast<List*>(dec->value()); bool all_invisible = true; for (size_t list_i = 0, list_L = list->length(); list_i < list_L; ++list_i) { Expression* item = (*list)[list_i]; if (!item->is_invisible()) all_invisible = false; } if (all_invisible) bPrintExpression = false; } } // Print if OK if (!stm->is_hoistable() && bPrintExpression) { if (!stm->block()) indent(); stm->perform(this); append_multiline_part_to_buffer("\n"); } } --indentation; buffer.erase(buffer.length()-1); if (ctx) ctx->source_map.remove_line(); append_multiline_part_to_buffer(" }\n"); } if (b->has_hoistable()) { if (decls) ++indentation; // indent(); for (size_t i = 0, L = b->length(); i < L; ++i) { Statement* stm = (*b)[i]; if (stm->is_hoistable()) { stm->perform(this); } } if (decls) --indentation; } }
void PragmaDeclaration::semantic(Scope *sc) { // Should be merged with PragmaStatement //printf("\tPragmaDeclaration::semantic '%s'\n",toChars()); if (ident == Id::msg) { if (args) { for (size_t i = 0; i < args->dim; i++) { Expression *e = (Expression *)args->data[i]; e = e->semantic(sc); if (e->op == TOKstring) { StringExp *se = (StringExp *)e; fprintf(stdmsg, "%.*s", se->len, se->string); } else error("string expected for message, not '%s'", e->toChars()); } fprintf(stdmsg, "\n"); } goto Lnodecl; } else if (ident == Id::lib) { if (!args || args->dim != 1) error("string expected for library name"); else { Expression *e = (Expression *)args->data[0]; e = e->semantic(sc); args->data[0] = (void *)e; if (e->op != TOKstring) error("string expected for library name, not '%s'", e->toChars()); } goto Lnodecl; } #if IN_GCC else if (ident == Id::GNU_asm) { if (! args || args->dim != 2) error("identifier and string expected for asm name"); else { Expression *e; Declaration *d = NULL; StringExp *s = NULL; e = (Expression *)args->data[0]; e = e->semantic(sc); if (e->op == TOKvar) { d = ((VarExp *)e)->var; if (! d->isFuncDeclaration() && ! d->isVarDeclaration()) d = NULL; } if (!d) error("first argument of GNU_asm must be a function or variable declaration"); e = (Expression *)args->data[1]; e = e->semantic(sc); e = e->optimize(WANTvalue); if (e->op == TOKstring && ((StringExp *)e)->sz == 1) s = ((StringExp *)e); else error("second argument of GNU_asm must be a char string"); if (d && s) d->c_ident = Lexer::idPool((char*) s->string); } goto Lnodecl; } #endif else error("unrecognized pragma(%s)", ident->toChars()); if (decl) { for (unsigned i = 0; i < decl->dim; i++) { Dsymbol *s = (Dsymbol *)decl->data[i]; s->semantic(sc); } } return; Lnodecl: if (decl) error("pragma is missing closing ';'"); }
static bool DeclareInner(Port &port, const Declaration &declaration, OperationEnvironment &env) { assert(declaration.Size() >= 2); assert(declaration.Size() <= 12); char user_data[2500]; if (!TryConnectRetry(port, user_data, sizeof(user_data), env)) return false; char *p = strstr(user_data, "USER DETAILS"); if (p != NULL) *p = 0; port.Write('\x18'); // start to upload file if (!port.FullWriteString(user_data, 5000) || !port.FullWriteString("USER DETAILS\r\n--------------\r\n\r\n", 1000)) return false; WritePair(port, "Pilot Name", declaration.pilot_name.c_str()); WritePair(port, "Competition ID", declaration.competition_id.c_str()); WritePair(port, "Aircraft Type", declaration.aircraft_type.c_str()); WritePair(port, "Aircraft ID", declaration.aircraft_registration.c_str()); if (!port.FullWriteString("\r\nFLIGHT DECLARATION\r\n-------------------\r\n\r\n", 1000)) return false; WritePair(port, "Description", _T("XCSoar task declaration")); for (unsigned i = 0; i < 11; i++) { if (env.IsCancelled()) return false; if (i+1>= declaration.Size()) { port.FullWriteString("TP LatLon: 0000000N00000000E TURN POINT\r\n", 1000); } else { const Waypoint &wp = declaration.GetWaypoint(i); if (i == 0) { EWMicroRecorderWriteWaypoint(port, "Take Off LatLong", wp); EWMicroRecorderWriteWaypoint(port, "Start LatLon", wp); } else if (i + 1 < declaration.Size()) { EWMicroRecorderWriteWaypoint(port, "TP LatLon", wp); } } } const Waypoint &wp = declaration.GetLastWaypoint(); EWMicroRecorderWriteWaypoint(port, "Finish LatLon", wp); EWMicroRecorderWriteWaypoint(port, "Land LatLon", wp); if (env.IsCancelled()) return false; port.Write('\x03'); // finish sending user file return port.ExpectString("uploaded successfully"); }
Dsymbol *ScopeDsymbol::search(Loc loc, Identifier *ident, int flags) { //printf("%s->ScopeDsymbol::search(ident='%s', flags=x%x)\n", toChars(), ident->toChars(), flags); //if (strcmp(ident->toChars(),"c") == 0) *(char*)0=0; // Look in symbols declared in this module Dsymbol *s = symtab ? symtab->lookup(ident) : NULL; if (s) { //printf("\ts = '%s.%s'\n",toChars(),s->toChars()); } else if (imports) { // Look in imported modules for (size_t i = 0; i < imports->dim; i++) { ScopeDsymbol *ss = (*imports)[i]; Dsymbol *s2; // If private import, don't search it if (flags & 1 && prots[i] == PROTprivate) continue; //printf("\tscanning import '%s', prots = %d, isModule = %p, isImport = %p\n", ss->toChars(), prots[i], ss->isModule(), ss->isImport()); /* Don't find private members if ss is a module */ s2 = ss->search(loc, ident, ss->isModule() ? 1 : 0); if (!s) s = s2; else if (s2 && s != s2) { if (s->toAlias() == s2->toAlias()) { /* After following aliases, we found the same symbol, * so it's not an ambiguity. * But if one alias is deprecated, prefer the other. */ if (s->isDeprecated()) s = s2; } else { /* Two imports of the same module should be regarded as * the same. */ Import *i1 = s->isImport(); Import *i2 = s2->isImport(); if (!(i1 && i2 && (i1->mod == i2->mod || (!i1->parent->isImport() && !i2->parent->isImport() && i1->ident->equals(i2->ident)) ) ) ) { ss->multiplyDefined(loc, s, s2); break; } } } } if (s) { Declaration *d = s->isDeclaration(); if (d && d->protection == PROTprivate && !d->parent->isTemplateMixin()) error(loc, "%s is private", d->toPrettyChars()); } } return s; }
static bool DeclareInner(Port &port, const Declaration &declaration, gcc_unused OperationEnvironment &env) { using CAI302::UploadShort; unsigned size = declaration.Size(); port.SetRxTimeout(500); env.SetProgressRange(6 + size); env.SetProgressPosition(0); CAI302::CommandModeQuick(port); if (!CAI302::UploadMode(port) || env.IsCancelled()) return false; port.SetRxTimeout(1500); CAI302::PilotMeta pilot_meta; if (!CAI302::UploadPilotMeta(port, pilot_meta) || env.IsCancelled()) return false; env.SetProgressPosition(1); CAI302::Pilot pilot; if (!CAI302::UploadPilot(port, 0, pilot) || env.IsCancelled()) return false; env.SetProgressPosition(2); CAI302::PolarMeta polar_meta; if (!CAI302::UploadPolarMeta(port, polar_meta) || env.IsCancelled()) return false; env.SetProgressPosition(3); CAI302::Polar polar; if (!CAI302::UploadPolar(port, polar) || env.IsCancelled()) return false; env.SetProgressPosition(4); if (!CAI302::DownloadMode(port) || env.IsCancelled()) return false; char GliderType[13], GliderID[13]; convert_string(GliderType, sizeof(GliderType), declaration.aircraft_type); convert_string(GliderID, sizeof(GliderID), declaration.aircraft_registration); convert_string(pilot.name, sizeof(pilot.name), declaration.pilot_name); if (!CAI302::DownloadPilot(port, pilot) || env.IsCancelled()) return false; env.SetProgressPosition(5); convert_string(polar.glider_type, sizeof(polar.glider_type), declaration.aircraft_type); convert_string(polar.glider_id, sizeof(polar.glider_id), declaration.aircraft_registration); if (!CAI302::DownloadPolar(port, polar) || env.IsCancelled()) return false; env.SetProgressPosition(6); for (unsigned i = 0; i < size; ++i) { if (!cai302DeclAddWaypoint(port, i, declaration.GetWaypoint(i)) || env.IsCancelled()) return false; env.SetProgressPosition(7 + i); } port.SetRxTimeout(1500); // D,255 takes more than 800ms return CAI302::DeclareSave(port); }
void PragmaDeclaration::semantic(Scope *sc) { // Should be merged with PragmaStatement //printf("\tPragmaDeclaration::semantic '%s'\n",toChars()); if (ident == Id::msg) { if (args) { for (size_t i = 0; i < args->dim; i++) { Expression *e = args->tdata()[i]; e = e->semantic(sc); e = e->optimize(WANTvalue | WANTinterpret); StringExp *se = e->toString(); if (se) { fprintf(stdmsg, "%.*s", (int)se->len, (char *)se->string); } else fprintf(stdmsg, "%s", e->toChars()); } fprintf(stdmsg, "\n"); } goto Lnodecl; } else if (ident == Id::lib) { if (!args || args->dim != 1) error("string expected for library name"); else { Expression *e = args->tdata()[0]; e = e->semantic(sc); e = e->optimize(WANTvalue | WANTinterpret); args->tdata()[0] = e; if (e->op == TOKerror) goto Lnodecl; StringExp *se = e->toString(); if (!se) error("string expected for library name, not '%s'", e->toChars()); else if (global.params.verbose) { char *name = (char *)mem.malloc(se->len + 1); memcpy(name, se->string, se->len); name[se->len] = 0; printf("library %s\n", name); mem.free(name); } } goto Lnodecl; } #if IN_GCC else if (ident == Id::GNU_asm) { if (! args || args->dim != 2) error("identifier and string expected for asm name"); else { Expression *e; Declaration *d = NULL; StringExp *s = NULL; e = args->tdata()[0]; e = e->semantic(sc); if (e->op == TOKvar) { d = ((VarExp *)e)->var; if (! d->isFuncDeclaration() && ! d->isVarDeclaration()) d = NULL; } if (!d) error("first argument of GNU_asm must be a function or variable declaration"); e = args->tdata()[1]; e = e->semantic(sc); e = e->optimize(WANTvalue | WANTinterpret); e = e->toString(); if (e && ((StringExp *)e)->sz == 1) s = ((StringExp *)e); else error("second argument of GNU_asm must be a char string"); if (d && s) d->c_ident = Lexer::idPool((char*) s->string); } goto Lnodecl; } #endif #if DMDV2 else if (ident == Id::startaddress) { if (!args || args->dim != 1) error("function name expected for start address"); else { Expression *e = args->tdata()[0]; e = e->semantic(sc); e = e->optimize(WANTvalue | WANTinterpret); args->tdata()[0] = e; Dsymbol *sa = getDsymbol(e); if (!sa || !sa->isFuncDeclaration()) error("function name expected for start address, not '%s'", e->toChars()); } goto Lnodecl; } #endif #if TARGET_NET else if (ident == Lexer::idPool("assembly")) { } #endif // TARGET_NET else if (global.params.ignoreUnsupportedPragmas) { if (global.params.verbose) { /* Print unrecognized pragmas */ printf("pragma %s", ident->toChars()); if (args) { for (size_t i = 0; i < args->dim; i++) { Expression *e = args->tdata()[i]; e = e->semantic(sc); e = e->optimize(WANTvalue | WANTinterpret); if (i == 0) printf(" ("); else printf(","); printf("%s", e->toChars()); } if (args->dim) printf(")"); } printf("\n"); } goto Lnodecl; } else error("unrecognized pragma(%s)", ident->toChars()); if (decl) { for (unsigned i = 0; i < decl->dim; i++) { Dsymbol *s = decl->tdata()[i]; s->semantic(sc); } } return; Lnodecl: if (decl) error("pragma is missing closing ';'"); }
void tst_Lookup::simple_class_1() { const QByteArray source = "\n" "@interface Zoo {} +(id)alloc; -(id)init; @end\n" "@implementation Zoo +(id)alloc{} -(id)init{} -(void)dealloc{} @end\n"; Document::Ptr doc = Document::create("simple_class_1"); doc->setUtf8Source(source); doc->parse(); doc->check(); QVERIFY(doc->diagnosticMessages().isEmpty()); QCOMPARE(doc->globalSymbolCount(), 2U); Snapshot snapshot; snapshot.insert(doc); ObjCClass *iface = doc->globalSymbolAt(0)->asObjCClass(); QVERIFY(iface); QVERIFY(iface->isInterface()); QCOMPARE(iface->memberCount(), 2U); ObjCClass *impl = doc->globalSymbolAt(1)->asObjCClass(); QVERIFY(impl); QVERIFY(!impl->isInterface()); QCOMPARE(impl->memberCount(), 3U); Declaration *allocMethodIface = iface->memberAt(0)->asDeclaration(); QVERIFY(allocMethodIface); QVERIFY(allocMethodIface->name() && allocMethodIface->name()->identifier()); QCOMPARE(QLatin1String(allocMethodIface->name()->identifier()->chars()), QLatin1String("alloc")); ObjCMethod *allocMethodImpl = impl->memberAt(0)->asObjCMethod(); QVERIFY(allocMethodImpl); QVERIFY(allocMethodImpl->name() && allocMethodImpl->name()->identifier()); QCOMPARE(QLatin1String(allocMethodImpl->name()->identifier()->chars()), QLatin1String("alloc")); ObjCMethod *deallocMethod = impl->memberAt(2)->asObjCMethod(); QVERIFY(deallocMethod); QVERIFY(deallocMethod->name() && deallocMethod->name()->identifier()); QCOMPARE(QLatin1String(deallocMethod->name()->identifier()->chars()), QLatin1String("dealloc")); const LookupContext context(doc, snapshot); // check class resolving: ClassOrNamespace *klass = context.lookupType(impl->name(), impl->enclosingScope()); QVERIFY(klass != 0); QCOMPARE(klass->symbols().size(), 2); QVERIFY(klass->symbols().contains(iface)); QVERIFY(klass->symbols().contains(impl)); // check method resolving: QList<LookupItem> results = context.lookup(allocMethodImpl->name(), impl); QCOMPARE(results.size(), 2); QCOMPARE(results.at(0).declaration(), allocMethodIface); QCOMPARE(results.at(1).declaration(), allocMethodImpl); results = context.lookup(deallocMethod->name(), impl); QCOMPARE(results.size(), 1); QCOMPARE(results.at(0).declaration(), deallocMethod); }
Expression *TraitsExp::semantic(Scope *sc) { #if LOGSEMANTIC printf("TraitsExp::semantic() %s\n", toChars()); #endif if (ident != Id::compiles && ident != Id::isSame && ident != Id::identifier) { TemplateInstance::semanticTiargs(loc, sc, args, 1); } size_t dim = args ? args->dim : 0; Object *o; Declaration *d; FuncDeclaration *f; #define ISTYPE(cond) \ for (size_t i = 0; i < dim; i++) \ { Type *t = getType((Object *)args->data[i]); \ if (!t) \ goto Lfalse; \ if (!(cond)) \ goto Lfalse; \ } \ if (!dim) \ goto Lfalse; \ goto Ltrue; #define ISDSYMBOL(cond) \ for (size_t i = 0; i < dim; i++) \ { Dsymbol *s = getDsymbol((Object *)args->data[i]); \ if (!s) \ goto Lfalse; \ if (!(cond)) \ goto Lfalse; \ } \ if (!dim) \ goto Lfalse; \ goto Ltrue; if (ident == Id::isArithmetic) { ISTYPE(t->isintegral() || t->isfloating()) } else if (ident == Id::isFloating) { ISTYPE(t->isfloating()) } else if (ident == Id::isIntegral) { ISTYPE(t->isintegral()) } else if (ident == Id::isScalar) { ISTYPE(t->isscalar()) } else if (ident == Id::isUnsigned) { ISTYPE(t->isunsigned()) } else if (ident == Id::isAssociativeArray) { ISTYPE(t->toBasetype()->ty == Taarray) } else if (ident == Id::isStaticArray) { ISTYPE(t->toBasetype()->ty == Tsarray) } else if (ident == Id::isAbstractClass) { ISTYPE(t->toBasetype()->ty == Tclass && ((TypeClass *)t->toBasetype())->sym->isAbstract()) } else if (ident == Id::isFinalClass) { ISTYPE(t->toBasetype()->ty == Tclass && ((TypeClass *)t->toBasetype())->sym->storage_class & STCfinal) } else if (ident == Id::isAbstractFunction) { ISDSYMBOL((f = s->isFuncDeclaration()) != NULL && f->isAbstract()) } else if (ident == Id::isVirtualFunction) { ISDSYMBOL((f = s->isFuncDeclaration()) != NULL && f->isVirtual()) } else if (ident == Id::isFinalFunction) { ISDSYMBOL((f = s->isFuncDeclaration()) != NULL && f->isFinal()) } #if DMDV2 else if (ident == Id::isStaticFunction) { ISDSYMBOL((f = s->isFuncDeclaration()) != NULL && !f->needThis()) } else if (ident == Id::isRef) { ISDSYMBOL((d = s->isDeclaration()) != NULL && d->isRef()) } else if (ident == Id::isOut) { ISDSYMBOL((d = s->isDeclaration()) != NULL && d->isOut()) } else if (ident == Id::isLazy) { ISDSYMBOL((d = s->isDeclaration()) != NULL && d->storage_class & STClazy) } else if (ident == Id::identifier) { // Get identifier for symbol as a string literal // Specify 0 for the flags argument to semanticTiargs() so that // a symbol should not be folded to a constant. TemplateInstance::semanticTiargs(loc, sc, args, 0); if (dim != 1) goto Ldimerror; Object *o = (Object *)args->data[0]; Dsymbol *s = getDsymbol(o); if (!s || !s->ident) { error("argument %s has no identifier", o->toChars()); goto Lfalse; } StringExp *se = new StringExp(loc, s->ident->toChars()); return se->semantic(sc); } else if (ident == Id::parent) { if (dim != 1) goto Ldimerror; Object *o = (Object *)args->data[0]; Dsymbol *s = getDsymbol(o); if (s) s = s->toParent(); if (!s) { error("argument %s has no parent", o->toChars()); goto Lfalse; } return (new DsymbolExp(loc, s))->semantic(sc); } #endif else if (ident == Id::hasMember || ident == Id::getMember || ident == Id::getOverloads || ident == Id::getVirtualFunctions) { if (dim != 2) goto Ldimerror; Object *o = (Object *)args->data[0]; Expression *e = isExpression((Object *)args->data[1]); if (!e) { error("expression expected as second argument of __traits %s", ident->toChars()); goto Lfalse; } e = e->optimize(WANTvalue | WANTinterpret); if (e->op != TOKstring) { error("string expected as second argument of __traits %s instead of %s", ident->toChars(), e->toChars()); goto Lfalse; } StringExp *se = (StringExp *)e; se = se->toUTF8(sc); if (se->sz != 1) { error("string must be chars"); goto Lfalse; } Identifier *id = Lexer::idPool((char *)se->string); Type *t = isType(o); e = isExpression(o); Dsymbol *s = isDsymbol(o); if (t) e = typeDotIdExp(loc, t, id); else if (e) e = new DotIdExp(loc, e, id); else if (s) { e = new DsymbolExp(loc, s); e = new DotIdExp(loc, e, id); } else { error("invalid first argument"); goto Lfalse; } if (ident == Id::hasMember) { /* Take any errors as meaning it wasn't found */ e = e->trySemantic(sc); if (!e) { if (global.gag) global.errors++; goto Lfalse; } else goto Ltrue; } else if (ident == Id::getMember) { e = e->semantic(sc); return e; } else if (ident == Id::getVirtualFunctions || ident == Id::getOverloads) { unsigned errors = global.errors; Expression *ex = e; e = e->semantic(sc); if (errors < global.errors) error("%s cannot be resolved", ex->toChars()); /* Create tuple of functions of e */ //e->dump(0); Expressions *exps = new Expressions(); FuncDeclaration *f; if (e->op == TOKvar) { VarExp *ve = (VarExp *)e; f = ve->var->isFuncDeclaration(); } else if (e->op == TOKdotvar) { DotVarExp *dve = (DotVarExp *)e; f = dve->var->isFuncDeclaration(); } else f = NULL; Ptrait p; p.exps = exps; p.e1 = e; p.ident = ident; overloadApply(f, fptraits, &p); TupleExp *tup = new TupleExp(loc, exps); return tup->semantic(sc); } else assert(0); } else if (ident == Id::classInstanceSize) { if (dim != 1) goto Ldimerror; Object *o = (Object *)args->data[0]; Dsymbol *s = getDsymbol(o); ClassDeclaration *cd; if (!s || (cd = s->isClassDeclaration()) == NULL) { error("first argument is not a class"); goto Lfalse; } return new IntegerExp(loc, cd->structsize, Type::tsize_t); } else if (ident == Id::allMembers || ident == Id::derivedMembers) { if (dim != 1) goto Ldimerror; Object *o = (Object *)args->data[0]; Dsymbol *s = getDsymbol(o); ScopeDsymbol *sd; if (!s) { error("argument has no members"); goto Lfalse; } if ((sd = s->isScopeDsymbol()) == NULL) { error("%s %s has no members", s->kind(), s->toChars()); goto Lfalse; } Expressions *exps = new Expressions; while (1) { size_t dim = ScopeDsymbol::dim(sd->members); for (size_t i = 0; i < dim; i++) { Dsymbol *sm = ScopeDsymbol::getNth(sd->members, i); //printf("\t[%i] %s %s\n", i, sm->kind(), sm->toChars()); if (sm->ident) { //printf("\t%s\n", sm->ident->toChars()); char *str = sm->ident->toChars(); /* Skip if already present in exps[] */ for (size_t j = 0; j < exps->dim; j++) { StringExp *se2 = (StringExp *)exps->data[j]; if (strcmp(str, (char *)se2->string) == 0) goto Lnext; } StringExp *se = new StringExp(loc, str); exps->push(se); } Lnext: ; } ClassDeclaration *cd = sd->isClassDeclaration(); if (cd && cd->baseClass && ident == Id::allMembers) sd = cd->baseClass; // do again with base class else break; } #if DMDV1 Expression *e = new ArrayLiteralExp(loc, exps); #endif #if DMDV2 /* Making this a tuple is more flexible, as it can be statically unrolled. * To make an array literal, enclose __traits in [ ]: * [ __traits(allMembers, ...) ] */ Expression *e = new TupleExp(loc, exps); #endif e = e->semantic(sc); return e; } else if (ident == Id::compiles) { /* Determine if all the objects - types, expressions, or symbols - * compile without error */ if (!dim) goto Lfalse; for (size_t i = 0; i < dim; i++) { Object *o = (Object *)args->data[i]; Expression *e; unsigned errors = global.errors; global.gag++; Type *t = isType(o); if (t) { Dsymbol *s; t->resolve(loc, sc, &e, &t, &s); if (t) t->semantic(loc, sc); else if (e) { e = e->semantic(sc); e = e->optimize(WANTvalue); } } else { e = isExpression(o); if (e) { e = e->semantic(sc); e = e->optimize(WANTvalue); } } global.gag--; if (errors != global.errors) { global.errors = errors; goto Lfalse; } } goto Ltrue; } else if (ident == Id::isSame) { /* Determine if two symbols are the same */ if (dim != 2) goto Ldimerror; TemplateInstance::semanticTiargs(loc, sc, args, 0); Object *o1 = (Object *)args->data[0]; Object *o2 = (Object *)args->data[1]; Dsymbol *s1 = getDsymbol(o1); Dsymbol *s2 = getDsymbol(o2); //printf("isSame: %s, %s\n", o1->toChars(), o2->toChars()); #if 0 printf("o1: %p\n", o1); printf("o2: %p\n", o2); if (!s1) { Expression *ea = isExpression(o1); if (ea) printf("%s\n", ea->toChars()); Type *ta = isType(o1); if (ta) printf("%s\n", ta->toChars()); goto Lfalse; } else printf("%s %s\n", s1->kind(), s1->toChars()); #endif if (!s1 && !s2) { Expression *ea1 = isExpression(o1); Expression *ea2 = isExpression(o2); if (ea1 && ea2) { if (ea1->equals(ea2)) goto Ltrue; } } if (!s1 || !s2) goto Lfalse; s1 = s1->toAlias(); s2 = s2->toAlias(); if (s1 == s2) goto Ltrue; else goto Lfalse; } else { error("unrecognized trait %s", ident->toChars()); goto Lfalse; } return NULL; Lnottype: error("%s is not a type", o->toChars()); goto Lfalse; Ldimerror: error("wrong number of arguments %d", dim); goto Lfalse; Lfalse: return new IntegerExp(loc, 0, Type::tbool); Ltrue: return new IntegerExp(loc, 1, Type::tbool); }
void Output_Nested::operator()(Ruleset* r) { Selector* s = r->selector(); Block* b = r->block(); bool decls = false; // In case the extend visitor isn't called (if there are no @extend // directives in the entire document), check for placeholders here and // make sure they aren't output. // TODO: investigate why I decided to duplicate this logic in the extend visitor Selector_List* sl = static_cast<Selector_List*>(s); if (!ctx->extensions.size()) { Selector_List* new_sl = new (ctx->mem) Selector_List(sl->path(), sl->position()); for (size_t i = 0, L = sl->length(); i < L; ++i) { if (!(*sl)[i]->has_placeholder()) { *new_sl << (*sl)[i]; } } s = new_sl; sl = new_sl; r->selector(new_sl); } if (sl->length() == 0) return; if (b->has_non_hoistable()) { decls = true; indent(); if (source_comments) { stringstream ss; ss << "/* line " << r->position().line << ", " << r->path() << " */" << endl; append_singleline_part_to_buffer(ss.str()); indent(); } s->perform(this); append_multiline_part_to_buffer(" {\n"); ++indentation; for (size_t i = 0, L = b->length(); i < L; ++i) { Statement* stm = (*b)[i]; bool bPrintExpression = true; // Check print conditions if (typeid(*stm) == typeid(Declaration)) { Declaration* dec = static_cast<Declaration*>(stm); if (dec->value()->concrete_type() == Expression::STRING) { String_Constant* valConst = static_cast<String_Constant*>(dec->value()); string val(valConst->value()); if (val.empty()) { bPrintExpression = false; } } else if (dec->value()->concrete_type() == Expression::LIST) { List* list = static_cast<List*>(dec->value()); bool all_invisible = true; for (size_t list_i = 0, list_L = list->length(); list_i < list_L; ++list_i) { Expression* item = (*list)[list_i]; if (!item->is_invisible()) all_invisible = false; } if (all_invisible) bPrintExpression = false; } } // Print if OK if (!stm->is_hoistable() && bPrintExpression) { if (!stm->block()) indent(); stm->perform(this); append_multiline_part_to_buffer("\n"); } } --indentation; buffer.erase(buffer.length()-1); if (ctx) ctx->source_map.remove_line(); append_multiline_part_to_buffer(" }\n"); } if (b->has_hoistable()) { if (decls) ++indentation; // indent(); for (size_t i = 0, L = b->length(); i < L; ++i) { Statement* stm = (*b)[i]; if (stm->is_hoistable()) { stm->perform(this); } } if (decls) --indentation; } }
inline void debug_ast(AST_Node* node, std::string ind, Env* env) { if (node == 0) return; if (ind == "") std::cerr << "####################################################################\n"; if (dynamic_cast<Bubble*>(node)) { Bubble* bubble = dynamic_cast<Bubble*>(node); std::cerr << ind << "Bubble " << bubble; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " " << bubble->tabs(); std::cerr << std::endl; debug_ast(bubble->node(), ind + " ", env); } else if (dynamic_cast<Trace*>(node)) { Trace* trace = dynamic_cast<Trace*>(node); std::cerr << ind << "Trace " << trace; std::cerr << " (" << pstate_source_position(node) << ")" << " [name:" << trace->name() << "]" << std::endl; debug_ast(trace->block(), ind + " ", env); } else if (dynamic_cast<At_Root_Block*>(node)) { At_Root_Block* root_block = dynamic_cast<At_Root_Block*>(node); std::cerr << ind << "At_Root_Block " << root_block; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " " << root_block->tabs(); std::cerr << std::endl; debug_ast(root_block->expression(), ind + ":", env); debug_ast(root_block->block(), ind + " ", env); } else if (dynamic_cast<CommaSequence_Selector*>(node)) { CommaSequence_Selector* selector = dynamic_cast<CommaSequence_Selector*>(node); std::cerr << ind << "CommaSequence_Selector " << selector; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " <" << selector->hash() << ">"; std::cerr << " [@media:" << selector->media_block() << "]"; std::cerr << (selector->is_invisible() ? " [INVISIBLE]": " -"); std::cerr << (selector->has_placeholder() ? " [PLACEHOLDER]": " -"); std::cerr << (selector->is_optional() ? " [is_optional]": " -"); std::cerr << (selector->has_parent_ref() ? " [has-parent]": " -"); std::cerr << (selector->has_line_break() ? " [line-break]": " -"); std::cerr << (selector->has_line_feed() ? " [line-feed]": " -"); std::cerr << std::endl; for(auto i : selector->elements()) { debug_ast(i, ind + " ", env); } // } else if (dynamic_cast<Expression*>(node)) { // Expression* expression = dynamic_cast<Expression*>(node); // std::cerr << ind << "Expression " << expression << " " << expression->concrete_type() << std::endl; } else if (dynamic_cast<Parent_Selector*>(node)) { Parent_Selector* selector = dynamic_cast<Parent_Selector*>(node); std::cerr << ind << "Parent_Selector " << selector; // if (selector->not_selector()) cerr << " [in_declaration]"; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " <" << selector->hash() << ">"; std::cerr << " [" << (selector->is_real_parent_ref() ? "REAL" : "FAKE") << "]"; std::cerr << " <" << prettyprint(selector->pstate().token.ws_before()) << ">" << std::endl; // debug_ast(selector->selector(), ind + "->", env); } else if (dynamic_cast<Sequence_Selector*>(node)) { Sequence_Selector* selector = dynamic_cast<Sequence_Selector*>(node); std::cerr << ind << "Sequence_Selector " << selector << " (" << pstate_source_position(node) << ")" << " <" << selector->hash() << ">" << " [length:" << longToHex(selector->length()) << "]" << " [weight:" << longToHex(selector->specificity()) << "]" << " [@media:" << selector->media_block() << "]" << (selector->is_invisible() ? " [INVISIBLE]": " -") << (selector->has_placeholder() ? " [PLACEHOLDER]": " -") << (selector->is_optional() ? " [is_optional]": " -") << (selector->has_parent_ref() ? " [has parent]": " -") << (selector->has_line_feed() ? " [line-feed]": " -") << (selector->has_line_break() ? " [line-break]": " -") << " -- "; std::string del; switch (selector->combinator()) { case Sequence_Selector::PARENT_OF: del = ">"; break; case Sequence_Selector::PRECEDES: del = "~"; break; case Sequence_Selector::ADJACENT_TO: del = "+"; break; case Sequence_Selector::ANCESTOR_OF: del = " "; break; case Sequence_Selector::REFERENCE: del = "//"; break; } // if (del = "/") del += selector->reference()->perform(&to_string) + "/"; std::cerr << " <" << prettyprint(selector->pstate().token.ws_before()) << ">" << std::endl; debug_ast(selector->head(), ind + " " /* + "[" + del + "]" */, env); if (selector->tail()) { debug_ast(selector->tail(), ind + "{" + del + "}", env); } else if(del != " ") { std::cerr << ind << " |" << del << "| {trailing op}" << std::endl; } SourcesSet set = selector->sources(); // debug_sources_set(set, ind + " @--> "); } else if (dynamic_cast<SimpleSequence_Selector*>(node)) { SimpleSequence_Selector* selector = dynamic_cast<SimpleSequence_Selector*>(node); std::cerr << ind << "SimpleSequence_Selector " << selector; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " <" << selector->hash() << ">"; std::cerr << " [weight:" << longToHex(selector->specificity()) << "]"; std::cerr << " [@media:" << selector->media_block() << "]"; std::cerr << (selector->extended() ? " [extended]": " -"); std::cerr << (selector->is_optional() ? " [is_optional]": " -"); std::cerr << (selector->has_parent_ref() ? " [has-parent]": " -"); std::cerr << (selector->has_line_break() ? " [line-break]": " -"); std::cerr << (selector->has_line_feed() ? " [line-feed]": " -"); std::cerr << " <" << prettyprint(selector->pstate().token.ws_before()) << ">" << std::endl; for(auto i : selector->elements()) { debug_ast(i, ind + " ", env); } } else if (dynamic_cast<Wrapped_Selector*>(node)) { Wrapped_Selector* selector = dynamic_cast<Wrapped_Selector*>(node); std::cerr << ind << "Wrapped_Selector " << selector; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " <" << selector->hash() << ">"; std::cerr << " <<" << selector->ns_name() << ">>"; std::cerr << (selector->is_optional() ? " [is_optional]": " -"); std::cerr << (selector->has_parent_ref() ? " [has-parent]": " -"); std::cerr << (selector->has_line_break() ? " [line-break]": " -"); std::cerr << (selector->has_line_feed() ? " [line-feed]": " -"); std::cerr << std::endl; debug_ast(selector->selector(), ind + " () ", env); } else if (dynamic_cast<Pseudo_Selector*>(node)) { Pseudo_Selector* selector = dynamic_cast<Pseudo_Selector*>(node); std::cerr << ind << "Pseudo_Selector " << selector; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " <" << selector->hash() << ">"; std::cerr << " <<" << selector->ns_name() << ">>"; std::cerr << (selector->is_optional() ? " [is_optional]": " -"); std::cerr << (selector->has_parent_ref() ? " [has-parent]": " -"); std::cerr << (selector->has_line_break() ? " [line-break]": " -"); std::cerr << (selector->has_line_feed() ? " [line-feed]": " -"); std::cerr << std::endl; debug_ast(selector->expression(), ind + " <= ", env); } else if (dynamic_cast<Attribute_Selector*>(node)) { Attribute_Selector* selector = dynamic_cast<Attribute_Selector*>(node); std::cerr << ind << "Attribute_Selector " << selector; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " <" << selector->hash() << ">"; std::cerr << " <<" << selector->ns_name() << ">>"; std::cerr << (selector->is_optional() ? " [is_optional]": " -"); std::cerr << (selector->has_parent_ref() ? " [has-parent]": " -"); std::cerr << (selector->has_line_break() ? " [line-break]": " -"); std::cerr << (selector->has_line_feed() ? " [line-feed]": " -"); std::cerr << std::endl; debug_ast(selector->value(), ind + "[" + selector->matcher() + "] ", env); } else if (dynamic_cast<Class_Selector*>(node)) { Class_Selector* selector = dynamic_cast<Class_Selector*>(node); std::cerr << ind << "Class_Selector " << selector; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " <" << selector->hash() << ">"; std::cerr << " <<" << selector->ns_name() << ">>"; std::cerr << (selector->is_optional() ? " [is_optional]": " -"); std::cerr << (selector->has_parent_ref() ? " [has-parent]": " -"); std::cerr << (selector->has_line_break() ? " [line-break]": " -"); std::cerr << (selector->has_line_feed() ? " [line-feed]": " -"); std::cerr << std::endl; } else if (dynamic_cast<Id_Selector*>(node)) { Id_Selector* selector = dynamic_cast<Id_Selector*>(node); std::cerr << ind << "Id_Selector " << selector; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " <" << selector->hash() << ">"; std::cerr << " <<" << selector->ns_name() << ">>"; std::cerr << (selector->is_optional() ? " [is_optional]": " -"); std::cerr << (selector->has_parent_ref() ? " [has-parent]": " -"); std::cerr << (selector->has_line_break() ? " [line-break]": " -"); std::cerr << (selector->has_line_feed() ? " [line-feed]": " -"); std::cerr << std::endl; } else if (dynamic_cast<Element_Selector*>(node)) { Element_Selector* selector = dynamic_cast<Element_Selector*>(node); std::cerr << ind << "Element_Selector " << selector; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " <" << selector->hash() << ">"; std::cerr << " <<" << selector->ns_name() << ">>"; std::cerr << (selector->is_optional() ? " [is_optional]": " -"); std::cerr << (selector->has_parent_ref() ? " [has-parent]": " -"); std::cerr << (selector->has_line_break() ? " [line-break]": " -"); std::cerr << (selector->has_line_feed() ? " [line-feed]": " -"); std::cerr << " <" << prettyprint(selector->pstate().token.ws_before()) << ">"; std::cerr << std::endl; } else if (dynamic_cast<Placeholder_Selector*>(node)) { Placeholder_Selector* selector = dynamic_cast<Placeholder_Selector*>(node); std::cerr << ind << "Placeholder_Selector [" << selector->ns_name() << "] " << selector << " <" << selector->hash() << ">" << " [@media:" << selector->media_block() << "]" << (selector->is_optional() ? " [is_optional]": " -") << (selector->has_line_break() ? " [line-break]": " -") << (selector->has_line_feed() ? " [line-feed]": " -") << std::endl; } else if (dynamic_cast<Simple_Selector*>(node)) { Simple_Selector* selector = dynamic_cast<Simple_Selector*>(node); std::cerr << ind << "Simple_Selector " << selector; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << (selector->has_line_break() ? " [line-break]": " -") << (selector->has_line_feed() ? " [line-feed]": " -") << std::endl; } else if (dynamic_cast<Selector_Schema*>(node)) { Selector_Schema* selector = dynamic_cast<Selector_Schema*>(node); std::cerr << ind << "Selector_Schema " << selector; std::cerr << " (" << pstate_source_position(node) << ")" << (selector->at_root() && selector->at_root() ? " [@ROOT]" : "") << " [@media:" << selector->media_block() << "]" << (selector->has_line_break() ? " [line-break]": " -") << (selector->has_line_feed() ? " [line-feed]": " -") << std::endl; debug_ast(selector->contents(), ind + " "); // for(auto i : selector->elements()) { debug_ast(i, ind + " ", env); } } else if (dynamic_cast<Selector*>(node)) { Selector* selector = dynamic_cast<Selector*>(node); std::cerr << ind << "Selector " << selector; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << (selector->has_line_break() ? " [line-break]": " -") << (selector->has_line_feed() ? " [line-feed]": " -") << std::endl; } else if (dynamic_cast<Media_Query_Expression*>(node)) { Media_Query_Expression* block = dynamic_cast<Media_Query_Expression*>(node); std::cerr << ind << "Media_Query_Expression " << block; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << (block->is_interpolated() ? " [is_interpolated]": " -") << std::endl; debug_ast(block->feature(), ind + " feature) "); debug_ast(block->value(), ind + " value) "); } else if (dynamic_cast<Media_Query*>(node)) { Media_Query* block = dynamic_cast<Media_Query*>(node); std::cerr << ind << "Media_Query " << block; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << (block->is_negated() ? " [is_negated]": " -") << (block->is_restricted() ? " [is_restricted]": " -") << std::endl; debug_ast(block->media_type(), ind + " "); for(auto i : block->elements()) { debug_ast(i, ind + " ", env); } } else if (dynamic_cast<Media_Block*>(node)) { Media_Block* block = dynamic_cast<Media_Block*>(node); std::cerr << ind << "Media_Block " << block; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " " << block->tabs() << std::endl; debug_ast(block->media_queries(), ind + " =@ "); if (block->block()) for(auto i : block->block()->elements()) { debug_ast(i, ind + " ", env); } } else if (dynamic_cast<Supports_Block*>(node)) { Supports_Block* block = dynamic_cast<Supports_Block*>(node); std::cerr << ind << "Supports_Block " << block; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " " << block->tabs() << std::endl; debug_ast(block->condition(), ind + " =@ "); debug_ast(block->block(), ind + " <>"); } else if (dynamic_cast<Supports_Operator*>(node)) { Supports_Operator* block = dynamic_cast<Supports_Operator*>(node); std::cerr << ind << "Supports_Operator " << block; std::cerr << " (" << pstate_source_position(node) << ")" << std::endl; debug_ast(block->left(), ind + " left) "); debug_ast(block->right(), ind + " right) "); } else if (dynamic_cast<Supports_Negation*>(node)) { Supports_Negation* block = dynamic_cast<Supports_Negation*>(node); std::cerr << ind << "Supports_Negation " << block; std::cerr << " (" << pstate_source_position(node) << ")" << std::endl; debug_ast(block->condition(), ind + " condition) "); } else if (dynamic_cast<At_Root_Query*>(node)) { At_Root_Query* block = dynamic_cast<At_Root_Query*>(node); std::cerr << ind << "At_Root_Query " << block; std::cerr << " (" << pstate_source_position(node) << ")" << std::endl; debug_ast(block->feature(), ind + " feature) "); debug_ast(block->value(), ind + " value) "); } else if (dynamic_cast<Supports_Declaration*>(node)) { Supports_Declaration* block = dynamic_cast<Supports_Declaration*>(node); std::cerr << ind << "Supports_Declaration " << block; std::cerr << " (" << pstate_source_position(node) << ")" << std::endl; debug_ast(block->feature(), ind + " feature) "); debug_ast(block->value(), ind + " value) "); } else if (dynamic_cast<Block*>(node)) { Block* root_block = dynamic_cast<Block*>(node); std::cerr << ind << "Block " << root_block; std::cerr << " (" << pstate_source_position(node) << ")"; if (root_block->is_root()) std::cerr << " [root]"; std::cerr << " " << root_block->tabs() << std::endl; if (root_block->block()) for(auto i : root_block->block()->elements()) { debug_ast(i, ind + " ", env); } } else if (dynamic_cast<Warning*>(node)) { Warning* block = dynamic_cast<Warning*>(node); std::cerr << ind << "Warning " << block; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " " << block->tabs() << std::endl; debug_ast(block->message(), ind + " : "); } else if (dynamic_cast<Error*>(node)) { Error* block = dynamic_cast<Error*>(node); std::cerr << ind << "Error " << block; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " " << block->tabs() << std::endl; } else if (dynamic_cast<Debug*>(node)) { Debug* block = dynamic_cast<Debug*>(node); std::cerr << ind << "Debug " << block; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " " << block->tabs() << std::endl; debug_ast(block->value(), ind + " "); } else if (dynamic_cast<Comment*>(node)) { Comment* block = dynamic_cast<Comment*>(node); std::cerr << ind << "Comment " << block; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " " << block->tabs() << " <" << prettyprint(block->pstate().token.ws_before()) << ">" << std::endl; debug_ast(block->text(), ind + "// ", env); } else if (dynamic_cast<If*>(node)) { If* block = dynamic_cast<If*>(node); std::cerr << ind << "If " << block; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " " << block->tabs() << std::endl; debug_ast(block->predicate(), ind + " = "); debug_ast(block->block(), ind + " <>"); debug_ast(block->alternative(), ind + " ><"); } else if (dynamic_cast<Return*>(node)) { Return* block = dynamic_cast<Return*>(node); std::cerr << ind << "Return " << block; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " " << block->tabs() << std::endl; } else if (dynamic_cast<Extension*>(node)) { Extension* block = dynamic_cast<Extension*>(node); std::cerr << ind << "Extension " << block; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " " << block->tabs() << std::endl; debug_ast(block->selector(), ind + "-> ", env); } else if (dynamic_cast<Content*>(node)) { Content* block = dynamic_cast<Content*>(node); std::cerr << ind << "Content " << block; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " [@media:" << block->media_block() << "]"; std::cerr << " " << block->tabs() << std::endl; } else if (dynamic_cast<Import_Stub*>(node)) { Import_Stub* block = dynamic_cast<Import_Stub*>(node); std::cerr << ind << "Import_Stub " << block; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " [" << block->imp_path() << "] "; std::cerr << " " << block->tabs() << std::endl; } else if (dynamic_cast<Import*>(node)) { Import* block = dynamic_cast<Import*>(node); std::cerr << ind << "Import " << block; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " " << block->tabs() << std::endl; // std::vector<std::string> files_; for (auto imp : block->urls()) debug_ast(imp, ind + "@: ", env); debug_ast(block->media_queries(), ind + "@@ "); } else if (dynamic_cast<Assignment*>(node)) { Assignment* block = dynamic_cast<Assignment*>(node); std::cerr << ind << "Assignment " << block; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " <<" << block->variable() << ">> " << block->tabs() << std::endl; debug_ast(block->value(), ind + "=", env); } else if (dynamic_cast<Declaration*>(node)) { Declaration* block = dynamic_cast<Declaration*>(node); std::cerr << ind << "Declaration " << block; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " " << block->tabs() << std::endl; debug_ast(block->property(), ind + " prop: ", env); debug_ast(block->value(), ind + " value: ", env); debug_ast(block->block(), ind + " ", env); } else if (dynamic_cast<Keyframe_Rule*>(node)) { Keyframe_Rule* has_block = dynamic_cast<Keyframe_Rule*>(node); std::cerr << ind << "Keyframe_Rule " << has_block; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " " << has_block->tabs() << std::endl; if (has_block->selector()) debug_ast(has_block->selector(), ind + "@"); if (has_block->block()) for(auto i : has_block->block()->elements()) { debug_ast(i, ind + " ", env); } } else if (dynamic_cast<Directive*>(node)) { Directive* block = dynamic_cast<Directive*>(node); std::cerr << ind << "Directive " << block; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " [" << block->keyword() << "] " << block->tabs() << std::endl; debug_ast(block->selector(), ind + "~", env); debug_ast(block->value(), ind + "+", env); if (block->block()) for(auto i : block->block()->elements()) { debug_ast(i, ind + " ", env); } } else if (dynamic_cast<Each*>(node)) { Each* block = dynamic_cast<Each*>(node); std::cerr << ind << "Each " << block; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " " << block->tabs() << std::endl; if (block->block()) for(auto i : block->block()->elements()) { debug_ast(i, ind + " ", env); } } else if (dynamic_cast<For*>(node)) { For* block = dynamic_cast<For*>(node); std::cerr << ind << "For " << block; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " " << block->tabs() << std::endl; if (block->block()) for(auto i : block->block()->elements()) { debug_ast(i, ind + " ", env); } } else if (dynamic_cast<While*>(node)) { While* block = dynamic_cast<While*>(node); std::cerr << ind << "While " << block; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " " << block->tabs() << std::endl; if (block->block()) for(auto i : block->block()->elements()) { debug_ast(i, ind + " ", env); } } else if (dynamic_cast<Definition*>(node)) { Definition* block = dynamic_cast<Definition*>(node); std::cerr << ind << "Definition " << block; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " [name: " << block->name() << "] "; std::cerr << " [type: " << (block->type() == Sass::Definition::Type::MIXIN ? "Mixin " : "Function ") << "] "; // this seems to lead to segfaults some times? // std::cerr << " [signature: " << block->signature() << "] "; std::cerr << " [native: " << block->native_function() << "] "; std::cerr << " " << block->tabs() << std::endl; debug_ast(block->parameters(), ind + " params: ", env); if (block->block()) debug_ast(block->block(), ind + " ", env); } else if (dynamic_cast<Mixin_Call*>(node)) { Mixin_Call* block = dynamic_cast<Mixin_Call*>(node); std::cerr << ind << "Mixin_Call " << block << " " << block->tabs(); std::cerr << " [" << block->name() << "]"; std::cerr << " [has_content: " << block->has_content() << "] " << std::endl; debug_ast(block->arguments(), ind + " args: "); if (block->block()) debug_ast(block->block(), ind + " ", env); } else if (Ruleset* ruleset = dynamic_cast<Ruleset*>(node)) { std::cerr << ind << "Ruleset " << ruleset; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " [indent: " << ruleset->tabs() << "]"; std::cerr << (ruleset->is_invisible() ? " [INVISIBLE]" : ""); std::cerr << (ruleset->at_root() ? " [@ROOT]" : ""); std::cerr << (ruleset->is_root() ? " [root]" : ""); std::cerr << std::endl; debug_ast(ruleset->selector(), ind + ">"); debug_ast(ruleset->block(), ind + " "); } else if (dynamic_cast<Block*>(node)) { Block* block = dynamic_cast<Block*>(node); std::cerr << ind << "Block " << block; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << (block->is_invisible() ? " [INVISIBLE]" : ""); std::cerr << " [indent: " << block->tabs() << "]" << std::endl; for(auto i : block->elements()) { debug_ast(i, ind + " ", env); } } else if (dynamic_cast<Textual*>(node)) { Textual* expression = dynamic_cast<Textual*>(node); std::cerr << ind << "Textual "; if (expression->type() == Textual::NUMBER) std::cerr << " [NUMBER]"; else if (expression->type() == Textual::PERCENTAGE) std::cerr << " [PERCENTAGE]"; else if (expression->type() == Textual::DIMENSION) std::cerr << " [DIMENSION]"; else if (expression->type() == Textual::HEX) std::cerr << " [HEX]"; std::cerr << expression << " [" << expression->value() << "]"; std::cerr << " [interpolant: " << expression->is_interpolant() << "] "; if (expression->is_delayed()) std::cerr << " [delayed]"; std::cerr << std::endl; } else if (dynamic_cast<Variable*>(node)) { Variable* expression = dynamic_cast<Variable*>(node); std::cerr << ind << "Variable " << expression; std::cerr << " [interpolant: " << expression->is_interpolant() << "] "; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " [" << expression->name() << "]" << std::endl; std::string name(expression->name()); if (env && env->has(name)) debug_ast(static_cast<Expression*>((*env)[name]), ind + " -> ", env); } else if (dynamic_cast<Function_Call_Schema*>(node)) { Function_Call_Schema* expression = dynamic_cast<Function_Call_Schema*>(node); std::cerr << ind << "Function_Call_Schema " << expression; std::cerr << " [interpolant: " << expression->is_interpolant() << "] "; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << "" << std::endl; debug_ast(expression->name(), ind + "name: ", env); debug_ast(expression->arguments(), ind + " args: ", env); } else if (dynamic_cast<Function_Call*>(node)) { Function_Call* expression = dynamic_cast<Function_Call*>(node); std::cerr << ind << "Function_Call " << expression; std::cerr << " [interpolant: " << expression->is_interpolant() << "] "; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " [" << expression->name() << "]"; if (expression->is_delayed()) std::cerr << " [delayed]"; if (expression->is_interpolant()) std::cerr << " [interpolant]"; std::cerr << std::endl; debug_ast(expression->arguments(), ind + " args: ", env); } else if (dynamic_cast<Arguments*>(node)) { Arguments* expression = dynamic_cast<Arguments*>(node); std::cerr << ind << "Arguments " << expression; if (expression->is_delayed()) std::cerr << " [delayed]"; std::cerr << " (" << pstate_source_position(node) << ")"; if (expression->has_named_arguments()) std::cerr << " [has_named_arguments]"; if (expression->has_rest_argument()) std::cerr << " [has_rest_argument]"; if (expression->has_keyword_argument()) std::cerr << " [has_keyword_argument]"; std::cerr << std::endl; for(auto i : expression->elements()) { debug_ast(i, ind + " ", env); } } else if (dynamic_cast<Argument*>(node)) { Argument* expression = dynamic_cast<Argument*>(node); std::cerr << ind << "Argument " << expression; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " [" << expression->value() << "]"; std::cerr << " [name: " << expression->name() << "] "; std::cerr << " [rest: " << expression->is_rest_argument() << "] "; std::cerr << " [keyword: " << expression->is_keyword_argument() << "] " << std::endl; debug_ast(expression->value(), ind + " value: ", env); } else if (dynamic_cast<Parameters*>(node)) { Parameters* expression = dynamic_cast<Parameters*>(node); std::cerr << ind << "Parameters " << expression; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " [has_optional: " << expression->has_optional_parameters() << "] "; std::cerr << " [has_rest: " << expression->has_rest_parameter() << "] "; std::cerr << std::endl; for(auto i : expression->elements()) { debug_ast(i, ind + " ", env); } } else if (dynamic_cast<Parameter*>(node)) { Parameter* expression = dynamic_cast<Parameter*>(node); std::cerr << ind << "Parameter " << expression; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " [name: " << expression->name() << "] "; std::cerr << " [default: " << expression->default_value() << "] "; std::cerr << " [rest: " << expression->is_rest_parameter() << "] " << std::endl; } else if (dynamic_cast<Unary_Expression*>(node)) { Unary_Expression* expression = dynamic_cast<Unary_Expression*>(node); std::cerr << ind << "Unary_Expression " << expression; std::cerr << " [interpolant: " << expression->is_interpolant() << "] "; std::cerr << " [delayed: " << expression->is_delayed() << "] "; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " [" << expression->type() << "]" << std::endl; debug_ast(expression->operand(), ind + " operand: ", env); } else if (dynamic_cast<Binary_Expression*>(node)) { Binary_Expression* expression = dynamic_cast<Binary_Expression*>(node); std::cerr << ind << "Binary_Expression " << expression; if (expression->is_interpolant()) std::cerr << " [is interpolant] "; if (expression->is_left_interpolant()) std::cerr << " [left interpolant] "; if (expression->is_right_interpolant()) std::cerr << " [right interpolant] "; std::cerr << " [delayed: " << expression->is_delayed() << "] "; std::cerr << " [ws_before: " << expression->op().ws_before << "] "; std::cerr << " [ws_after: " << expression->op().ws_after << "] "; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " [" << expression->type_name() << "]" << std::endl; debug_ast(expression->left(), ind + " left: ", env); debug_ast(expression->right(), ind + " right: ", env); } else if (dynamic_cast<Map*>(node)) { Map* expression = dynamic_cast<Map*>(node); std::cerr << ind << "Map " << expression; std::cerr << " [interpolant: " << expression->is_interpolant() << "] "; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " [Hashed]" << std::endl; for (auto i : expression->elements()) { debug_ast(i.first, ind + " key: "); debug_ast(i.second, ind + " val: "); } } else if (dynamic_cast<List*>(node)) { List* expression = dynamic_cast<List*>(node); std::cerr << ind << "List " << expression; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " (" << expression->length() << ") " << (expression->separator() == SASS_COMMA ? "Comma " : expression->separator() == SASS_HASH ? "Map" : "Space ") << " [delayed: " << expression->is_delayed() << "] " << " [interpolant: " << expression->is_interpolant() << "] " << " [listized: " << expression->from_selector() << "] " << " [arglist: " << expression->is_arglist() << "] " << " [hash: " << expression->hash() << "] " << std::endl; for(auto i : expression->elements()) { debug_ast(i, ind + " ", env); } } else if (dynamic_cast<Content*>(node)) { Content* expression = dynamic_cast<Content*>(node); std::cerr << ind << "Content " << expression; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " [@media:" << expression->media_block() << "]"; std::cerr << " [Statement]" << std::endl; } else if (dynamic_cast<Boolean*>(node)) { Boolean* expression = dynamic_cast<Boolean*>(node); std::cerr << ind << "Boolean " << expression; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " [interpolant: " << expression->is_interpolant() << "] "; std::cerr << " [" << expression->value() << "]" << std::endl; } else if (dynamic_cast<Color*>(node)) { Color* expression = dynamic_cast<Color*>(node); std::cerr << ind << "Color " << expression; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " [delayed: " << expression->is_delayed() << "] "; std::cerr << " [interpolant: " << expression->is_interpolant() << "] "; std::cerr << " [" << expression->r() << ":" << expression->g() << ":" << expression->b() << "@" << expression->a() << "]" << std::endl; } else if (dynamic_cast<Number*>(node)) { Number* expression = dynamic_cast<Number*>(node); std::cerr << ind << "Number " << expression; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " [interpolant: " << expression->is_interpolant() << "] "; std::cerr << " [" << expression->value() << expression->unit() << "]" << " [hash: " << expression->hash() << "] " << std::endl; } else if (dynamic_cast<String_Quoted*>(node)) { String_Quoted* expression = dynamic_cast<String_Quoted*>(node); std::cerr << ind << "String_Quoted " << expression; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " [" << prettyprint(expression->value()) << "]"; if (expression->is_delayed()) std::cerr << " [delayed]"; if (expression->is_interpolant()) std::cerr << " [interpolant]"; if (expression->quote_mark()) std::cerr << " [quote_mark: " << expression->quote_mark() << "]"; std::cerr << " <" << prettyprint(expression->pstate().token.ws_before()) << ">" << std::endl; } else if (dynamic_cast<String_Constant*>(node)) { String_Constant* expression = dynamic_cast<String_Constant*>(node); std::cerr << ind << "String_Constant " << expression; if (expression->concrete_type()) { std::cerr << " " << expression->concrete_type(); } std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " [" << prettyprint(expression->value()) << "]"; if (expression->is_delayed()) std::cerr << " [delayed]"; if (expression->is_interpolant()) std::cerr << " [interpolant]"; std::cerr << " <" << prettyprint(expression->pstate().token.ws_before()) << ">" << std::endl; } else if (dynamic_cast<String_Schema*>(node)) { String_Schema* expression = dynamic_cast<String_Schema*>(node); std::cerr << ind << "String_Schema " << expression; std::cerr << " " << expression->concrete_type(); if (expression->is_delayed()) std::cerr << " [delayed]"; if (expression->is_interpolant()) std::cerr << " [is interpolant]"; if (expression->has_interpolant()) std::cerr << " [has interpolant]"; if (expression->is_left_interpolant()) std::cerr << " [left interpolant] "; if (expression->is_right_interpolant()) std::cerr << " [right interpolant] "; std::cerr << " <" << prettyprint(expression->pstate().token.ws_before()) << ">" << std::endl; for(auto i : expression->elements()) { debug_ast(i, ind + " ", env); } } else if (dynamic_cast<String*>(node)) { String* expression = dynamic_cast<String*>(node); std::cerr << ind << "String " << expression; std::cerr << " " << expression->concrete_type(); std::cerr << " (" << pstate_source_position(node) << ")"; if (expression->is_interpolant()) std::cerr << " [interpolant]"; std::cerr << " <" << prettyprint(expression->pstate().token.ws_before()) << ">" << std::endl; } else if (dynamic_cast<Expression*>(node)) { Expression* expression = dynamic_cast<Expression*>(node); std::cerr << ind << "Expression " << expression; std::cerr << " (" << pstate_source_position(node) << ")"; switch (expression->concrete_type()) { case Expression::Concrete_Type::NONE: std::cerr << " [NONE]"; break; case Expression::Concrete_Type::BOOLEAN: std::cerr << " [BOOLEAN]"; break; case Expression::Concrete_Type::NUMBER: std::cerr << " [NUMBER]"; break; case Expression::Concrete_Type::COLOR: std::cerr << " [COLOR]"; break; case Expression::Concrete_Type::STRING: std::cerr << " [STRING]"; break; case Expression::Concrete_Type::LIST: std::cerr << " [LIST]"; break; case Expression::Concrete_Type::MAP: std::cerr << " [MAP]"; break; case Expression::Concrete_Type::SELECTOR: std::cerr << " [SELECTOR]"; break; case Expression::Concrete_Type::NULL_VAL: std::cerr << " [NULL_VAL]"; break; case Expression::Concrete_Type::C_WARNING: std::cerr << " [C_WARNING]"; break; case Expression::Concrete_Type::C_ERROR: std::cerr << " [C_ERROR]"; break; case Expression::Concrete_Type::NUM_TYPES: std::cerr << " [NUM_TYPES]"; break; } std::cerr << std::endl; } else if (dynamic_cast<Has_Block*>(node)) { Has_Block* has_block = dynamic_cast<Has_Block*>(node); std::cerr << ind << "Has_Block " << has_block; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " " << has_block->tabs() << std::endl; if (has_block->block()) for(auto i : has_block->block()->elements()) { debug_ast(i, ind + " ", env); } } else if (dynamic_cast<Statement*>(node)) { Statement* statement = dynamic_cast<Statement*>(node); std::cerr << ind << "Statement " << statement; std::cerr << " (" << pstate_source_position(node) << ")"; std::cerr << " " << statement->tabs() << std::endl; } if (ind == "") std::cerr << "####################################################################\n"; }
void PragmaDeclaration::semantic(Scope *sc) { // Should be merged with PragmaStatement #if IN_LLVM Pragma llvm_internal = LLVMnone; std::string arg1str; #endif //printf("\tPragmaDeclaration::semantic '%s'\n",toChars()); if (ident == Id::msg) { if (args) { for (size_t i = 0; i < args->dim; i++) { Expression *e = (*args)[i]; e = e->semantic(sc); if (e->op != TOKerror) e = e->optimize(WANTvalue | WANTinterpret); if (e->op == TOKerror) { errorSupplemental(loc, "while evaluating pragma(msg, %s)", (*args)[i]->toChars()); return; } StringExp *se = e->toString(); if (se) { fprintf(stdmsg, "%.*s", (int)se->len, (char *)se->string); } else fprintf(stdmsg, "%s", e->toChars()); } fprintf(stdmsg, "\n"); } goto Lnodecl; } else if (ident == Id::lib) { if (!args || args->dim != 1) error("string expected for library name"); else { Expression *e = (*args)[0]; e = e->semantic(sc); e = e->optimize(WANTvalue | WANTinterpret); (*args)[0] = e; if (e->op == TOKerror) goto Lnodecl; StringExp *se = e->toString(); if (!se) error("string expected for library name, not '%s'", e->toChars()); else if (global.params.verbose) { char *name = (char *)mem.malloc(se->len + 1); memcpy(name, se->string, se->len); name[se->len] = 0; printf("library %s\n", name); mem.free(name); } } goto Lnodecl; } #if IN_GCC else if (ident == Id::GNU_asm) { if (! args || args->dim != 2) error("identifier and string expected for asm name"); else { Expression *e; Declaration *d = NULL; StringExp *s = NULL; e = (*args)[0]; e = e->semantic(sc); if (e->op == TOKvar) { d = ((VarExp *)e)->var; if (! d->isFuncDeclaration() && ! d->isVarDeclaration()) d = NULL; } if (!d) error("first argument of GNU_asm must be a function or variable declaration"); e = (*args)[1]; e = e->semantic(sc); e = e->optimize(WANTvalue | WANTinterpret); e = e->toString(); if (e && ((StringExp *)e)->sz == 1) s = ((StringExp *)e); else error("second argument of GNU_asm must be a character string"); if (d && s) d->c_ident = Lexer::idPool((char*) s->string); } goto Lnodecl; } #endif #if DMDV2 else if (ident == Id::startaddress) { if (!args || args->dim != 1) error("function name expected for start address"); else { Expression *e = (*args)[0]; e = e->semantic(sc); e = e->optimize(WANTvalue | WANTinterpret); (*args)[0] = e; Dsymbol *sa = getDsymbol(e); if (!sa || !sa->isFuncDeclaration()) error("function name expected for start address, not '%s'", e->toChars()); } goto Lnodecl; } #endif #if TARGET_NET else if (ident == Lexer::idPool("assembly")) { } #endif // TARGET_NET #if IN_LLVM else if ((llvm_internal = DtoGetPragma(sc, this, arg1str)) != LLVMnone) { // nothing to do anymore } #endif else if (global.params.ignoreUnsupportedPragmas) { if (global.params.verbose) { /* Print unrecognized pragmas */ printf("pragma %s", ident->toChars()); if (args) { for (size_t i = 0; i < args->dim; i++) { Expression *e = (*args)[i]; // ignore errors in ignored pragmas. global.gag++; unsigned errors_save = global.errors; e = e->semantic(sc); e = e->optimize(WANTvalue | WANTinterpret); if (i == 0) printf(" ("); else printf(","); printf("%s", e->toChars()); // restore error state. global.gag--; global.errors = errors_save; } if (args->dim) printf(")"); } printf("\n"); } } else error("unrecognized pragma(%s)", ident->toChars()); Ldecl: if (decl) { for (size_t i = 0; i < decl->dim; i++) { Dsymbol *s = (*decl)[i]; s->semantic(sc); #if IN_LLVM DtoCheckPragma(this, s, llvm_internal, arg1str); #endif } } return; Lnodecl: if (decl) { error("pragma is missing closing ';'"); goto Ldecl; // do them anyway, to avoid segfaults. } }
/** * Loads LX task structure from XCSoar task structure * @param decl The declaration */ static bool LoadTask(LX::Declaration &lxDevice_Declaration, const Declaration &declaration) { if (declaration.Size() > 10) return false; if (declaration.Size() < 2) return false; memset((void*)lxDevice_Declaration.unknown1, 0, sizeof(lxDevice_Declaration.unknown1)); BrokenDate DeclDate; DeclDate.day = 1; DeclDate.month = 1; DeclDate.year = 2010; if (DeclDate.day > 0 && DeclDate.day < 32 && DeclDate.month > 0 && DeclDate.month < 13) { lxDevice_Declaration.dayinput = (unsigned char)DeclDate.day; lxDevice_Declaration.monthinput = (unsigned char)DeclDate.month; int iCentury = DeclDate.year / 100; // Todo: if no gps fix, use system time iCentury *= 100; lxDevice_Declaration.yearinput = (unsigned char)(DeclDate.year - iCentury); } else { lxDevice_Declaration.dayinput = (unsigned char)1; lxDevice_Declaration.monthinput = (unsigned char)1; lxDevice_Declaration.yearinput = (unsigned char)10; } lxDevice_Declaration.dayuser = lxDevice_Declaration.dayinput; lxDevice_Declaration.monthuser = lxDevice_Declaration.monthinput; lxDevice_Declaration.yearuser = lxDevice_Declaration.yearinput; lxDevice_Declaration.taskid = 0; lxDevice_Declaration.numtps = declaration.Size(); for (unsigned i = 0; i < LX::NUMTPS; i++) { if (i == 0) { // takeoff lxDevice_Declaration.tptypes[i] = 3; lxDevice_Declaration.Latitudes[i] = 0; lxDevice_Declaration.Longitudes[i] = 0; copy_space_padded(lxDevice_Declaration.WaypointNames[i], _T("TAKEOFF"), sizeof(lxDevice_Declaration.WaypointNames[i])); } else if (i <= declaration.Size()) { lxDevice_Declaration.tptypes[i] = 1; lxDevice_Declaration.Longitudes[i] = AngleToLX(declaration.GetLocation(i - 1).longitude); lxDevice_Declaration.Latitudes[i] = AngleToLX(declaration.GetLocation(i - 1).latitude); copy_space_padded(lxDevice_Declaration.WaypointNames[i], declaration.GetName(i - 1), sizeof(lxDevice_Declaration.WaypointNames[i])); } else if (i == declaration.Size() + 1) { // landing lxDevice_Declaration.tptypes[i] = 2; lxDevice_Declaration.Longitudes[i] = 0; lxDevice_Declaration.Latitudes[i] = 0; copy_space_padded(lxDevice_Declaration.WaypointNames[i], _T("LANDING"), sizeof(lxDevice_Declaration.WaypointNames[i])); } else { // unused lxDevice_Declaration.tptypes[i] = 0; lxDevice_Declaration.Longitudes[i] = 0; lxDevice_Declaration.Latitudes[i] = 0; memset((void*)lxDevice_Declaration.WaypointNames[i], 0, 9); } } return true; }
Dsymbol *ScopeDsymbol::search(Loc loc, Identifier *ident, int flags) { //printf("%s->ScopeDsymbol::search(ident='%s', flags=x%x)\n", toChars(), ident->toChars(), flags); //if (strcmp(ident->toChars(),"c") == 0) *(char*)0=0; // Look in symbols declared in this module Dsymbol *s = symtab ? symtab->lookup(ident) : NULL; //printf("\ts = %p, imports = %p, %d\n", s, imports, imports ? imports->dim : 0); if (s) { //printf("\ts = '%s.%s'\n",toChars(),s->toChars()); } else if (imports) { OverloadSet *a = NULL; // Look in imported modules for (size_t i = 0; i < imports->dim; i++) { Dsymbol *ss = (*imports)[i]; Dsymbol *s2; // If private import, don't search it if (flags & 1 && prots[i] == PROTprivate) continue; //printf("\tscanning import '%s', prots = %d, isModule = %p, isImport = %p\n", ss->toChars(), prots[i], ss->isModule(), ss->isImport()); /* Don't find private members if ss is a module */ s2 = ss->search(loc, ident, ss->isModule() ? 1 : 0); if (!s) s = s2; else if (s2 && s != s2) { if (s->toAlias() == s2->toAlias()) { /* After following aliases, we found the same * symbol, so it's not an ambiguity. But if one * alias is deprecated or less accessible, prefer * the other. */ if (s->isDeprecated() || s2->prot() > s->prot() && s2->prot() != PROTnone) s = s2; } else { /* Two imports of the same module should be regarded as * the same. */ Import *i1 = s->isImport(); Import *i2 = s2->isImport(); if (!(i1 && i2 && (i1->mod == i2->mod || (!i1->parent->isImport() && !i2->parent->isImport() && i1->ident->equals(i2->ident)) ) ) ) { /* If both s2 and s are overloadable (though we only * need to check s once) */ if (s2->isOverloadable() && (a || s->isOverloadable())) { if (!a) a = new OverloadSet(); /* Don't add to a[] if s2 is alias of previous sym */ for (size_t j = 0; j < a->a.dim; j++) { Dsymbol *s3 = a->a[j]; if (s2->toAlias() == s3->toAlias()) { if (s3->isDeprecated() || s2->prot() > s3->prot() && s2->prot() != PROTnone) a->a[j] = s2; goto Lcontinue; } } a->push(s2); Lcontinue: continue; } if (flags & 4) // if return NULL on ambiguity return NULL; if (!(flags & 2)) ScopeDsymbol::multiplyDefined(loc, s, s2); break; } } } } /* Build special symbol if we had multiple finds */ if (a) { assert(s); a->push(s); s = a; } if (s) { Declaration *d = s->isDeclaration(); if (d && d->protection == PROTprivate && !d->parent->isTemplateMixin() && !(flags & 2)) error(loc, "%s is private", d->toPrettyChars()); } } return s; }
inline void debug_ast(AST_Node* node, string ind = "", Env* env = 0) { if (node == 0) return; if (ind == "") cerr << "####################################################################\n"; if (dynamic_cast<Bubble*>(node)) { Bubble* bubble = dynamic_cast<Bubble*>(node); cerr << ind << "Bubble " << bubble; cerr << " (" << pstate_source_position(node) << ")"; cerr << " " << bubble->tabs(); cerr << endl; } else if (dynamic_cast<At_Root_Block*>(node)) { At_Root_Block* root_block = dynamic_cast<At_Root_Block*>(node); cerr << ind << "At_Root_Block " << root_block; cerr << " (" << pstate_source_position(node) << ")"; cerr << " " << root_block->tabs(); cerr << endl; if (root_block->block()) for(auto i : root_block->block()->elements()) { debug_ast(i, ind + " ", env); } } else if (dynamic_cast<Selector_List*>(node)) { Selector_List* selector = dynamic_cast<Selector_List*>(node); cerr << ind << "Selector_List " << selector; cerr << " (" << pstate_source_position(node) << ")"; cerr << " [block:" << selector->last_block() << "]"; cerr << (selector->last_block() && selector->last_block()->is_root() ? " [root]" : ""); cerr << " [@media:" << selector->media_block() << "]"; cerr << (selector->is_optional() ? " [is_optional]": " -"); cerr << (selector->has_line_break() ? " [line-break]": " -"); cerr << (selector->has_line_feed() ? " [line-feed]": " -"); cerr << endl; for(auto i : selector->elements()) { debug_ast(i, ind + " ", env); } // } else if (dynamic_cast<Expression*>(node)) { // Expression* expression = dynamic_cast<Expression*>(node); // cerr << ind << "Expression " << expression << " " << expression->concrete_type() << endl; } else if (dynamic_cast<Parent_Selector*>(node)) { Parent_Selector* selector = dynamic_cast<Parent_Selector*>(node); cerr << ind << "Parent_Selector " << selector; cerr << " (" << pstate_source_position(node) << ")"; cerr << " <" << prettyprint(selector->pstate().token.ws_before()) << ">" << endl; debug_ast(selector->selector(), ind + "->", env); } else if (dynamic_cast<Complex_Selector*>(node)) { Complex_Selector* selector = dynamic_cast<Complex_Selector*>(node); cerr << ind << "Complex_Selector " << selector << " (" << pstate_source_position(node) << ")" << " [block:" << selector->last_block() << "]" << " [weight:" << longToHex(selector->specificity()) << "]" << (selector->last_block() && selector->last_block()->is_root() ? " [root]" : "") << " [@media:" << selector->media_block() << "]" << (selector->is_optional() ? " [is_optional]": " -") << (selector->has_line_break() ? " [line-break]": " -") << (selector->has_line_feed() ? " [line-feed]": " -") << " -> "; switch (selector->combinator()) { case Complex_Selector::PARENT_OF: cerr << "{>}"; break; case Complex_Selector::PRECEDES: cerr << "{~}"; break; case Complex_Selector::ADJACENT_TO: cerr << "{+}"; break; case Complex_Selector::ANCESTOR_OF: cerr << "{ }"; break; } cerr << " <" << prettyprint(selector->pstate().token.ws_before()) << ">" << endl; debug_ast(selector->head(), ind + " ", env); debug_ast(selector->tail(), ind + "-", env); } else if (dynamic_cast<Compound_Selector*>(node)) { Compound_Selector* selector = dynamic_cast<Compound_Selector*>(node); cerr << ind << "Compound_Selector " << selector; cerr << " (" << pstate_source_position(node) << ")"; cerr << " [block:" << selector->last_block() << "]"; cerr << " [weight:" << longToHex(selector->specificity()) << "]"; // cerr << (selector->last_block() && selector->last_block()->is_root() ? " [root]" : ""); cerr << " [@media:" << selector->media_block() << "]"; cerr << (selector->is_optional() ? " [is_optional]": " -"); cerr << (selector->has_line_break() ? " [line-break]": " -"); cerr << (selector->has_line_feed() ? " [line-feed]": " -"); cerr << " <" << prettyprint(selector->pstate().token.ws_before()) << ">" << endl; for(auto i : selector->elements()) { debug_ast(i, ind + " ", env); } } else if (dynamic_cast<Propset*>(node)) { Propset* selector = dynamic_cast<Propset*>(node); cerr << ind << "Propset " << selector; cerr << " (" << pstate_source_position(node) << ")"; cerr << " " << selector->tabs() << endl; if (selector->block()) for(auto i : selector->block()->elements()) { debug_ast(i, ind + " ", env); } } else if (dynamic_cast<Wrapped_Selector*>(node)) { Wrapped_Selector* selector = dynamic_cast<Wrapped_Selector*>(node); cerr << ind << "Wrapped_Selector " << selector; cerr << " (" << pstate_source_position(node) << ")"; cerr << " <<" << selector->name() << ">>" << (selector->has_line_break() ? " [line-break]": " -") << (selector->has_line_feed() ? " [line-feed]": " -") << endl; debug_ast(selector->selector(), ind + " () ", env); } else if (dynamic_cast<Pseudo_Selector*>(node)) { Pseudo_Selector* selector = dynamic_cast<Pseudo_Selector*>(node); cerr << ind << "Pseudo_Selector " << selector; cerr << " (" << pstate_source_position(node) << ")"; cerr << " <<" << selector->name() << ">>" << (selector->has_line_break() ? " [line-break]": " -") << (selector->has_line_feed() ? " [line-feed]": " -") << endl; debug_ast(selector->expression(), ind + " <= ", env); } else if (dynamic_cast<Attribute_Selector*>(node)) { Attribute_Selector* selector = dynamic_cast<Attribute_Selector*>(node); cerr << ind << "Attribute_Selector " << selector; cerr << " (" << pstate_source_position(node) << ")"; cerr << " <<" << selector->name() << ">>" << (selector->has_line_break() ? " [line-break]": " -") << (selector->has_line_feed() ? " [line-feed]": " -") << endl; debug_ast(selector->value(), ind + "[" + selector->matcher() + "] ", env); } else if (dynamic_cast<Selector_Qualifier*>(node)) { Selector_Qualifier* selector = dynamic_cast<Selector_Qualifier*>(node); cerr << ind << "Selector_Qualifier " << selector; cerr << " (" << pstate_source_position(node) << ")"; cerr << " <<" << selector->name() << ">>" << (selector->has_line_break() ? " [line-break]": " -") << (selector->has_line_feed() ? " [line-feed]": " -") << endl; } else if (dynamic_cast<Type_Selector*>(node)) { Type_Selector* selector = dynamic_cast<Type_Selector*>(node); cerr << ind << "Type_Selector " << selector; cerr << " (" << pstate_source_position(node) << ")"; cerr << " <<" << selector->name() << ">>" << (selector->has_line_break() ? " [line-break]": " -") << " <" << prettyprint(selector->pstate().token.ws_before()) << ">" << endl; } else if (dynamic_cast<Selector_Placeholder*>(node)) { Selector_Placeholder* selector = dynamic_cast<Selector_Placeholder*>(node); cerr << ind << "Selector_Placeholder [" << selector->name() << "] " << selector << " [block:" << selector->last_block() << "]" << " [@media:" << selector->media_block() << "]" << (selector->is_optional() ? " [is_optional]": " -") << (selector->has_line_break() ? " [line-break]": " -") << (selector->has_line_feed() ? " [line-feed]": " -") << endl; } else if (dynamic_cast<Selector_Reference*>(node)) { Selector_Reference* selector = dynamic_cast<Selector_Reference*>(node); cerr << ind << "Selector_Reference " << selector; cerr << " (" << pstate_source_position(node) << ")"; cerr << " @ref " << selector->selector() << endl; } else if (dynamic_cast<Simple_Selector*>(node)) { Simple_Selector* selector = dynamic_cast<Simple_Selector*>(node); cerr << ind << "Simple_Selector " << selector; cerr << " (" << pstate_source_position(node) << ")"; cerr << (selector->has_line_break() ? " [line-break]": " -") << (selector->has_line_feed() ? " [line-feed]": " -") << endl; } else if (dynamic_cast<Selector_Schema*>(node)) { Selector_Schema* selector = dynamic_cast<Selector_Schema*>(node); cerr << ind << "Selector_Schema " << selector; cerr << " (" << pstate_source_position(node) << ")"; cerr << " [block:" << selector->last_block() << "]" << (selector->last_block() && selector->last_block()->is_root() ? " [root]" : "") << " [@media:" << selector->media_block() << "]" << (selector->has_line_break() ? " [line-break]": " -") << (selector->has_line_feed() ? " [line-feed]": " -") << endl; debug_ast(selector->contents(), ind + " "); // for(auto i : selector->elements()) { debug_ast(i, ind + " ", env); } } else if (dynamic_cast<Selector*>(node)) { Selector* selector = dynamic_cast<Selector*>(node); cerr << ind << "Selector " << selector; cerr << " (" << pstate_source_position(node) << ")"; cerr << (selector->has_line_break() ? " [line-break]": " -") << (selector->has_line_feed() ? " [line-feed]": " -") << endl; } else if (dynamic_cast<Media_Query_Expression*>(node)) { Media_Query_Expression* block = dynamic_cast<Media_Query_Expression*>(node); cerr << ind << "Media_Query_Expression " << block; cerr << " (" << pstate_source_position(node) << ")"; cerr << (block->is_interpolated() ? " [is_interpolated]": " -") << endl; debug_ast(block->feature(), ind + " f) "); debug_ast(block->value(), ind + " v) "); } else if (dynamic_cast<Media_Query*>(node)) { Media_Query* block = dynamic_cast<Media_Query*>(node); cerr << ind << "Media_Query " << block; cerr << " (" << pstate_source_position(node) << ")"; cerr << (block->is_negated() ? " [is_negated]": " -") << (block->is_restricted() ? " [is_restricted]": " -") << endl; debug_ast(block->media_type(), ind + " "); for(auto i : block->elements()) { debug_ast(i, ind + " ", env); } } else if (dynamic_cast<Media_Block*>(node)) { Media_Block* block = dynamic_cast<Media_Block*>(node); cerr << ind << "Media_Block " << block; cerr << " (" << pstate_source_position(node) << ")"; cerr << " " << block->tabs() << endl; debug_ast(block->media_queries(), ind + " =@ "); debug_ast(block->selector(), ind + " -@ "); if (block->block()) for(auto i : block->block()->elements()) { debug_ast(i, ind + " ", env); } } else if (dynamic_cast<Feature_Block*>(node)) { Feature_Block* block = dynamic_cast<Feature_Block*>(node); cerr << ind << "Feature_Block " << block; cerr << " (" << pstate_source_position(node) << ")"; cerr << " " << block->tabs() << endl; if (block->block()) for(auto i : block->block()->elements()) { debug_ast(i, ind + " ", env); } } else if (dynamic_cast<Block*>(node)) { Block* root_block = dynamic_cast<Block*>(node); cerr << ind << "Block " << root_block; cerr << " (" << pstate_source_position(node) << ")"; if (root_block->is_root()) cerr << " [root]"; cerr << " " << root_block->tabs() << endl; if (root_block->block()) for(auto i : root_block->block()->elements()) { debug_ast(i, ind + " ", env); } } else if (dynamic_cast<Warning*>(node)) { Warning* block = dynamic_cast<Warning*>(node); cerr << ind << "Warning " << block; cerr << " (" << pstate_source_position(node) << ")"; cerr << " " << block->tabs() << endl; } else if (dynamic_cast<Error*>(node)) { Error* block = dynamic_cast<Error*>(node); cerr << ind << "Error " << block; cerr << " (" << pstate_source_position(node) << ")"; cerr << " " << block->tabs() << endl; } else if (dynamic_cast<Debug*>(node)) { Debug* block = dynamic_cast<Debug*>(node); cerr << ind << "Debug " << block; cerr << " (" << pstate_source_position(node) << ")"; cerr << " " << block->tabs() << endl; } else if (dynamic_cast<Comment*>(node)) { Comment* block = dynamic_cast<Comment*>(node); cerr << ind << "Comment " << block; cerr << " (" << pstate_source_position(node) << ")"; cerr << " " << block->tabs() << " <" << prettyprint(block->pstate().token.ws_before()) << ">" << endl; debug_ast(block->text(), ind + "// ", env); } else if (dynamic_cast<If*>(node)) { If* block = dynamic_cast<If*>(node); cerr << ind << "If " << block; cerr << " (" << pstate_source_position(node) << ")"; cerr << " " << block->tabs() << endl; } else if (dynamic_cast<Return*>(node)) { Return* block = dynamic_cast<Return*>(node); cerr << ind << "Return " << block; cerr << " (" << pstate_source_position(node) << ")"; cerr << " " << block->tabs() << endl; } else if (dynamic_cast<Extension*>(node)) { Extension* block = dynamic_cast<Extension*>(node); cerr << ind << "Extension " << block; cerr << " (" << pstate_source_position(node) << ")"; cerr << " " << block->tabs() << endl; debug_ast(block->selector(), ind + "-> ", env); } else if (dynamic_cast<Content*>(node)) { Content* block = dynamic_cast<Content*>(node); cerr << ind << "Content " << block; cerr << " (" << pstate_source_position(node) << ")"; cerr << " " << block->tabs() << endl; } else if (dynamic_cast<Import_Stub*>(node)) { Import_Stub* block = dynamic_cast<Import_Stub*>(node); cerr << ind << "Import_Stub " << block; cerr << " (" << pstate_source_position(node) << ")"; cerr << " " << block->tabs() << endl; } else if (dynamic_cast<Import*>(node)) { Import* block = dynamic_cast<Import*>(node); cerr << ind << "Import " << block; cerr << " (" << pstate_source_position(node) << ")"; cerr << " " << block->tabs() << endl; // vector<string> files_; for (auto imp : block->urls()) debug_ast(imp, "@ ", env); } else if (dynamic_cast<Assignment*>(node)) { Assignment* block = dynamic_cast<Assignment*>(node); cerr << ind << "Assignment " << block; cerr << " (" << pstate_source_position(node) << ")"; cerr << " <<" << block->variable() << ">> " << block->tabs() << endl; debug_ast(block->value(), ind + "=", env); } else if (dynamic_cast<Declaration*>(node)) { Declaration* block = dynamic_cast<Declaration*>(node); cerr << ind << "Declaration " << block; cerr << " (" << pstate_source_position(node) << ")"; cerr << " " << block->tabs() << endl; debug_ast(block->property(), ind + " prop: ", env); debug_ast(block->value(), ind + " value: ", env); } else if (dynamic_cast<Keyframe_Rule*>(node)) { Keyframe_Rule* has_block = dynamic_cast<Keyframe_Rule*>(node); cerr << ind << "Keyframe_Rule " << has_block; cerr << " (" << pstate_source_position(node) << ")"; cerr << " " << has_block->tabs() << endl; if (has_block->selector()) debug_ast(has_block->selector(), ind + "@"); if (has_block->block()) for(auto i : has_block->block()->elements()) { debug_ast(i, ind + " ", env); } } else if (dynamic_cast<At_Rule*>(node)) { At_Rule* block = dynamic_cast<At_Rule*>(node); cerr << ind << "At_Rule " << block; cerr << " (" << pstate_source_position(node) << ")"; cerr << " [" << block->keyword() << "] " << block->tabs() << endl; debug_ast(block->value(), ind + "+", env); debug_ast(block->selector(), ind + "~", env); if (block->block()) for(auto i : block->block()->elements()) { debug_ast(i, ind + " ", env); } } else if (dynamic_cast<Each*>(node)) { Each* block = dynamic_cast<Each*>(node); cerr << ind << "Each " << block; cerr << " (" << pstate_source_position(node) << ")"; cerr << " " << block->tabs() << endl; if (block->block()) for(auto i : block->block()->elements()) { debug_ast(i, ind + " ", env); } } else if (dynamic_cast<For*>(node)) { For* block = dynamic_cast<For*>(node); cerr << ind << "For " << block; cerr << " (" << pstate_source_position(node) << ")"; cerr << " " << block->tabs() << endl; if (block->block()) for(auto i : block->block()->elements()) { debug_ast(i, ind + " ", env); } } else if (dynamic_cast<While*>(node)) { While* block = dynamic_cast<While*>(node); cerr << ind << "While " << block; cerr << " (" << pstate_source_position(node) << ")"; cerr << " " << block->tabs() << endl; if (block->block()) for(auto i : block->block()->elements()) { debug_ast(i, ind + " ", env); } } else if (dynamic_cast<Definition*>(node)) { Definition* block = dynamic_cast<Definition*>(node); cerr << ind << "Definition " << block; cerr << " (" << pstate_source_position(node) << ")"; cerr << " " << block->tabs() << endl; if (block->block()) for(auto i : block->block()->elements()) { debug_ast(i, ind + " ", env); } } else if (dynamic_cast<Mixin_Call*>(node)) { Mixin_Call* block = dynamic_cast<Mixin_Call*>(node); cerr << ind << "Mixin_Call " << block << " " << block->tabs() << endl; if (block->block()) for(auto i : block->block()->elements()) { debug_ast(i, ind + " ", env); } } else if (dynamic_cast<Ruleset*>(node)) { Ruleset* ruleset = dynamic_cast<Ruleset*>(node); cerr << ind << "Ruleset " << ruleset; cerr << " (" << pstate_source_position(node) << ")"; cerr << " " << ruleset->tabs() << endl; debug_ast(ruleset->selector(), ind + " "); if (ruleset->block()) for(auto i : ruleset->block()->elements()) { debug_ast(i, ind + " ", env); } } else if (dynamic_cast<Block*>(node)) { Block* block = dynamic_cast<Block*>(node); cerr << ind << "Block " << block; cerr << " (" << pstate_source_position(node) << ")"; cerr << " " << block->tabs() << endl; for(auto i : block->elements()) { debug_ast(i, ind + " ", env); } } else if (dynamic_cast<Textual*>(node)) { Textual* expression = dynamic_cast<Textual*>(node); cerr << ind << "Textual "; if (expression->type() == Textual::NUMBER) cerr << " [NUMBER]"; else if (expression->type() == Textual::PERCENTAGE) cerr << " [PERCENTAGE]"; else if (expression->type() == Textual::DIMENSION) cerr << " [DIMENSION]"; else if (expression->type() == Textual::HEX) cerr << " [HEX]"; cerr << expression << " [" << expression->value() << "]" << endl; } else if (dynamic_cast<Variable*>(node)) { Variable* expression = dynamic_cast<Variable*>(node); cerr << ind << "Variable " << expression; cerr << " (" << pstate_source_position(node) << ")"; cerr << " [" << expression->name() << "]" << endl; string name(expression->name()); if (env && env->has(name)) debug_ast(static_cast<Expression*>((*env)[name]), ind + " -> ", env); } else if (dynamic_cast<Function_Call_Schema*>(node)) { Function_Call_Schema* expression = dynamic_cast<Function_Call_Schema*>(node); cerr << ind << "Function_Call_Schema " << expression; cerr << " (" << pstate_source_position(node) << ")"; cerr << "" << endl; debug_ast(expression->name(), ind + "name: ", env); debug_ast(expression->arguments(), ind + " args: ", env); } else if (dynamic_cast<Function_Call*>(node)) { Function_Call* expression = dynamic_cast<Function_Call*>(node); cerr << ind << "Function_Call " << expression; cerr << " (" << pstate_source_position(node) << ")"; cerr << " [" << expression->name() << "]" << endl; debug_ast(expression->arguments(), ind + " args: ", env); } else if (dynamic_cast<Arguments*>(node)) { Arguments* expression = dynamic_cast<Arguments*>(node); cerr << ind << "Arguments " << expression; cerr << " (" << pstate_source_position(node) << ")"; cerr << endl; for(auto i : expression->elements()) { debug_ast(i, ind + " ", env); } } else if (dynamic_cast<Argument*>(node)) { Argument* expression = dynamic_cast<Argument*>(node); cerr << ind << "Argument " << expression; cerr << " (" << pstate_source_position(node) << ")"; cerr << " [" << expression->value() << "]" << endl; debug_ast(expression->value(), ind + " value: ", env); } else if (dynamic_cast<Unary_Expression*>(node)) { Unary_Expression* expression = dynamic_cast<Unary_Expression*>(node); cerr << ind << "Unary_Expression " << expression; cerr << " (" << pstate_source_position(node) << ")"; cerr << " [" << expression->type() << "]" << endl; debug_ast(expression->operand(), ind + " operand: ", env); } else if (dynamic_cast<Binary_Expression*>(node)) { Binary_Expression* expression = dynamic_cast<Binary_Expression*>(node); cerr << ind << "Binary_Expression " << expression; cerr << " (" << pstate_source_position(node) << ")"; cerr << " [" << expression->type() << "]" << endl; debug_ast(expression->left(), ind + " left: ", env); debug_ast(expression->right(), ind + " right: ", env); } else if (dynamic_cast<Map*>(node)) { Map* expression = dynamic_cast<Map*>(node); cerr << ind << "Map " << expression; cerr << " (" << pstate_source_position(node) << ")"; cerr << " [Hashed]" << endl; } else if (dynamic_cast<List*>(node)) { List* expression = dynamic_cast<List*>(node); cerr << ind << "List " << expression; cerr << " (" << pstate_source_position(node) << ")"; cerr << " (" << expression->length() << ") " << (expression->separator() == Sass::List::Separator::COMMA ? "Comma " : "Space ") << " [delayed: " << expression->is_delayed() << "] " << " [interpolant: " << expression->is_interpolant() << "] " << endl; for(auto i : expression->elements()) { debug_ast(i, ind + " ", env); } } else if (dynamic_cast<Content*>(node)) { Content* expression = dynamic_cast<Content*>(node); cerr << ind << "Content " << expression; cerr << " (" << pstate_source_position(node) << ")"; cerr << " [Statement]" << endl; } else if (dynamic_cast<Boolean*>(node)) { Boolean* expression = dynamic_cast<Boolean*>(node); cerr << ind << "Boolean " << expression; cerr << " (" << pstate_source_position(node) << ")"; cerr << " [" << expression->value() << "]" << endl; } else if (dynamic_cast<Color*>(node)) { Color* expression = dynamic_cast<Color*>(node); cerr << ind << "Color " << expression; cerr << " (" << pstate_source_position(node) << ")"; cerr << " [" << expression->r() << ":" << expression->g() << ":" << expression->b() << "@" << expression->a() << "]" << endl; } else if (dynamic_cast<Number*>(node)) { Number* expression = dynamic_cast<Number*>(node); cerr << ind << "Number " << expression; cerr << " (" << pstate_source_position(node) << ")"; cerr << " [" << expression->value() << expression->unit() << "]" << endl; } else if (dynamic_cast<String_Quoted*>(node)) { String_Quoted* expression = dynamic_cast<String_Quoted*>(node); cerr << ind << "String_Quoted : " << expression; cerr << " (" << pstate_source_position(node) << ")"; cerr << " [" << prettyprint(expression->value()) << "]" << (expression->is_delayed() ? " {delayed}" : "") << (expression->sass_fix_1291() ? " {sass_fix_1291}" : "") << (expression->quote_mark() != 0 ? " {qm:" + string(1, expression->quote_mark()) + "}" : "") << " <" << prettyprint(expression->pstate().token.ws_before()) << ">" << endl; } else if (dynamic_cast<String_Constant*>(node)) { String_Constant* expression = dynamic_cast<String_Constant*>(node); cerr << ind << "String_Constant : " << expression; cerr << " (" << pstate_source_position(node) << ")"; cerr << " [" << prettyprint(expression->value()) << "]" << (expression->is_delayed() ? " {delayed}" : "") << (expression->sass_fix_1291() ? " {sass_fix_1291}" : "") << " <" << prettyprint(expression->pstate().token.ws_before()) << ">" << endl; } else if (dynamic_cast<String_Schema*>(node)) { String_Schema* expression = dynamic_cast<String_Schema*>(node); cerr << ind << "String_Schema " << expression; cerr << " (" << pstate_source_position(node) << ")"; cerr << " " << expression->concrete_type() << (expression->has_interpolants() ? " {has_interpolants}" : "") << endl; for(auto i : expression->elements()) { debug_ast(i, ind + " ", env); } } else if (dynamic_cast<String*>(node)) { String* expression = dynamic_cast<String*>(node); cerr << ind << "String " << expression; cerr << " (" << pstate_source_position(node) << ")"; cerr << expression->concrete_type() << " " << (expression->sass_fix_1291() ? "{sass_fix_1291}" : "") << endl; } else if (dynamic_cast<Expression*>(node)) { Expression* expression = dynamic_cast<Expression*>(node); cerr << ind << "Expression " << expression; cerr << " (" << pstate_source_position(node) << ")"; switch (expression->concrete_type()) { case Expression::Concrete_Type::NONE: cerr << " [NONE]"; break; case Expression::Concrete_Type::BOOLEAN: cerr << " [BOOLEAN]"; break; case Expression::Concrete_Type::NUMBER: cerr << " [NUMBER]"; break; case Expression::Concrete_Type::COLOR: cerr << " [COLOR]"; break; case Expression::Concrete_Type::STRING: cerr << " [STRING]"; break; case Expression::Concrete_Type::LIST: cerr << " [LIST]"; break; case Expression::Concrete_Type::MAP: cerr << " [MAP]"; break; case Expression::Concrete_Type::SELECTOR: cerr << " [SELECTOR]"; break; case Expression::Concrete_Type::NULL_VAL: cerr << " [NULL_VAL]"; break; case Expression::Concrete_Type::NUM_TYPES: cerr << " [NUM_TYPES]"; break; } cerr << endl; } else if (dynamic_cast<Has_Block*>(node)) { Has_Block* has_block = dynamic_cast<Has_Block*>(node); cerr << ind << "Has_Block " << has_block; cerr << " (" << pstate_source_position(node) << ")"; cerr << " " << has_block->tabs() << endl; if (has_block->block()) for(auto i : has_block->block()->elements()) { debug_ast(i, ind + " ", env); } } else if (dynamic_cast<Statement*>(node)) { Statement* statement = dynamic_cast<Statement*>(node); cerr << ind << "Statement " << statement; cerr << " (" << pstate_source_position(node) << ")"; cerr << " " << statement->tabs() << endl; } if (ind == "") cerr << "####################################################################\n"; }