Пример #1
0
VALUE rb_ary_new_with_len(long len) {
  VALUE ary = INT2FIX(len);
  VALUE block = push_block();
  ary = rb_class_new_instance(1, &ary, rb_cArray);
  pop_block(block);
  return ary;
}
Пример #2
0
static inline int execute_if (node *stmt, exec_env *env)
{
	int ret;
	value val;

	ret = eval_expression(&val, stmt->left, env);
	if(ret  < 0) {
		return ret;
	} else {
		ret = 0;
	}
	if(is_true(&val)) {
		ret = push_block(env, stmt->right);
		if(ret >= 0) {
			env->skip_advance = 1;
			return 0;
		}
		env->error.code = ERROR_BAD_ALLOC;
		env->error.line = stmt->loc.line;
		env->error.col  = stmt->loc.col;
		env->error.file = env->lib->label;
		env->error.static_msg = "unable to push block.";

		return ret;
	}
	return 1;
}
Пример #3
0
static void decision_tree(
    unsigned int s, unsigned int e, char *var, void (*leaf)(unsigned int))
{
    if ( s == (e-1) )
    {
        (*leaf)(s);
        return;
    }

    push_block("If", "And(%s, 0x%02x)", var, (e-s)/2);
    decision_tree((s+e)/2, e, var, leaf);
    pop_block();
    push_block("Else", NULL);
    decision_tree(s, (s+e)/2, var, leaf);
    pop_block();
}
Пример #4
0
int Message_Unit::recover_ptr_body(Unit_Message *ptr_data) {
	if (!ptr_data->ptr_data) return CALL_RETURN;

	if (ptr_data->data_type == Unit_Message::TYPE_DATA_BUFFER) {
		push_block(ptr_data->pool_gid, (Block_Buffer *)ptr_data->ptr_data);
		return CALL_RETURN;
	}

	return CALL_CONTINUE;
}
Пример #5
0
void blockchain::create_genesis_block() {

    genesis_block_.header_.prev_hash = "0000000000000000000000000000000000000000000000000000000000000000";
    genesis_block_.header_.timestamp = get_now_timestamp();
    genesis_block_.header_.tx_count = 1;
    genesis_block_.header_.difficulty = 1;

    genesis_block_.header_.hash = to_sha256(genesis_block_.to_json());

    push_block(genesis_block_);
}
Пример #6
0
Файл: astree.c Проект: mtnash/oc
int handlefunction(astree node, FILE* outfile){
    astree type = node->first;
    astree ident = node->first->first;
    astree param = node->first->next->first;
    bitset_t newattrs = bitlookup(type->symbol); 
    node->attrs = newattrs;
    cstring funcname = peek_stringtable(ident->lexinfo);

    sym_noderef lookup = search_sym_table(ident,gident_tbl);
    if (lookup != NULL){
        if (lookup->attributes & ATTR_PROTOTYPE){
            //found previous func declaration, it's a prototype
            if (lookup->attributes == ((newattrs | ATTR_PROTOTYPE))){
                if(paramcheck(param,lookup->nextparam,funcname)){
                    return 1;
                }
            } else {
                print_attributes(stdout,(ATTR_PROTOTYPE + ATTR_BOOL));
                eprintf("\n");
                print_attributes(stdout,(newattrs|ATTR_PROTOTYPE));
                eprintf("\n");
                //func declaration does not match prototype's type
                eprintf(
            "prototype's type does not match function declaration %s\n",
                        funcname);
            }
        } else {
            //found previous func declaration, it's not a prototype
            eprintf(
            "redeclaring function %s at line %d\n",
            peek_stringtable(ident->lexinfo),ident->linenr-1);
            eprintf(
            "(previously declared at line %d)\n",lookup->linenr-1);
            return 1;
        }
    } else {
        ident->attrs = ATTR_FUNCTION | bitlookup(type->symbol);
        sym_noderef temp = intern_sym_table(ident,gident_tbl,outfile);
        push_block(gblock_stk);
        for(;param != NULL; param = param->next){
            param->first->attrs = bitlookup(param->symbol) | ATTR_PARAM;
            param->first->blocknr = gblock_stk->top->blocknr;
            temp->nextparam = 
            intern_sym_table(param->first,gident_tbl,outfile);
            temp = temp->nextparam;
        }
        pop_idents(gident_tbl,gblock_stk->top->blocknr);
        pop_block(gblock_stk);
    }
    return 0;
}
Пример #7
0
void database::debug_update( const fc::variant_object& update )
{
   block_id_type head_id = head_block_id();
   auto it = _node_property_object.debug_updates.find( head_id );
   if( it == _node_property_object.debug_updates.end() )
      it = _node_property_object.debug_updates.emplace( head_id, std::vector< fc::variant_object >() ).first;
   it->second.emplace_back( update );

   optional<signed_block> head_block = fetch_block_by_id( head_id );
   FC_ASSERT( head_block.valid() );

   // What the last block does has been changed by adding to node_property_object, so we have to re-apply it
   pop_block();
   push_block( *head_block );
}
Пример #8
0
/* checks a block and includes it in the database with synchronization, ruturs non-zero value in case of error */
int xdag_sync_add_block(struct xdag_block *b, void *conn)
{
	int res, ttl = b->field[0].transport_header >> 8 & 0xff;

	res = xdag_add_block(b);
	if (res >= 0) {
		xdag_sync_pop_block(b);
		if (res > 0 && ttl > 2) {
			b->field[0].transport_header = ttl << 8;
			xdag_send_packet(b, (void*)((uintptr_t)conn | 1l));
		}
	} else if (g_xdag_sync_on && ((res = -res) & 0xf) == 5) {
		res = (res >> 4) & 0xf;
		if (push_block(b, conn, res, ttl)) {
			struct sync_block **p, *q;
			uint64_t *hash = b->field[res].hash;
			time_t t = time(0);

			pthread_mutex_lock(&g_sync_hash_mutex);
 
begin:
			for (p = get_list_r(hash); (q = *p); p = &q->next_r) {
				if (!memcmp(hash, q->hash, sizeof(xdag_hashlow_t))) {
					if (t - q->t < REQ_PERIOD) {
						pthread_mutex_unlock(&g_sync_hash_mutex);
						return 0;
					}

					q->t = t;
					hash = q->b.field[q->nfield].hash;

					goto begin;
				}
			}

			pthread_mutex_unlock(&g_sync_hash_mutex);
			
			xdag_request_block(hash, (void*)(uintptr_t)1l);
			
			xdag_info("ReqBlk: %016llx%016llx%016llx%016llx", hash[3], hash[2], hash[1], hash[0]);
		}
	}
Пример #9
0
signed_block database::_generate_block(
   fc::time_point_sec when,
   witness_id_type witness_id,
   const fc::ecc::private_key& block_signing_private_key
   )
{
   try {
   uint32_t skip = get_node_properties().skip_flags;
   uint32_t slot_num = get_slot_at_time( when );
   FC_ASSERT( slot_num > 0 );
   witness_id_type scheduled_witness = get_scheduled_witness( slot_num );
   FC_ASSERT( scheduled_witness == witness_id );

   const auto& witness_obj = witness_id(*this);

   if( !(skip & skip_witness_signature) )
      FC_ASSERT( witness_obj.signing_key == block_signing_private_key.get_public_key() );

   static const size_t max_block_header_size = fc::raw::pack_size( signed_block_header() ) + 4;
   auto maximum_block_size = get_global_properties().parameters.maximum_block_size;
   size_t total_block_size = max_block_header_size;

   signed_block pending_block;

   //
   // The following code throws away existing pending_tx_session and
   // rebuilds it by re-applying pending transactions.
   //
   // This rebuild is necessary because pending transactions' validity
   // and semantics may have changed since they were received, because
   // time-based semantics are evaluated based on the current block
   // time.  These changes can only be reflected in the database when
   // the value of the "when" variable is known, which means we need to
   // re-apply pending transactions in this method.
   //
   _pending_tx_session.reset();
   _pending_tx_session = _undo_db.start_undo_session();

   uint64_t postponed_tx_count = 0;
   // pop pending state (reset to head block state)
   for( const processed_transaction& tx : _pending_tx )
   {
      size_t new_total_size = total_block_size + fc::raw::pack_size( tx );

      // postpone transaction if it would make block too big
      if( new_total_size >= maximum_block_size )
      {
         postponed_tx_count++;
         continue;
      }

      try
      {
         auto temp_session = _undo_db.start_undo_session();
         processed_transaction ptx = _apply_transaction( tx );
         temp_session.merge();

         // We have to recompute pack_size(ptx) because it may be different
         // than pack_size(tx) (i.e. if one or more results increased
         // their size)
         total_block_size += fc::raw::pack_size( ptx );
         pending_block.transactions.push_back( ptx );
      }
      catch ( const fc::exception& e )
      {
         // Do nothing, transaction will not be re-applied
         wlog( "Transaction was not processed while generating block due to ${e}", ("e", e) );
         wlog( "The transaction was ${t}", ("t", tx) );
      }
   }
   if( postponed_tx_count > 0 )
   {
      wlog( "Postponed ${n} transactions due to block size limit", ("n", postponed_tx_count) );
   }

   _pending_tx_session.reset();

   // We have temporarily broken the invariant that
   // _pending_tx_session is the result of applying _pending_tx, as
   // _pending_tx now consists of the set of postponed transactions.
   // However, the push_block() call below will re-create the
   // _pending_tx_session.

   pending_block.previous = head_block_id();
   pending_block.timestamp = when;
   pending_block.transaction_merkle_root = pending_block.calculate_merkle_root();
   pending_block.witness = witness_id;

   if( !(skip & skip_witness_signature) )
      pending_block.sign( block_signing_private_key );

   // TODO:  Move this to _push_block() so session is restored.
   if( !(skip & skip_block_size_check) )
   {
      FC_ASSERT( fc::raw::pack_size(pending_block) <= get_global_properties().parameters.maximum_block_size );
   }

   push_block( pending_block, skip );

   return pending_block;
} FC_CAPTURE_AND_RETHROW( (witness_id) ) }
Пример #10
0
int FIAL_interpret (struct FIAL_exec_env *env)
{
	block *b = NULL;
	node *stmt = NULL;

	if(!env || !env->block_stack)
		return -1;
	if(!env->block_stack->stmt)
		return 1;


	for(;;) {
		b = env->block_stack;
		stmt = b->stmt->left;

		assert(stmt);
		switch(stmt->type) {
		case AST_VAR_DECL:
			ER(declare_variable(stmt, env));
			break;
		case AST_ASSIGN:
			ER(assign_variable(stmt, env));
			break;
		case AST_IF:
			ER(execute_if(stmt, env));
			break;
		case AST_BLOCK:
			ER(push_block(env, stmt));
			env->skip_advance = 1;
			break;
		case AST_CALL_A:
			ER(execute_call_A(stmt, env));
			break;
		case AST_CALL_B:
			ER(execute_call_B(stmt, env));
			break;
		case AST_BREAK:
			ER(execute_break(stmt, env));
			break;
		case AST_CONTINUE:
			ER(execute_continue(stmt, env));
			break;
		default:
			assert(0);
			/*is this an error?  I could just skip unknown
			 * statements...*/
			break;
		}
		if(!env->block_stack)
			break;
		if(env->skip_advance)
			env->skip_advance = 0;
		else
			env->block_stack->stmt = env->block_stack->stmt->right;
		while(!env->block_stack->stmt) {
			pop_block(env);
			if(!env->block_stack) {
				return 0;
			}
			assert(env->block_stack->stmt);
			env->block_stack->stmt = env->block_stack->stmt->right;
		}
	}
	return 0;
}
Пример #11
0
int main(int argc, char **argv)
{
    unsigned int slot, dev, intx, link, cpu, max_cpus = HVM_MAX_VCPUS;

    /* Extract optional maximum-cpu specification from invocation name. */
    sscanf(argv[0], "%*[^0-9]%u", &max_cpus); /* e.g., ./mk_dsdt15 */

    /**** DSDT DefinitionBlock start ****/
    /* (we append to existing DSDT definition block) */
    indent_level++;

    /**** Processor start ****/
    push_block("Scope", "\\_SB");

    /* MADT checksum */
    stmt("OperationRegion", "MSUM, SystemMemory, \\_SB.MSUA, 1");
    push_block("Field", "MSUM, ByteAcc, NoLock, Preserve");
    indent(); printf("MSU, 8\n");
    pop_block();

    /* Define processor objects and control methods. */
    for ( cpu = 0; cpu < max_cpus; cpu++)
    {
        push_block("Processor", "PR%02X, %d, 0x0000b010, 0x06", cpu, cpu);

        stmt("Name", "_HID, \"ACPI0007\"");

        /* Name this processor's MADT LAPIC descriptor. */
        stmt("OperationRegion", 
             "MATR, SystemMemory, Add(\\_SB.MAPA, %d), 8", cpu*8);

        push_block("Field", "MATR, ByteAcc, NoLock, Preserve");
        indent(); printf("MAT, 64\n");
        pop_block();

        push_block("Field", "MATR, ByteAcc, NoLock, Preserve");
        indent(); printf("Offset(4),\n");
        indent(); printf("FLG, 1\n");
        pop_block();

        push_block("Method", "_MAT, 0");
        stmt("Return", "ToBuffer(MAT)");
        pop_block();

        push_block("Method", "_STA");
        push_block("If", "FLG");
        stmt("Return", "0xF");
        pop_block();
        push_block("Else", NULL);
        stmt("Return", "0x0");
        pop_block();
        pop_block();

        push_block("Method", "_EJ0, 1, NotSerialized");
        stmt("Sleep", "0xC8");
        pop_block();

        pop_block();
    }

    /* Operation Region 'PRST': bitmask of online CPUs. */
    stmt("OperationRegion", "PRST, SystemIO, 0xaf00, 32");
    push_block("Field", "PRST, ByteAcc, NoLock, Preserve");
    indent(); printf("PRS, %u\n", max_cpus);
    pop_block();

    /* Control method 'PRSC': CPU hotplug GPE handler. */
    push_block("Method", "PRSC, 0");
    stmt("Store", "ToBuffer(PRS), Local0");
    for ( cpu = 0; cpu < max_cpus; cpu++ )
    {
        /* Read a byte at a time from the PRST online-CPU bitmask. */
        if ( (cpu & 7) == 0 )
            stmt("Store", "DerefOf(Index(Local0, %u)), Local1", cpu/8);
        else
            stmt("ShiftRight", "Local1, 1, Local1");
        /* Extract current CPU's status: 0=offline; 1=online. */
        stmt("And", "Local1, 1, Local2");
        /* Check if status is up-to-date in the relevant MADT LAPIC entry... */
        push_block("If", "LNotEqual(Local2, \\_SB.PR%02X.FLG)", cpu);
        /* ...If not, update it and the MADT checksum, and notify OSPM. */
        stmt("Store", "Local2, \\_SB.PR%02X.FLG", cpu);
        push_block("If", "LEqual(Local2, 1)");
        stmt("Notify", "PR%02X, 1", cpu); /* Notify: Device Check */
        stmt("Subtract", "\\_SB.MSU, 1, \\_SB.MSU"); /* Adjust MADT csum */
        pop_block();
        push_block("Else", NULL);
        stmt("Notify", "PR%02X, 3", cpu); /* Notify: Eject Request */
        stmt("Add", "\\_SB.MSU, 1, \\_SB.MSU"); /* Adjust MADT csum */
        pop_block();
        pop_block();
    }
    stmt("Return", "One");
    pop_block();

    pop_block();

    /* Define GPE control method '_L02'. */
    push_block("Scope", "\\_GPE");
    push_block("Method", "_L02");
    stmt("Return", "\\_SB.PRSC()");
    pop_block();
    pop_block();
    /**** Processor end ****/


    /**** PCI0 start ****/
    push_block("Scope", "\\_SB.PCI0");

    /*** PCI-ISA link definitions ***/
    /* BUFA: List of ISA IRQs available for linking to PCI INTx. */
    stmt("Name", "BUFA, ResourceTemplate() { "
         "IRQ(Level, ActiveLow, Shared) { 5, 10, 11 } }");
    /* BUFB: IRQ descriptor for returning from link-device _CRS methods. */
    stmt("Name", "BUFB, Buffer() { "
         "0x23, 0x00, 0x00, 0x18, " /* IRQ descriptor */
         "0x79, 0 }");              /* End tag, null checksum */
    stmt("CreateWordField", "BUFB, 0x01, IRQV");
    /* Create four PCI-ISA link devices: LNKA, LNKB, LNKC, LNKD. */
    for ( link = 0; link < 4; link++ )
    {
        push_block("Device", "LNK%c", 'A'+link);
        stmt("Name", "_HID,  EISAID(\"PNP0C0F\")");  /* PCI interrupt link */
        stmt("Name", "_UID, %u", link+1);
        push_block("Method", "_STA, 0");
        push_block("If", "And(PIR%c, 0x80)", 'A'+link);
        stmt("Return", "0x09");
        pop_block();
        push_block("Else", NULL);
        stmt("Return", "0x0B");
        pop_block();
        pop_block();
        push_block("Method", "_PRS");
        stmt("Return", "BUFA");
        pop_block();
        push_block("Method", "_DIS");
        stmt("Or", "PIR%c, 0x80, PIR%c", 'A'+link, 'A'+link);
        pop_block();
        push_block("Method", "_CRS");
        stmt("And", "PIR%c, 0x0f, Local0", 'A'+link);
        stmt("ShiftLeft", "0x1, Local0, IRQV");
        stmt("Return", "BUFB");
        pop_block();
        push_block("Method", "_SRS, 1");
        stmt("CreateWordField", "ARG0, 0x01, IRQ1");
        stmt("FindSetRightBit", "IRQ1, Local0");
        stmt("Decrement", "Local0");
        stmt("Store", "Local0, PIR%c", 'A'+link);
        pop_block();
        pop_block();
    }

    /*** PCI interrupt routing definitions***/
    /* _PRT: Method to return routing table. */
    push_block("Method", "_PRT, 0");
    push_block("If", "PICD");
    stmt("Return", "PRTA");
    pop_block();
    stmt("Return", "PRTP");
    pop_block();
    /* PRTP: PIC routing table (via ISA links). */
    printf("Name(PRTP, Package() {\n");
    for ( dev = 1; dev < 32; dev++ )
        for ( intx = 0; intx < 4; intx++ ) /* INTA-D */
            printf("Package(){0x%04xffff, %u, \\_SB.PCI0.LNK%c, 0},\n",
                   dev, intx, 'A'+((dev+intx)&3));
    printf("})\n");
    /* PRTA: APIC routing table (via non-legacy IOAPIC GSIs). */
    printf("Name(PRTA, Package() {\n");
    for ( dev = 1; dev < 32; dev++ )
        for ( intx = 0; intx < 4; intx++ ) /* INTA-D */
            printf("Package(){0x%04xffff, %u, 0, %u},\n",
                   dev, intx, ((dev*4+dev/8+intx)&31)+16);
    printf("})\n");

    /*
     * Each PCI hotplug slot needs at least two methods to handle
     * the ACPI event:
     *  _EJ0: eject a device
     *  _STA: return a device's status, e.g. enabled or removed
     * Other methods are optional: 
     *  _PS0/3: put them here for debug purpose
     * 
     * Eject button would generate a general-purpose event, then the
     * control method for this event uses Notify() to inform OSPM which
     * action happened and on which device.
     *
     * Pls. refer "6.3 Device Insertion, Removal, and Status Objects"
     * in ACPI spec 3.0b for details.
     *
     * QEMU provides a simple hotplug controller with some I/O to handle
     * the hotplug action and status, which is beyond the ACPI scope.
     */
    for ( slot = 0; slot < 0x100; slot++ )
    {
        push_block("Device", "S%02X", slot);
        /* _ADR == dev:fn (16:16) */
        stmt("Name", "_ADR, 0x%08x", ((slot & ~7) << 13) | (slot & 7));
        /* _SUN == dev */
        stmt("Name", "_SUN, 0x%08x", slot >> 3);
        push_block("Method", "_PS0, 0");
        stmt("Store", "0x%02x, \\_GPE.DPT1", slot);
        stmt("Store", "0x80, \\_GPE.DPT2");
        pop_block();
        push_block("Method", "_PS3, 0");
        stmt("Store", "0x%02x, \\_GPE.DPT1", slot);
        stmt("Store", "0x83, \\_GPE.DPT2");
        pop_block();
        push_block("Method", "_EJ0, 1");
        stmt("Store", "0x%02x, \\_GPE.DPT1", slot);
        stmt("Store", "0x88, \\_GPE.DPT2");
        stmt("Store", "0x%02x, \\_GPE.PH%02X", /* eject */
             (slot & 1) ? 0x10 : 0x01, slot & ~1);
        pop_block();
        push_block("Method", "_STA, 0");
        stmt("Store", "0x%02x, \\_GPE.DPT1", slot);
        stmt("Store", "0x89, \\_GPE.DPT2");
        if ( slot & 1 )
            stmt("ShiftRight", "0x4, \\_GPE.PH%02X, Local1", slot & ~1);
        else
            stmt("And", "\\_GPE.PH%02X, 0x0f, Local1", slot & ~1);
        stmt("Return", "Local1"); /* IN status as the _STA */
        pop_block();
        pop_block();
    }

    pop_block();
    /**** PCI0 end ****/


    /**** GPE start ****/
    push_block("Scope", "\\_GPE");

    stmt("OperationRegion", "PHP, SystemIO, 0x10c0, 0x82");

    push_block("Field", "PHP, ByteAcc, NoLock, Preserve");
    indent(); printf("PSTA, 8,\n"); /* hotplug controller event reg */
    indent(); printf("PSTB, 8,\n"); /* hotplug controller slot reg */
    for ( slot = 0; slot < 0x100; slot += 2 )
    {
        indent();
        /* Each hotplug control register manages a pair of pci functions. */
        printf("PH%02X, 8,\n", slot);
    }
    pop_block();

    stmt("OperationRegion", "DG1, SystemIO, 0xb044, 0x04");

    push_block("Field", "DG1, ByteAcc, NoLock, Preserve");
    indent(); printf("DPT1, 8, DPT2, 8\n");
    pop_block();

    push_block("Method", "_L03, 0, Serialized");
    /* Detect slot and event (remove/add). */
    stmt("Name", "SLT, 0x0");
    stmt("Name", "EVT, 0x0");
    stmt("Store", "PSTA, Local1");
    stmt("And", "Local1, 0xf, EVT");
    stmt("Store", "PSTB, Local1"); /* XXX: Store (PSTB, SLT) ? */
    stmt("And", "Local1, 0xff, SLT");
    /* Debug */
    stmt("Store", "SLT, DPT1");
    stmt("Store", "EVT, DPT2");
    /* Decision tree */
    decision_tree(0x00, 0x100, "SLT", pci_hotplug_notify);
    pop_block();

    pop_block();
    /**** GPE end ****/


    pop_block();
    /**** DSDT DefinitionBlock end ****/

    return 0;
}
Пример #12
0
Файл: astree.c Проект: mtnash/oc
void visit_tree(astree node, FILE* outfile){
    switch(node->symbol){
        case TOK_STRUCT:
            handlestruct(node, outfile);
            return;
        case TOK_BLOCK:
            push_block(gblock_stk);
            break;
        case TOK_FUNCTION:
            if (handlefunction(node, outfile)){
                return;
            } else {
                push_block(gblock_stk);
                break;
            }
        case TOK_PROTOTYPE:
            handleprototype(node,outfile);
            break;
        case TOK_VARDECLINIT:
            handlevardecl(node,outfile);
            break;
    } 
    astree temp;
    for(temp = node->first; temp != NULL; temp = temp->next){
        visit_tree(temp, outfile);
    }
    switch(node->symbol){
        case TOK_BLOCK:
        case TOK_FUNCTION:
            pop_idents(gident_tbl,gblock_stk->top->blocknr);
            pop_block(gblock_stk);
            break;
        case TOK_INTCON:
            node->attrs = ATTR_INT | ATTR_CONST;
            break;
        case TOK_CHARCON:
            node->attrs = ATTR_CHAR | ATTR_CONST;
            break;
        case TOK_STRINGCON:
            node->attrs = ATTR_STRING | ATTR_CONST;
            break;
        case TOK_FALSE:
        case TOK_TRUE:
        case TOK_BOOL:
            node->attrs = ATTR_BOOL | ATTR_CONST;
            node->blocknr = gblock_stk->top->blocknr;
            break;
        case TOK_ARRAY:
            node->attrs = ATTR_ARRAY | bitlookup(node->first->symbol);
            node->blocknr = gblock_stk->top->blocknr;
            break;
        case TOK_INT:
            node->attrs = ATTR_INT;
            node->blocknr = gblock_stk->top->blocknr;
            break;
        case TOK_CHAR:
            node->attrs = ATTR_CHAR;
            node->blocknr = gblock_stk->top->blocknr;
            break;
        case TOK_STRING:
            node->attrs = ATTR_STRING;
            node->blocknr = gblock_stk->top->blocknr;
            break;
        case TOK_TYPEID:
            node->attrs = ATTR_TYPEID;
            node->blocknr = gblock_stk->top->blocknr;
            break;
        case TOK_VOID:
            node->attrs = ATTR_VOID;
            node->blocknr = gblock_stk->top->blocknr;
            break;
    }
}
Пример #13
0
void l_scan (SOURCE_FILE * sf)
{
	int r = 1,in_sub = FALSE;
	int block_stack[STACK_SIZE],block_size = 0;

	list_init(&list_sub);
	list_init(&list_var);
	list_init(&list_array);

	while(r)
	{
		r = l_get_line(sf);
		pline = line;
		l_get_token ();
		// skip empty line
		if (token_type==TT_LINE_END) continue;
		// check command
		if (IS_KEYWORD(token_type))
		{
			if (token_type==KEY_SUB)
			{
				USER_SUB * sub;
				
				if(in_sub)
				{
					merror_msg("sub procedure can not be nested");
				}
				in_sub = TRUE;

				match_type(TT_ID);
				sub = (USER_SUB*)calloc(sizeof(USER_SUB),1);
				sub->name	= s_strdup(token);
				sub->pos	= sf->pos;
				list_push(&list_sub,sub);
				match_type(TT_LINE_END);
				push_block(B_SUB);
				continue;
			}
			else if (token_type==KEY_END)
			{
				if (block_size<=0 || block_top==B_REPEAT)
					merror_illegal_token();
				match_type(TT_LINE_END);
				if(pop_block==B_SUB)
				{
					in_sub = FALSE;
				}
				continue;
			}
			else if(token_type==KEY_VAR)
			{
				while(1)
				{
					match_type(TT_ID);
					l_get_token();
					if (token_type==TT_END)			break;
					else if (token_type==TT_COM)	continue;
					else 							merror_illegal_token();
				}
			}
			if (!in_sub) merror_illegal_token();
			if(token_type==KEY_IF)
			{
				match_exp(pline);
				match_type(TT_LINE_END);
				push_block(B_IF);
			}
			else if (token_type==KEY_ELSEIF)
			{
				if (block_size<=0 || block_top!=B_IF)
					merror_illegal_token();
				match_exp(pline);
				match_type(TT_LINE_END);
			}
			else if (token_type==KEY_ELSE)
			{
				if (block_size<=0 || !(block_top==B_IF || block_top==B_CASE))
					merror_illegal_token();
				match_type(TT_LINE_END);
			}
			else if (token_type==KEY_WHILE)
			{
				match_exp(pline);
				match_type(TT_LINE_END);
				push_block(B_WHILE);
			}
			else if (token_type==KEY_FOR)
			{
				// 'for' ID '=' EXP 'to' EXP
				match_type(TT_ID);
				match_type(OPR_EQ);
				match_exp(pline);
				match_str("to");
				match_exp(pline);
				l_get_token();
				if (token_type!=TT_LINE_END)
				{
					if (!str_eq(token,"step"))
						merror_expect("step");
					match_exp(pline);
					match_type(TT_LINE_END);
				}
				push_block(B_FOR);
			}
			else if (token_type==KEY_CASE)
			{
				match_type(TT_ID);
				match_type(TT_LINE_END);
				push_block(B_CASE);
			}
			else if (token_type==KEY_REPEAT)
			{
				match_type(TT_LINE_END);
				push_block(B_REPEAT);
			}
			else if (token_type==KEY_UNTIL)
			{
				if (block_size<=0 || block_top!=B_REPEAT)
					merror_illegal_token();
				match_exp(pline);
				match_type(TT_LINE_END);
				pop_block;
			}
			else if (token_type==KEY_WHEN)
			{
				if (block_size<=0 || block_top!=B_CASE)
					merror_illegal_token();
				match_exp(pline);
				match_type(TT_LINE_END);
			}
			else if (token_type==KEY_GOSUB)
			{
				match_type(TT_ID);
				match_type(TT_LINE_END);
			}
			else if (token_type==KEY_EXIT)
			{
				match_type(TT_LINE_END);
			}
			else if (token_type==KEY_BREAK)
			{
				match_type(TT_LINE_END);
			}
			else if (token_type==KEY_RETURN)
			{
				match_type(TT_LINE_END);
			}
			else if (token_type==KEY_DIM)
			{
				while(1)
				{
					match_type	(TT_ID);
					match_type	(TT_LBK);
					match_exp	(pline);
					match_type	(TT_RBK);
					l_get_token();
					if		(token_type==TT_COM)		continue;
					else if	(token_type==TT_LINE_END)	break;
					else								merror_illegal_token();
				}
			}
		}
		else if (token_type==TT_ID)
		{
			if (!in_sub) merror_illegal_token();
			if (str_eq(token,"print"))
			{
				while(1)
				{
					l_get_token();
					if(token_type!=TT_STRING)
					{
						l_put_back();
						match_exp(pline);
					}
					l_get_token();
					if(token_type==TT_LINE_END) break;
					else if (token_type==TT_COM) continue;
					else merror_expect(",");
				}
			}
			else if (str_eq(token,"input"))
			{
				while(1)
				{
					match_type(TT_ID);
					l_get_token();
					if(token_type==TT_LINE_END) break;
					else if (token_type==TT_COM) continue;
					else merror_expect(",");
				}
			}
			else
			{	// match: [var][=][exp]
				l_get_token();
				if (token_type==OPR_EQ)
				{
					match_exp(pline);
					match_type(TT_LINE_END);
				}
				else
				{
					if (token_type!=TT_LBK)merror_expect("(");
					match_exp(pline);
					match_type(TT_RBK);
					match_type(OPR_EQ);
					match_exp(pline);
					match_type(TT_LINE_END);
				}
			}
		}
		else 
			merror_illegal_token ();
	}
	if (block_size>0)
		merror_msg("incompleted '%s' block!",BLOCK_NAME[block_top]);
}
Пример #14
0
// Convert a node_block list to HTML.  Returns 0 on success, and sets result.
static void blocks_to_html(strbuf *html, node_block *b)
{
	struct ListData *data;
	render_stack* rstack = NULL;
	bool visit_children = false;
	bool tight = false;

	while(b != NULL) {
		visit_children = false;
		switch(b->tag) {
		case BLOCK_DOCUMENT:
			rstack = push_block(rstack, b->next, "", false, false);
			visit_children = true;
			break;

		case BLOCK_PARAGRAPH:
			if (tight) {
				inlines_to_html(html, b->inline_content);
			} else {
				cr(html);
				strbuf_puts(html, "<p>");
				inlines_to_html(html, b->inline_content);
				strbuf_puts(html, "</p>\n");
			}
			break;

		case BLOCK_BQUOTE:
			cr(html);
			strbuf_puts(html, "<blockquote>\n");
			rstack = push_block(rstack, b->next, "</blockquote>\n", tight, false);
			tight = false;
			visit_children = true;
			break;

		case BLOCK_LIST_ITEM:
			cr(html);
			strbuf_puts(html, "<li>");
			rstack = push_block(rstack, b->next, "</li>\n", tight, true);
			visit_children = true;
			break;

		case BLOCK_LIST:
			// make sure a list starts at the beginning of the line:
			cr(html);
			data = &(b->as.list);

			if (data->start > 1) {
				strbuf_printf(html, "<%s start=\"%d\">\n",
					      data->list_type == bullet ? "ul" : "ol",
					      data->start);
			} else {
				strbuf_puts(html, data->list_type == bullet ? "<ul>\n" : "<ol>\n");
			}

			rstack = push_block(rstack, b->next,
					    data->list_type == bullet ?
					    "\n</ul>\n" : "\n</ol>\n", tight, false);
			tight = data->tight;
			visit_children = true;
			break;

		case BLOCK_ATX_HEADER:
		case BLOCK_SETEXT_HEADER:
			cr(html);
			strbuf_printf(html, "<h%d>", b->as.header.level);
			inlines_to_html(html, b->inline_content);
			strbuf_printf(html, "</h%d>\n", b->as.header.level);
			break;

		case BLOCK_INDENTED_CODE:
		case BLOCK_FENCED_CODE:
			cr(html);

			strbuf_puts(html, "<pre><code");

			if (b->tag == BLOCK_FENCED_CODE) {
				strbuf *info = &b->as.code.info;

				if (strbuf_len(info) > 0) {
					int first_tag = strbuf_strchr(info, ' ', 0);
					if (first_tag < 0)
						first_tag = strbuf_len(info);

					strbuf_puts(html, " class=\"language-");
					escape_html(html, info->ptr, first_tag);
					strbuf_putc(html, '"');
				}
			}

			strbuf_putc(html, '>');
			escape_html(html, b->string_content.ptr, b->string_content.size);
			strbuf_puts(html, "</code></pre>\n");
			break;

		case BLOCK_HTML:
			strbuf_put(html, b->string_content.ptr, b->string_content.size);
			break;

		case BLOCK_HRULE:
			strbuf_puts(html, "<hr />\n");
			break;

		case BLOCK_REFERENCE_DEF:
			break;

		default:
			assert(false);
		}
		if (visit_children) {
			b = b->children;
		} else {
			b = b->next;
		}
		while (b == NULL && rstack != NULL) {
			strbuf_puts(html, rstack->literal);
			if (rstack->trim) {
				strbuf_rtrim(html);
			}
			tight = rstack->tight;
			b = rstack->next_sibling.block;
			rstack = pop_render_stack(rstack);
		}
	}

	free_render_stack(rstack);
}