--- layout: post title: Short Stories ---
A weak minded sheep and her lamb once lived on a bit of barren land; there were several small spots where clover grew, and a little shelter of old brush. They were not well cared for, but they made the best of what they had, and were reasonably happy. One day a she-wolf brought over to their place, from her own green fields, several sheep from her flock; they devoured all the clover that was the only subsistence⟨sustenance⟩ of the sheep and lamb, and carelessly threw over their shelter of boughs.
It sounds odd that a she-wolf should have charge of a flock; but this was a wily she-
wolf; there were many wolves in the forest, and game was scarce and shy, so she got a place
with a shepherd as a sheepdog. The shepherd was blind, and old, and foolish, and never knew
the imposture. The neighbours, who were reluctant to meddle in other people’s affairs, did
not like, or did not choose to tell him; so the she-wolf and her cubs waxed fast and strong,
while her kinsmen of the forest, gaunt and hungry roamed
[manuscript page break]
about, seeking their prey.
It was not that she particularly wished to harm the sheep and lamb that the she-wolf robbed them, but that her natural instincts inclining her to a guerrilla life occasionally overcame the teachings of civilization.
It was hard upon the sheep and the lamb. A cold rain fell, and winter was not far off. Before the clover had started to grow again, the shivering lamb was dead. The sheep tried to warm it with her own body, but her wool was wet, and she, too, was starved with the cold; she could only watch her lamb’s innocent eyes grey, and its little legs stiffen, with a breaking heart. She could do nothing; she could not replace the shelter, nor could she make the grass grow again, though she would gladly have watered the grass with her blood, and torn the fleece from her back to keep the cold from the lamb.
When the lamb was dead it was thrown into a hole. The sheep, in her grief, hoped and thought she might die too; but she was older and stronger and more used to hardship than the lamb, so, sad and lonely, she held on and endured the cold and the hunger. Most of the time she either stood gazing
at the hole where they had thrown her lamb, or wandered about the bare pasture where it had frisked and played in happier days. Once a cub of the she-wolf came that way; it was so plump, and sleek, and well cared for, that when the bereaved sheep looked upon it she felt her weak heart giving way because of the injustice of things, and in a mad rage chased the wolf-cub howling away to its mother.
The next day the blind shepherd came in a great rage to the sheep.
The sheep could not remember these details, but full of trouble went off alone to think it over; and wondered if all this were really true, and she had actually become a mad ravening sheep.
Soon she met the Haymaker who was fond of walking in paths and places where the shadows were heavy. He was called the Haymaker because he was supposed to make hay while the sun shone. All people went to him for advice, he was
accounted so very wise; he was thought to be wise because he had many books, and he looked solemn, and he often said “policy is better than honesty,” “don’t whistle too much for your pay,” and other things that showed a profound intellect, and a habit of deep thought. When he demanded the reason of the sheep’s depression of mind, she, being in awe of so great a man, told her story.
“I must tell you what to do,” said he.“Oh no!” cried the sheep “you are so very respectable that it would never do that you should mix yourself up in the affairs of a silly sheep, and a beast of prey.”
The Haymaker insisted that she listen to him, and be guided by him.
‘“But I know myself what is best for me,” cried the sheep. “Let me go away off to some quiet place where I can be quite alone. There I may be able to recover my former tranquility of mind. As it is, I fear I am in too dangerous a state to be allowed to roam about freely. It is a dreadful thing to find out that one is a ravening sheep. How do I know, or how do you know, to what wild deed my fevered mind may prompt me. Suppose I should suddenly spring upon the wild bull, drag him to
the ground, and tear his vitals from his quivering body."’
“That would, indeed, be horrible,” said the Haymaker; “but worse yet than that may happen.”“Worse than that!” Cried the sheep in an awe-stricken voice.“Yes; there is a lower depth still,” and he spoke in a voice as hollow and ghastly that a thrill went through the veins of the sheep, and chilled her very heart.“Suppose the pigs and the grasshoppers should find it out?”
With a cry of horror the sheep fell swooning upon the ground. She had never thought of that.  That the pigs and the grasshoppers should know!
Crushed and humiliated she was carried off to a small paddock by the sea; here she nibbled grass on the hillside, and trotted by the beach, and might have become reasonable, cheerful in her latter days, but for the awful dread that always lay like a stone in her heart, “Suppose the pigs and the grasshoppers should know.”
The Haymaker came in time to dislike all thought or mention of the sheep; for he, too, was terrified lest the pigs and grasshoppers should know, and it should be whispered about that a man as staid and respectable as he had once known a ravening sheep.


| Package | Description |
|---|---|
| org.apache.batik.bridge |
Provides an API for mapping and maintaining consistency between
the SVG DOM tree and the GVT tree.
|
| org.apache.batik.gvt |
Contains all of the interfaces for describing and painting vector
graphics as Java objects.
|
| Modifier and Type | Method and Description |
|---|---|
static Marker |
PaintServer.convertMarker(Element e,
Value v,
BridgeContext ctx)
Returns a
Marker defined on the specified element by
the specified value, and for the specified shape node. |
Marker |
MarkerBridge.createMarker(BridgeContext ctx,
Element markerElement,
Element paintedElement)
Creates a
Marker according to the specified parameters. |
Marker |
SVGMarkerElementBridge.createMarker(BridgeContext ctx,
Element markerElement,
Element paintedElement)
Creates a
Marker according to the specified parameters. |
| Modifier and Type | Field and Description |
|---|---|
protected Marker |
MarkerShapePainter.endMarker
End Marker
|
protected Marker |
MarkerShapePainter.middleMarker
Middle Marker
|
protected Marker |
MarkerShapePainter.startMarker
Start Marker
|
| Modifier and Type | Method and Description |
|---|---|
Marker |
MarkerShapePainter.getEndMarker()
Returns the marker that shall be drawn at the last vertex of the given
shape.
|
Marker |
MarkerShapePainter.getMiddleMarker()
Returns the marker that shall be drawn at every other vertex (not the
first or the last one) of the given shape.
|
Marker |
MarkerShapePainter.getStartMarker()
Returns the marker that shall be drawn at the first vertex of the given
shape.
|
| Modifier and Type | Method and Description |
|---|---|
void |
MarkerShapePainter.setEndMarker(Marker endMarker)
Sets the marker that shall be drawn at the last vertex of the given
shape.
|
void |
MarkerShapePainter.setMiddleMarker(Marker middleMarker)
Sets the marker that shall be drawn at every other vertex (not the first
or the last one) of the given shape.
|
void |
MarkerShapePainter.setStartMarker(Marker startMarker)
Sets the marker that shall be drawn at the first vertex of the given
shape.
|
Copyright © 2022 Apache Software Foundation. All Rights Reserved.


AddWindowTimer()
语法
AddWindowTimer(#Window, Timer, Timeout)概要
Adds a new timer to the specified window. This will cause #PB_Event_Timer events to be received periodically in the WindowEvent() or WaitWindowEvent() functions. The RemoveWindowTimer() function can be used to remove the timer again.
参数
#Window 要使用的窗口. A timer is always attached to a window and will be removed if that window is closed. Timer An user-defined number that identifies this timer. Timers on separate windows may have overlapping numbers. This value will later be returned from EventTimer() when a #PB_Event_Timer is received. It can also be used to remove the timer again with the RemoveWindowTimer() function. Timeout Specifies the amount of time (in milliseconds) between each #PB_Event_Timer events. The timer events will only be generated when there are no other events to be processed (timers are low-priority events). This means that the time that elapses between two timer events may be larger than the specified Timeout value. Timers are therefore not suited for precise timing but are rather intended to perform periodic tasks such as updating a gadget content or similar.
返回值
无.
示例
If OpenWindow(0, 0, 0, 400, 100, "Timer Example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) ProgressBarGadget(0, 10, 10, 380, 20, 0, 100) AddWindowTimer(0, 123, 250) Value = 0 Repeat Event = WaitWindowEvent() If Event = #PB_Event_Timer And EventTimer() = 123 Value = (Value + 5) % 100 SetGadgetState(0, Value) EndIf Until Event = #PB_Event_CloseWindow EndIf
备注
To change the timer duration you have to remove the timer first, then add the same timer with a new 'Timeout' value again:RemoveWindowTimer(#Window, Timer) AddWindowTimer(#Window, Timer, Timeout)
参阅
RemoveWindowTimer(), EventTimer()
已支持操作系统
所有


Whoops! Something Went Wrong
You must log in in order to create, edit, or delete jerseys
Click Here To Return To Homepage!


LogIn Page
Username or password is not correct!
Username:
Password:
Don't have an account?
Register now!


The Mechanics of Execution - An Overview of Code Generation
This is an extended tutorial on how to generate backend code from intermediate code. Don’t start this until instructed. At the very least, you should have intermediate code generation working in your compiler first.
With that out of the way, this document introduces introduces the basic mechanics of writing an interpreter, a transpiler, and generation of machine code using LLVM and WebAssembly. In general, none of this is "hard" except that there often a lot of fiddly bits concerning tooling and data formats. Some simplifications have been made to make encoding easier (at the expense of a bit of space optimization).
For this tutorial, we’re going to consider the following code fragment:
var x int = 4;
var y int = 5;
var d int = x * x + y * y;
print d;
When compiled by your compiler, you should generate the following intermediate code:
code = [
('GLOBALI', 'x'),
('CONSTI', 4),
('STORE', 'x'),
('GLOBALI', 'y'),
('CONSTI', 5),
('STORE', 'y'),
('GLOBALI', 'd'),
('LOAD', 'x'),
('LOAD', 'x'),
('MULI',),
('LOAD', 'y'),
('LOAD', 'y'),
('MULI',),
('ADDI',),
('STORE', 'd'),
('LOAD', 'd'),
('PRINTI',)
]
Copy the above code
variable to a Python file where you can use it
in some examples.
Part (a) - Writing an Interpreter
One possible target for your compiler is to write an interpreter. An interpreter directly runs the instructions on a kind of simulated machine. The simulated machine has memory, a stack, and a program counter just like a real CPU. Define the following class and try it with the above code:
class Interpreter:
def __init__(self):
self.store = { }
self.stack = [ ]
self.pc = 0
def run(self, code):
self.pc = 0
while self.pc < len(code):
op, *opargs = code[self.pc]
getattr(self, f'run_{op}')(*opargs)
self.pc += 1
def push(self, item):
self.stack.append(item)
def pop(self):
return self.stack.pop()
def run_GLOBALI(self, name):
self.store[name] = None
def run_CONSTI(self, value):
self.push(value)
def run_STORE(self, name):
self.store[name] = self.pop()
def run_LOAD(self, name):
self.push(self.store[name])
def run_ADDI(self):
self.push(self.pop() + self.pop())
def run_MULI(self):
self.push(self.pop() * self.pop())
def run_PRINTI(self):
print(self.pop())
# Run it!
interp = Interpreter()
interp.run(code)
Modify your interpreter by giving it a new instruction SUBI
and
running it on this program which should produce an output of "1":
code = [
('CONSTI', 5),
('CONSTI', 4),
('SUBI',)
('PRINTI',)
]
Direct interpretation of simulated instructions on a simulated machine is how various scripting languages such as Python, Ruby, PHP, and so forth work. This "simulation" is a big part of dynamic typing. It’s also why these languages run slower than compiled languages like C.
Part (b) - Writing a Transpiler
Instead of directly running intermediate code, another option is to turn the code into source code for another programming language such as Python or C. This is how early versions of C++ worked. It’s also the basis of modern languages such as TypeScript (transpiled to JavaScript). A common target of transpiling is C. Here is a transpiler that produces Python:
class Transpiler:
def __init__(self):
self.outcode = 'def main():\n'
self.stack = [ ]
def translate(self, code):
for op, *opargs in code:
getattr(self, f'translate_{op}')(*opargs)
self.outcode += '\nmain()\n'
return self.outcode
def push(self, item):
self.stack.append(item)
def pop(self):
return self.stack.pop()
def translate_GLOBALI(self, name):
pass
def translate_CONSTI(self, value):
self.push(repr(value))
def translate_STORE(self, name):
self.outcode += f' {name} = {self.pop()}\n'
def translate_LOAD(self, name):
self.push(name)
def translate_ADDI(self):
self.push(f'({self.pop()} + {self.pop()})')
def translate_MULI(self):
self.push(f'({self.pop()} * {self.pop()})')
def translate_PRINTI(self):
self.outcode += f' print({self.pop()})\n'
trans = Transpiler()
print(trans.translate(code))
In this implementation, you still maintain an internal stack to manage the construction of expressions (e.g., certain methods still push and pop things from the stack). However, instead of actually performing an operation as with the interpreter, you’re now producing source code to perform the operation.
If you run the program, you should get this:
bash % python3 transpile.py
def main():
x = 4
y = 5
d = ((y * y) + (x * x))
print(d)
main()
bash %
Try redirecting the output to a file and running it:
bash % python3 transpile.py > out.py
bash % python3 out.py
41
bash %
See if you can modify the program so that it produces C instead, creating the following output code:
#include <stdio.h>
int main() {
int x;
int y;
int d;
x = 4;
y = 5;
d = ((y * y) + (x * x));
printf("%i\n", (d));
}
If you’re making a new language, transpiling is often a easy approach for getting things to work. Take your language, transpile it to C, combine with a few library functions and you’re running.
Part (c) - Generating Assembly Code with LLVM
With transpiling, you’re taking a high-level language and producing output in a different high-level language. Instead of that, you could compile down to a low-level machine language that is either the actual hardware or a very close approximation to it. One such tool for doing that is LLVM. LLVM is used in a number of major projects such as the clang C/C++ compiler. It’s also used to implement various so-called JIT (Just in Time) compilation features.
LLVM is an extremely large project that can be daunting to jump into.
However, using it in a simple manner is not so bad. To explore the
basics, we’re going to use the llvmlite
package. This is available
in the Anaconda Python distribution so if you’re using that, you
should already have it.
LLVM Preliminaries
Your first task is to make sure Anaconda Python and the clang C/C++ compiler have been installed on your machine. Please review the README file for the compilers project regarding installation notes.
Hello World
The first step in using LLVM is to make a LLVM module which contains
all of the code you will be generating. Create a file
hellollvm.py
and put this code into it:
# hellollvm.py
from llvmlite.ir import Module
mod = Module('hello')
print(mod)
Run the program and you should get some output like this:
bash % python3 hellollvm.py
; ModuleID = "hello"
target triple = "unknown-unknown-unknown"
target datalayout = ""
bash %
The output you’re seeing is LLVM low-level code—a kind of architecture
independent assembly language. At this point, it’s not too
interesting. However, let’s declare a function to put in the module.
Change the program to the following to declare a function with the C
prototype int hello()
:
# hellollvm.py
from llvmlite.ir import (
Module, Function, FunctionType, IntType
)
mod = Module('hello')
int_type = IntType(32)
hello_func = Function(mod, FunctionType(int_type, []), name='hello')
print(mod)
Running the program, you should now get the following:
bash % python3 hellollvm.py
; ModuleID = "hello"
target triple = "unknown-unknown-unknown"
target datalayout = ""
declare i32 @"hello"()
bash %
Again, it’s not too interesting yet. However, you can see
how a function declaration was placed in the module output. The LLVM
statement declare i32 @"hello"()
is declaring a function that
returns a 32-bit integer and takes no arguments.
Let’s add some code to the function. To do this, you first need to create a basic block. A basic block is a container that holds low-level instructions. Add the following to the program:
# hellollvm.py
from llvmlite.ir import (
Module, Function, FunctionType, IntType, IRBuilder
)
mod = Module('hello')
int_type = IntType(32)
hello_func = Function(mod, FunctionType(int_type, []), name='hello')
block = hello_func.append_basic_block('entry')
builder = IRBuilder(block)
builder.ret(Constant(IntType(32), 37))
print(mod)
Running the program should now produce this:
; ModuleID = "hello"
target triple = "unknown-unknown-unknown"
target datalayout = ""
define i32 @"hello"()
{
entry:
ret i32 37
}
There you are---a complete LLVM function that does nothing but return the value 37. Now, a question arises: How do you go about getting it to run?
Compilation to a Standalone Executable
If you want to run your LLVM generated code, one approach is to feed it
to a LLVM-based compiler such as clang
. Save your generated
code to a file hello.ll
:
bash % python3 hellollvm.py > hello.ll
bash %
Now, write a short C program to bootstrap the function:
/* main.c */
#include <stdio.h>
extern int hello();
int main() {
printf("hello() returned %i\n", hello());
}
Compile this program together with hello.ll
to make an executable:
bash % clang main.c hello.ll
bash % ./a.out
hello() returned 37
bash %
This basic technique for invoking your code and creating stand-alone
programs will be useful for testing and development. You also get the
advantage of being able to use C library functions such as
printf()
. Without this, you’d have to figure out how to perform
I/O directly using low-level LLVM instructions—which would not be
fun.
Just in Time Compilation
In our example, we are creating LLVM instructions, writing them to a
file, and using the clang
compiler to produce an executable.
It’s possible that this won’t work due to the local setup on
your machine (maybe you don’t have clang installed correctly).
One feature of LLVM is that it can compile it’s own code to executable
machine instructions without ever going to a file or using clang.
You can do this entirely in Python and have Python call the resulting
function.
This part is rather tricky and obscure, but add the following code to
hellollvm.py
:
# hellollvm.py
... keep earlier LLVM example here ...
def run_jit(module):
import llvmlite.binding as llvm
llvm.initialize()
llvm.initialize_native_target()
llvm.initialize_native_asmprinter()
target = llvm.Target.from_default_triple()
target_machine = target.create_target_machine()
compiled_mod = llvm.parse_assembly(str(module))
engine = llvm.create_mcjit_compiler(compiled_mod, target_machine)
# Look up the function pointer (a Python int)
func_ptr = engine.get_function_address("hello")
# Turn into a Python callable using ctypes
from ctypes import CFUNCTYPE, c_int
hello = CFUNCTYPE(c_int)(func_ptr)
res = hello()
print('hello() returned', res)
# Run it!
run_jit(mod)
If you run this, you should see the program run the code, and produce output such as this:
bash % python3 hellollvm.py
hello() returned 37
bash %
This version runs entirely inside an active Python interpreter process. If you can’t get clang to work, you can always use this as a fallback.
Local Variables and Math Operations
To do more with LLVM, you need to use more instructions on the
builder
object in the example. To declare a local variable "x",
you use this method:
x = builder.alloca(int_type, name="x")
To load and store values, you use these instructions:
r = builder.load(x) # Load a value from x into r
builder.store(r, x) # Store r into y
To perform arithmetic, you use instructions such as these:
r3 = builder.add(r1, r2) # r3 = r1 + r2
r3 = builder.mul(r1, r2) # r3 = r1 + r2
Here is an example that implements the program given at the start of this exercise:
# hellollvm.py
from llvmlite.ir import (
Module, Function, FunctionType, IntType,
Constant, IRBuilder
)
mod = Module('hello')
int_type = IntType(32)
hello_func = Function(mod, FunctionType(int_type, []), name='hello')
block = hello_func.append_basic_block('entry')
builder = IRBuilder(block)
x = builder.alloca(int_type, name='x')
y = builder.alloca(int_type, name='y')
builder.store(Constant(int_type, 4), x)
builder.store(Constant(int_type, 5), y)
r1 = builder.load(x)
r2 = builder.mul(r1, r1)
r3 = builder.load(y)
r4 = builder.mul(r3, r3)
r5 = builder.add(r2, r4)
d = builder.alloca(int_type, name='d')
builder.store(r5, d)
builder.ret(builder.load(d))
print(mod)
An important thing about LLVM is that it is NOT a stack machine. It is based
on registers and Single Static Assignment (SSA). Basically, every operation
produces a new variable that can only be assigned once. It also requires explicit
load/store instructions to go between local variables and registers. In the
above example, you can’t do an instruction such as builder.add(x, y)
between
local variables. You have to load the variables into registers first and
perform the instruction on the registers.
Try compiling the above program and running you code again:
bash % python3 hellollvm.py > hello.ll
bash % clang main.c hello.ll
bash % ./a.out
hello() returned 41
bash %
Functions with Arguments
Let’s make a more interesting function. This function takes two
arguments x
and y
and computes the value x**2 + y**2
. To
do this, we’re going to follow similar steps as above. First, declare
the function, add a basic block, and make a new builder. Once the
builder is obtained, we’ll create some instructions to compute and
return the result. Add the following code to your hellollvm.py
program:
# hellollvm.py
...
# A user-defined function
from llvmlite.ir import DoubleType
ty_double = DoubleType()
dsquared_func = Function(mod,
FunctionType(ty_double, [ty_double, ty_double]),
name='dsquared')
block = dsquared_func.append_basic_block('entry')
builder = IRBuilder(block)
# Get the function args
x, y = dsquared_func.args
# Compute temporary values for x*x and y*y
xsquared = builder.fmul(x, x)
ysquared = builder.fmul(y, y)
# Sum the values and return the result
d2 = builder.fadd(xsquared, ysquared)
builder.ret(d2)
# Output the final module
print(mod)
One thing to notice is that you use the builder to carry out the steps
needed to perform the calculation that you’re trying to perform. Python
variables such as x
, xsquared
, and d2
are being used to
hold intermediate results.
If you run this program, you should output similar to the following:
; ModuleID = "hello"
...
define double @"dsquared"(double %".1", double %".2")
{
entry:
%".4" = fmul double %".1", %".1"
%".5" = fmul double %".2", %".2"
%".6" = fadd double %".4", %".5"
ret double %".6"
}
To test it, modify the C bootstrap code as follows:
/* main.c */
#include <stdio.h>
extern int hello();
extern double dsquared(double, double);
int main() {
printf("Hello returned: %i\n", hello());
printf("dsquared(3, 4) = %f\n", dsquared(3.0, 4.0));
}
Compile as follows:
bash % python3 hellollvm.py > hello.ll
bash % clang main.c hello.ll
bash % ./a.out
Hello returned: 41
dsquared(3, 4) = 25.000000
bash %
Calling an external function
Even though you’re emitting low-level assembly code, there’s no need
to completely reinvent the wheel from scratch. One problem concerns
printing. In our IR code, there is an instruction to print a value
to the screen. How do you do that in LLVM? The short answer is that
you don’t (well, unless you’re some kind of masochist). You do printing
in C. Make a new file runtime.c
and put a
a _print_int()
function in it like this:
/* runtime.c */
#include <stdio.h>
void _print_int(int x) {
printf("out: %i\n", x);
}
Now, suppose you wanted to call that function from LLVM. To do it, you need to declare it:
# hellollvm.py
...
from llvmlite.ir import VoidType, IntType
void_type = VoidType()
int_type = IntType(32)
_print_int = Function(mod,
FunctionType(void_type, [int_type]),
name='_print_int')
To call the function, you use the builder.call()
instruction:
r2 = builder.call(_print_int, [r1])
Change your hellollvm.py
program so that it looks like this:
# hellollvm.py
from llvmlite.ir import (
Module, Function, FunctionType, IntType, VoidType,
Constant, IRBuilder
)
mod = Module('hello')
int_type = IntType(32)
void_type = VoidType()
_print_int = Function(mod,
FunctionType(void_type, [int_type]),
name='_print_int')
hello_func = Function(mod, FunctionType(int_type, []), name='hello')
block = hello_func.append_basic_block('entry')
builder = IRBuilder(block)
x = builder.alloca(int_type, name='x')
y = builder.alloca(int_type, name='y')
builder.store(Constant(int_type, 4), x)
builder.store(Constant(int_type, 5), y)
t1 = builder.load(x)
t2 = builder.load(x)
t3 = builder.mul(t1, t2)
t4 = builder.load(y)
t5 = builder.load(y)
t6 = builder.mul(t4, t5)
t7 = builder.add(t3, t6)
d = builder.alloca(int_type, name='d')
builder.store(t7, d)
builder.call(_print_int, [builder.load(d)]) # Call _print_int()
builder.ret(Constant(int_type, 37)) # Return 37
print(mod)
Compile and run (note inclusion of runtime.c
):
bash % python3 hellollvm.py > hello.ll
bash % clang main.c runtime.c hello.ll
bash % ./a.out
out: 41
hello() returned 41
bash %
Notice that there is output from the _print_int()
function as well as
the return value from the hello()
function itself.
As an aside, you can implement almost anything that you want in C and link it as library code into your output assembly code. Printing, memory access, and all sorts of other things could potentially be written in this way. You’ll have to do some of this in the project.
Global Variables and State
You might want to define a variable that keeps its state. Let’s make
a global variable x
:
# hellollvm.py
...
from llvmlite.ir import GlobalVariable
x_var = GlobalVariable(mod, ty_double, 'x')
x_var.initializer = Constant(ty_double, 0.0)
Now, let’s write a function that increments the variable and
prints its new value. To do this, you use load
and store
instructions to manipulate the variable state:
# hellollvm.py
...
from llvmlite.ir import VoidType
incr_func = Function(mod,
FunctionType(VoidType(), []),
name='incr')
block = incr_func.append_basic_block('entry')
builder = IRBuilder(block)
tmp1 = builder.load(x_var)
tmp2 = builder.fadd(tmp1, Constant(ty_double, 1.0))
builder.store(tmp2, x_var)
builder.ret_void()
Modify the main.c
file as follows:
/* main.c */
#include <stdio.h>
extern int hello();
extern double dsquared(double, double);
extern double x;
extern void incr();
int main() {
printf("Hello returned: %i\n", hello());
printf("dsquared(3, 4) = %f\n", dsquared(3.0, 4.0));
printf("x is %f\n", x);
incr();
printf("x is now %f\n", x);
}
- Compile and run the program again
bash % python3 hellollvm.py > hello.ll
bash % clang main.c hello.ll -lm
bash % ./a.out
out: 41
Hello returned: 41
dsquared(3, 4) = 25.000000
x is 0.000000
x is now 1.000000
bash %
Compiling to LLVM
In building your compiler, you’ll need to figure out how to translate IR code into the appropriate low-level LLVM operations. This part is left to the project, but the mechanics of it are going to be almost identical to the interpreter/transpiler exercises you did earlier. You need to keep track of variables. You need a stack to keep track of LLVM values. Most of the code generation will involve operations on this stack.
A LLVM Mini-Reference
This section aims to provide a mini-reference for using LLVM in the next part of the project. It summarizes some of the critical bits.
For creating LLVM code, use the following import:
from llvmlite.ir import (
Module, Function, FunctionType, IRBuilder,
IntType, DoubleType, VoidType, Constant
)
All LLVM code is placed in a module. You create one like this:
mod = Module("modname")
You declare functions like this:
func = Function(mod,
FunctionType(rettype, [argtypes]),
name="funcname")
The following basic datatypes are used heavily in declarations:
IntType(32) # A 32-bit integer
DoubleType() # A double-precision float
It is usually easier to make aliases for the types:
int_type = IntType(32)
float_type = DoubleType()
To define constants corresponding to the above types, do this:
c = Constant(int_type, value)
d = Constant(float_type, value)
To start adding code to a function, you must add a basic block and create a builder. For example:
block = func.append_basic_block('entry')
builder = IRBuilder(block)
Builder objects have a variety of useful methods for adding instructions. These include:
# Returning values
builder.ret(value)
builder.ret_void()
# Integer math
result = builder.add(left, right)
result = builder.sub(left, right)
result = builder.mul(left, right)
result = builder.sdiv(left, right)
# Floating math
result = builder.fadd(left, right)
result = builder.fsub(left, right)
result = builder.fmul(left, right)
result = builder.fdiv(left, right)
# Function call
result = builder.call(func, args)
When using the builder, it is important to emphasize that you must save the results of the above operations and use them in subsequent calls. For example:
t1 = builder.fmul(a, b)
t2 = builder.fmul(c, d)
t3 = builder.fadd(t1, t2)
...
To declare a local variable do something like this:
name_var = builder.alloca(int_type, name='varname')
To declare a global variabel do something like this:
x_var = GlobalVariable(mod, ty_double, 'x')
x_var.initializer = Constant(ty_double, 0.0)
To access either kind of variable, use load and store instructions:
tmp = builder.load(name_var)
builder.store(tmp, name_var)
Part (d) - Taking it to the Web (Assembly)
As our final target, we’re going to compile our code to Web Assembly (Wasm). Wasm is a relatively new technology that is usually introduced with a fairly complicated toolchain. For example, it is possible to compile C, C++, Rust, and other languages to Wasm and to have that code run (somehow) in the browser. You can even find demos of game engines and other interesting things. However, it can be a bit tough to wrap your brain around what’s happening. In this last part, we’re going to look at raw low-level Wasm without any assistive tooling. This is not the way that you’d likely work with it for real, but for the purposes of a compilers course, it’s instructive.
 It simulates a stack machine and it only understands 4 datatypes—integers and floats in both 32-bit and 64-bit encodings. The main difference is that Wasm is encoded in a compact binary encoding---not a list of tuples as we have done. Much of our effort to make Wasm work concerns details of the binary encoding.
As a note: To make it somewhat simpler to describe, our encoding will not be as compact as it could be. Web Assembly uses a number of techniques to compress the size of the output file at the expense of added encoding complexity. For the purpose of a course, it’s probably better to optimize for simplicity instead.
Low-level Encoding of Values
To start out, there are some basic encodings of integers, floats, and text strings that need to take place.
Integers are encoded into a LEB-128, a variable length encoding. The following functions can be used for this purpose:
def encode_unsigned(value):
'''
Produce an LEB128 encoded unsigned integer.
'''
parts = []
while value:
parts.append((value & 0x7f) | 0x80)
value >>= 7
if not parts:
parts.append(0)
parts[-1] &= 0x7f
return bytes(parts)
def encode_signed(value):
'''
Produce a LEB128 encoded signed integer.
'''
parts = [ ]
if value < 0:
# Sign extend the value up to a multiple of 7 bits
value = (1 << (value.bit_length() + (7 - value.bit_length() % 7))) + value
negative = True
else:
negative = False
while value:
parts.append((value & 0x7f) | 0x80)
value >>= 7
if not parts or (not negative and parts[-1] & 0x40):
parts.append(0)
parts[-1] &= 0x7f
return bytes(parts)
assert encode_unsigned(624485) == bytes([0xe5, 0x8e, 0x26])
assert encode_unsigned(127) == bytes([0x7f])
assert encode_signed(-624485) == bytes([0x9b, 0xf1, 0x59])
assert encode_signed(127) == bytes([0xff, 0x00])
Floating point numbers are encoded directly as a little-endian 8-byte double precision value using this function:
def encode_f64(value):
'''
Encode a 64-bit float point as little endian
'''
return struct.pack('<d', value)
Wasm sometimes involves the encoding of a so-called "vector". A vector is list of identically typed items. For example, you could have a vector of integers, a vector of floats, a vector of bytes, and so forth. Vectors are encoded as an unsigned length followed by the raw encoding of whatever items it contains. So, write the following function:
def encode_vector(items):
'''
A size-prefixed collection of objects. If items is already
bytes, it is prepended by a length and returned. If items
is a list of byte-strings, the length of the list is prepended
to byte-string formed by concatenating all of the items.
'''
if isinstance(items, bytes):
return encode_unsigned(len(items)) + items
else:
return encode_unsigned(len(items)) + b''.join(items)
Names are represented as a UTF-8 encoded vector of bytes. The following function will encoded a name:
def encode_name(name):
'''
Encode a text name as a UTF-8 vector
'''
return encode_vector(name.encode('utf-8'))
The first rule of Wasm is that ALL literal values (integers, floats, names, etc.) must
be encoded by these functions. So, put these in a file wasm.py
and use it as a starting
point.
Try a few examples to see what the encodings look like:
>>> encode_unsigned(1234)
b'\xd2\t'
>>> encode_signed(-1234)
b'\xaev'
>>> encode_f64(123.45)
b'\xcd\xcc\xcc\xcc\xcc\xdc^@'
>>> encode_name('spam')
b'\x04spam'
>>>
Reminder: You must use these functions.
Some Basic Instructions
Wasm defines a set of instructions similar to our own IR code. Wasm is also a stack machine just like our IR code. The following table shows a few basic instruction encodings:
b'\x41' <val> => i32.const (val is signed integer)
b'\x6a' => i32.add
b'\x6b' => i32.sub
b'\x6c' => i32.mul
b'\x6d' => i32.div_s
b'\x0b' => end block
Using this, we can start to write a basic Wasm instruction encoder for our example code. This is surprising easy---since Wasm is also a stack machine, we don’t need to maintain a stack or do much of anything other than translate the tuples of IR code into the binary coded version in Wasm:
class WasmEncoder:
def encode(self, code):
self.wcode = b''
for op, *opargs in code:
getattr(self, f'encode_{op}')(*opargs)
# Put a block terminator on the code
self.wcode += b'\x0b'
def encode_CONSTI(self, value):
self.wcode += b'\x41' + encode_signed(value)
def encode_ADDI(self):
self.wcode += b'\x6a'
def encode_MULI(self):
self.wcode += b'\x6c'
def encode_PRINTI(self):
# TO-DO
pass
def encode_GLOBALI(self, name):
# TO-DO
pass
def encode_STORE(self, name):
# TO-DO
pass
def encode_LOAD(self, name):
# TO-DO
pass
encoder = WasmEncoder()
encoder.encode(code)
print(encoder.wcode)
Try running this example. You should get some low-level output that looks like this:
bash % python3 wasm.py
b'A\x04A\x05llj\x0b'
bash %
The output is binary and not meant to be easily human readable.
Types and Global Variables
The low-level instruction stream you just generated is incomplete. Instructions related to global variables were left unimplemented. To do this, a bit more information is needed.
Wasm only has a four datatypes. Instead of being referenced by nice names like "int" or "float", they are identified by specific byte values:
i32 = b'\x7f' # (32-bit int)
i64 = b'\x7e' # (64-bit int)
f32 = b'\x7d' # (32-bit float)
f64 = b'\x7c' # (64-bit float)
Put the above definitions in your encoder. Instead of using a raw byte
value like b'\x7f'
, you’ll use the name i32
.
A global variable in Wasm consists of a type, a mutability flag, and a constant initial value. All of the variables are stored in a table which you can represent as a Python list. Here is an example:
global_defns = [
i32 + b'\x01\x41' + encode_signed(initial) + b'\x0b', # integer
f64 + b'\x01\x44' + encode_f64(initial) + b'\x0b', # float
...
]
To load/store global variables, a pair of instructions are used:
b'\x23' <globidx> => global.get
b'\x24' <globidx> => global.set
The global.get
instruction loads a variable from a global and puts it on
the stack. The global.set
instruction stores the top of the stack into
a variable. The globidx
value is an unsigned integer index into the
globals table. To associate this with a variable name, you’ll need to
maintain a separate dictionary:
# Mapping of variable names to global variable table indices
globals = {
'x': 0,
'y': 1,
...
}
Putting all of this together, here is how global variables get added to your encoder:
class WasmEncoder:
def __init__(self):
# Global variable table
self.global_defns = [ ]
# Table mapping global names to definition index
self.globals = { }
...
def encode_GLOBALI(self, name):
self.globals[name] = len(self.global_defns)
self.global_defns.append(i32 + b'\x01\x41' + encode_signed(0) + b'\x0b')
def encode_STORE(self, name):
self.wcode += b'\x24' + encode_unsigned(self.globals[name])
def encode_LOAD(self, name):
self.wcode += b'\x23' + encode_unsigned(self.globals[name])
Add these to your encoder and look at the resulting output. It should look something like this:
bash % python3 wasm.py
b'A\x04$\x00A\x05$\x01#\x00#\x00l#\x01#\x01lj$\x02#\x02\x0b'
bash %
Function Encoding
The low-level instruction stream you just generated is not enough to make Wasm work. Wasm requires all code to be packaged up inside a proper function. To do this, you need to deconstruct function definitions into parts. Consider the following Wabbit function:
func spam(x int, y int) int {
var z int;
z = x + y;
return z;
}
The function consists of three different parts. There is a textual
name 'spam'
, a type signature (int, int)->int
, and a function
body that contains the function code. In Wasm, these three components
are stored in separate tables.
In Wasm, a function type signature is expressed as a pair of tuples
containing the parameter and return types. For example, the signature
for spam()
above is:
[(i32, i32), (i32,)]
or if you fill in the raw type-codes:
[(b'\x7f', b'\x7f'), (b'\x7f',)]
To encode a signature into bytes, use the following function:
def encode_signature(argtypes, rettypes):
return b'\x60' + encode_vector(argtypes) + encode_vector(rettypes)
Type signatures for all functions are stored in a list. For example, suppose you had the following functions in your Wasm file:
func spam(x int, y int) int;
func square(x float) float;
func blah(x float, y int) float;
You will make a type-signature list like this:
signatures = [
encode_signature([i32, i32], [i32]), # spam
encode_signature([f64], [f64]), # square
encode_signature([f64, i32], [f64]), # blah
]
Carefully notice that the signature table contains no information about function names. For that, you need to maintain a separate dictionary that maps names to an associated type index. For example:
functions = {
'spam': 0, # Index refers to type signature table
'square': 1,
'blah': 2,
}
The code associated with each function is also stored in a table.
funccode = [
b'...', # Code for spam
b'...', # Code for square
b'...', # Code for blah
]
The code stored here is the same code that you’ve been making so far. However, some additional considerations must be made to handle local variables. Consider the following function again:
func spam(x int, y int) int {
var z int;
z = x + y;
return z;
}
This function has two parameters (x
, y
) and a local variable z
.
These variables are numbered starting at 0 (parameters go first). You
need to make a dict that maps variable names to numerical indices:
locals = {
'x': 0,
'y': 1,
'z': 2,
}
The following Wasm instructions are used to load/store local variables:
b'\x20' <localidx> => local.get
b'\x21' <localidx> => local.set
Here, localidx
is an unsigned integer index that refers to the
variable (the same index that’s stored in the locals
variable above).
The types of the function parameters are stored as part of the signature. However, the types of additional local variables (declared inside the function) must be stored in a separate list. So, you need to keep a separate record like this:
localtypes = [ b'\x01' + i32 ] # Type of z
It looks a little funny, but each local variable type is encoded with
b'\x01'+<typecode>
. The contents of this list are encoded as a
vector and prepended to the raw instruction code that you already
created. The entire function body (locals + code) is then prepended
by an integer length giving its size in bytes. Structurally, it’s going
to look like this:
[ length | locals | instructions ]
Last, but not least, you need to export your newly created function so that it can be accessed. To do that, you make an exports list like this:
exports = []
# An a function "name" to the exports list
exports.append(encode_name(name) + b'\x00' + encode_unsigned(functions[name]))
This is a lot to unpack, but here is a modified encoder that includes the necessary function support:
def encode_signature(argtypes, rettypes):
return b'\x60' + encode_vector(argtypes) + encode_vector(rettypes)
class WasmEncoder:
def __init__(self):
# Global variables
self.global_defns = [ ]
# Global variable symbol table mapping names to declarations
self.globals = { }
# Function type signatures
self.signatures = [ ]
# Function name -> signature map
self.functions = { }
# Function bodies
self.funccode = [ ]
# Exported functions
self.exports = [ ]
def encode_function(self, name, parmnames, parmtypes, rettypes, code):
self.functions[name] = len(self.signatures)
self.signatures.append(encode_signature(parmtypes, rettypes))
self.exports.append(encode_name(name) + b'\x00' + encode_unsigned(self.functions[name]))
# Create the local variable mapping
self.locals = { pname: n for n, pname in enumerate(parmnames) }
self.localtypes = [ ]
# Emit instructions
self.wcode = b''
for op, *opargs in code:
getattr(self, f'encode_{op}')(*opargs)
# Put a block terminator on the code
self.wcode += b'\x0b'
# Save the function code body
code = encode_vector(self.localtypes) + self.wcode
self.funccode.append(encode_unsigned(len(code)) + code)
... rest unchanged ...
# Example use
encoder = WasmEncoder()
encoder.encode_function("main", [], [], [i32], code)
If you run this code and inspect various attributes of the encoder, you should see the following:
>>> encoder.signatures
[b'`\x00\x01\x7f']
>>> encoder.functions
{'main': 0}
>>> encoder.funccode
[b'\x19\x00A\x04$\x00A\x05$\x01#\x00#\x00l#\x01#\x01lj$\x02#\x02\x0b']
>>> encoder.exports
[b'\x04main\x00\x00']
>>>
We’re almost at a point where you can make something run. The last step is to make a proper Wasm module.
Encoding a Module
Your final step in encoding Wasm is to make an encoded module. A module is broken up into sections and looks like this:
+----------------------------+
Header : | b'\x00asm\x01\x00\x00\x00' |
+----------------------------+
Section 1 : | type signatures |
+----------------------------+
Section 3 : | function types |
+----------------------------+
Section 6 : | globals |
+----------------------------+
Section 7 : | exports |
+----------------------------+
Section 10 : | function code |
+----------------------------+
There are other optional sections that are not needed right now. The encoding of each section is a 1-byte section number, a section length, and section contents. Write the following functions:
def encode_section(sectnum, contents):
return bytes([sectnum]) + encode_unsigned(len(contents)) + contents
The contents of each section is encoded as a vector. So, to encode section 1 for instance, you would do this:
encode_section(1, encode_vector(signatures))
Put all of this together by adding an encode_module()
method like
this:
class WasmEncoder:
...
def encode_module(self):
module = b'\x00asm\x01\x00\x00\x00'
module += encode_section(1, encode_vector(self.signatures))
vec = [encode_unsigned(v) for v in self.functions.values()]
module += encode_section(3, encode_vector(vec))
module += encode_section(6, encode_vector(self.global_defns))
module += encode_section(7, encode_vector(self.exports))
module += encode_section(10, encode_vector(self.funccode))
return module
# Example use:
encoder = WasmEncoder()
encoder.encode_function("main", [], [], [i32], code)
with open('out.wasm', 'wb') as file:
file.write(encoder.encode_module())
Put this in your file and run it. You should get a file out.wasm
written in the current directory.
Loading it in the Browser
Wasm doesn’t run by itself. It needs to be launched from Javascript.
Create a file hello.html
that contains the following HTML and
Javascript:
<html>
<body>
<h3>Program Output</h3>
<pre id="myout">The output is: </pre>
<script>
var imports = { };
fetch("out.wasm").then(response =>
response.arrayBuffer()
).then(bytes =>
WebAssembly.instantiate(bytes, imports)
).then(results => {
window.main = results.instance.exports.main;
out = window.main();
document.getElementById("myout").innerHTML += out + "\n";
});
</script>
</body>
</html>
In this code, the out.wasm
file is fetched and instantiated into a WebAssembly
instance. The main()
function is lifted out of the instance exports
section. When called, its output is appended to the HTML in the <pre>
section at the top.
To test this, go to the command line and the same directory as the hello.html
and out.wasm
file. Run the following Python command:
bash % python3 -m http.server
This launches a web server. Now click on http://localhost:8000/hello.html. You should see an output of "41". If you see nothing, open the JavaScript dev console in your browser, reload, and look for error messages. Even the slightest error in encoding your module will cause it to fail. Ask for help if stuck.
Building the Runtime
Wasm is extremely low-level and minimal. Keep in mind you only get integers and floats.
There are no strings. Or even any built-in functions! Wasm doesn’t get access to
any part of Javascript or the browser environment all by itself. This
presents certain logistical problems. For example, how do you implement the
PRINTI
instruction?
The solution here is the same as the solution in LLVM! If you want printing,
you implement it in JavaScript, not Wasm. Go to the hello.html
file and
modify the code so it looks like this:
<html>
<body>
<h3>Program Output</h3>
<pre id="myout">The output is: </pre>
<script>
var imports = {
runtime : {
_printi: (x) => { document.getElementById("myout").innerHTML += x + "\n"; },
}
};
fetch("out.wasm").then(response =>
response.arrayBuffer()
).then(bytes =>
WebAssembly.instantiate(bytes, imports)
).then(results => {
window.main = results.instance.exports.main;
window.main();
});
</script>
</body>
</html>
Carefully observe that we have added a _printi()
function to the
imports
variable. The original output at the end has been
removed.
To make the _printi
function available to Wasm, it has to be explicitly
imported. This is done by making import records and making a few minor
modifications as shown in this extension to the encoder:
class WasmEncoder:
def __init__(self):
...
# Imported functions
self.imports = [ ]
def import_function(self, module, name, parmtypes, rettypes):
assert not self.exports, "All imported functions must be declared first"
self.functions[name] = len(self.signatures)
self.signatures.append(encode_signature(parmtypes, rettypes))
self.imports.append(encode_name(module)+encode_name(name)+b'\x00' +
encode_unsigned(self.functions[name]))
...
def encode_module(self):
module = b'\x00asm\x01\x00\x00\x00'
module += encode_section(1, encode_vector(self.signatures))
# --- Next two lines added/modified. Don't forget slice on 2nd line!
module += encode_section(2, encode_vector(self.imports))
vec = [encode_unsigned(v) for v in self.functions.values()][len(self.imports):]
# ---
module += encode_section(3, encode_vector(vec))
module += encode_section(6, encode_vector(self.global_defns))
module += encode_section(7, encode_vector(self.exports))
module += encode_section(10, encode_vector(self.funccode))
return module
...
# Call the imported '_printi' function
def encode_PRINTI(self):
self.wcode += b'\x10' + encode_unsigned(self.functions['_printi'])
To use this new encoder, you need to declare the imported runtime function and fiddle a bit with type signatures. Do this:
encoder = WasmEncoder()
# Declare the runtime function
encoder.import_function("runtime", "_printi", [i32], [])
# Encode main(). Note: Return type changed to [].
encoder.encode_function("main", [], [], [], code)
# Write out the module
with open('out.wasm', 'wb') as file:
file.write(encoder.encode_module())
Try running your code to produce another out.wasm
file and reload the hello page
in the browser. You should see output being produced as before. If not, you’ll
have to do some debugging. Whew! That was some work.
A Wasm Mini Reference
This section provides a short reference of useful Wasm instructions and data encoding
Types:
b'\x7f' => i32
b'\x7c' => f64
It is usually easier to make aliases for the types:
i32 = b'\x7f'
f64 = b'\x7c'
To define constants corresponding to the above types, do this:
b'\x41' <value> => i32.const value
b'\x44' <value> => f64.const value
The <value>
needs to be encoded using encoded_signed()
or encode_f64()
depending
on the type.
Here are some useful opcodes for math:
b'\x6a' => i32.add
b'\x6b' => i32.sub
b'\x6c' => i32.mul
b'\x6d' => i32.div_s
b'\xa0' => f64.add
b'\xa1' => f64.sub
b'\xa2' => f64.mul
b'\xa3' => f64.div
To access a global variable, use these load and store instructions:
b'\x23' <globalidx> => global.get
b'\x24' <globalidx> => global.set
To access a local variable, use load and store instructions:
b'\x20' <localidx> => local.get
b'\x21' <localidx> => local.set
To call a function:
b'\x10' <funcidx> => call (funcidx is function index)
More instructions can be found in the Wasm official specification.
Complete Encoder
Here is the source code for the complete encoder developed in this part:
code = [
('GLOBALI', 'x'),
('CONSTI', 4),
('STORE', 'x'),
('GLOBALI', 'y'),
('CONSTI', 5),
('STORE', 'y'),
('GLOBALI', 'd'),
('LOAD', 'x'),
('LOAD', 'x'),
('MULI',),
('LOAD', 'y'),
('LOAD', 'y'),
('MULI',),
('ADDI',),
('STORE', 'd'),
('LOAD', 'd'),
('PRINTI',)
]
def encode_unsigned(value):
'''
Produce an LEB128 encoded unsigned integer.
'''
parts = []
while value:
parts.append((value & 0x7f) | 0x80)
value >>= 7
if not parts:
parts.append(0)
parts[-1] &= 0x7f
return bytes(parts)
def encode_signed(value):
'''
Produce a LEB128 encoded signed integer.
'''
parts = [ ]
if value < 0:
# Sign extend the value up to a multiple of 7 bits
value = (1 << (value.bit_length() + (7 - value.bit_length() % 7))) + value
negative = True
else:
negative = False
while value:
parts.append((value & 0x7f) | 0x80)
value >>= 7
if not parts or (not negative and parts[-1] & 0x40):
parts.append(0)
parts[-1] &= 0x7f
return bytes(parts)
assert encode_unsigned(624485) == bytes([0xe5, 0x8e, 0x26])
assert encode_unsigned(127) == bytes([0x7f])
assert encode_signed(-624485) == bytes([0x9b, 0xf1, 0x59])
assert encode_signed(127) == bytes([0xff, 0x00])
def encode_vector(items):
'''
A size-prefixed collection of objects. If items is already
bytes, it is prepended by a length and returned. If items
is a list of byte-strings, the length of the list is prepended
to byte-string formed by concatenating all of the items.
'''
if isinstance(items, bytes):
return encode_unsigned(len(items)) + items
else:
return encode_unsigned(len(items)) + b''.join(items)
import struct
def encode_f64(value):
'''
Encode a 64-bit float point as little endian
'''
return struct.pack('<d', value)
def encode_name(name):
'''
Encode a text name as a UTF-8 vector
'''
return encode_vector(name.encode('utf-8'))
def encode_signature(argtypes, rettypes):
return b'\x60' + encode_vector(argtypes) + encode_vector(rettypes)
def encode_section(sectnum, contents):
return bytes([sectnum]) + encode_unsigned(len(contents)) + contents
i32 = b'\x7f'
f64 = b'\x7d'
class WasmEncoder:
def __init__(self):
# Global variables
self.global_defns = [ ]
# Global variable symbol table mapping names to declarations
self.globals = { }
# Function type signatures
self.signatures = [ ]
# Function name -> signature map
self.functions = { }
# Function bodies
self.funccode = [ ]
# Exported functions
self.exports = [ ]
# Imported functions
self.imports = [ ]
def import_function(self, module, name, parmtypes, rettypes):
assert not self.exports, "All imported functions must be declared first"
self.functions[name] = len(self.signatures)
self.signatures.append(encode_signature(parmtypes, rettypes))
self.imports.append(encode_name(module)+encode_name(name)+b'\x00' + encode_unsigned(self.functions[name]))
def encode_function(self, name, parmnames, parmtypes, rettypes, code):
self.functions[name] = len(self.signatures)
self.signatures.append(encode_signature(parmtypes, rettypes))
self.exports.append(encode_name(name) + b'\x00' + encode_unsigned(self.functions[name]))
# Create the local variable mapping
self.locals = { pname: n for n, pname in enumerate(parmnames) }
self.localtypes = [ ]
# Emit instructions
self.wcode = b''
for op, *opargs in code:
getattr(self, f'encode_{op}')(*opargs)
# Put a block terminator on the code
self.wcode += b'\x0b'
# Save the function code body
code = encode_vector(self.localtypes) + self.wcode
self.funccode.append(encode_unsigned(len(code)) + code)
def encode_module(self):
module = b'\x00asm\x01\x00\x00\x00'
module += encode_section(1, encode_vector(self.signatures))
module += encode_section(2, encode_vector(self.imports))
vec = [encode_unsigned(v) for v in self.functions.values()][len(self.imports):]
module += encode_section(3, encode_vector(vec))
module += encode_section(6, encode_vector(self.global_defns))
module += encode_section(7, encode_vector(self.exports))
module += encode_section(10, encode_vector(self.funccode))
return module
def encode_CONSTI(self, value):
self.wcode += b'\x41' + encode_signed(value)
def encode_ADDI(self):
self.wcode += b'\x6a'
def encode_MULI(self):
self.wcode += b'\x6c'
def encode_PRINTI(self):
self.wcode += b'\x10' + encode_unsigned(self.functions['_printi'])
def encode_GLOBALI(self, name):
self.globals[name] = len(self.global_defns)
self.global_defns.append(i32 + b'\x01\x41' + encode_signed(0) + b'\x0b')
def encode_STORE(self, name):
self.wcode += b'\x24' + encode_unsigned(self.globals[name])
def encode_LOAD(self, name):
self.wcode += b'\x23' + encode_unsigned(self.globals[name])
encoder = WasmEncoder()
encoder.import_function("runtime", "_printi", [i32], [])
encoder.encode_function("main", [], [], [], code)
with open('out.wasm', 'wb') as file:
file.write(encoder.encode_module())


--- layout: page title: About header-img: "img/about-bg.png" ---
Follow the transition of my career change from Healthcare to Web Development. I will share my highs and lows and all the wonderful knowledge I will absorb.


VIDUALS
Your browser does not support the video tag.
Roll
Your browser does not support the video tag.
Disparate Youth
Your browser does not support the video tag.
Kool Aid
Your browser does not support the video tag.
Acid Rain
Your browser does not support the video tag.
Brush The Heat
Your browser does not support the video tag.
Say That
Your browser does not support the video tag.
Taken For A Fool
Your browser does not support the video tag.
Best Part
Your browser does not support the video tag.


Thread de Emails
from: {{threadEmail.email.sender}}
to: {{threadEmail.email.recipient}}
{{threadEmail.email.subject}}
{{threadEmail.email.content}}


What Do I Like To Do😄:
I spend most of my time reading, writing, and doodling!
I love to do Zumba. I love to strum my guitar and violin once in a while!
I try to do what every other engineering students do; code.
I actively participate in social services and social works. I work for the third and fourth SDG.
I love learning new things and always hunts for new opportunities!
Education🏫
(I)Undergraduate student in Govt Model Engineering College(2019-2023):
Electronics and Communication Department.
(II)Bhavans Vidya Mandir Girinagar(2007-2019):
Class I-XII
Positions Held🌟
World Literacy Foundation Ambassador 2020
Social Media Head DSC MEC 2020
Student Head of Electronics and Communication Dept IETE MEC
Content Volunteer IEEE Computer Society Kerala Chapter


Jon O. is our client-facing team leader. He is in charge of communication & gathering project requirements.
Nik is our key concept holder on the software side of things.
Korbin is our electrical/hardware concept holder.
Dan is in charge team communicaton and scheduling.
Jon H. is our website lead, publishing and updating web documents.
Alliant Energy Corporation (NYSE: LNT), headquartered in Madison, Wis., provides regulated electric and natural gas service to about 950,000 electric and 410,000 natural gas customers in Iowa and Wisconsin. Alliant Energy’s mission is to deliver energy solutions and exceptional service customers and communities count on – safely, efficiently and responsibly. Interstate Power and Light Company and Wisconsin Power and Light Company are Alliant Energy’s two public utility subsidiaries. For more information, please visit AlliantEnergy.com.


for i_episode in range(MAX_EPISODE):
episode_time = time.time()
s = env.reset()
t = 0 // number of step in this episode
all_r = [] // rewards of all steps
while True:
if RENDER: env.render()
After Change
for i_episode in range(MAX_EPISODE):
episode_time = time.time()
s = env.reset().astype(np.float32)
t = 0 // number of step in this episode
all_r = [] // rewards of all steps
while True:
if RENDER: env.render()


Todo-ism is a simple but effective todo list app built using AngularJS, Node.js and BlueMix.
- Add/delete as many lists as you like.
- Add/delete todos. Mark them done as they get completed.
- Lightning fast search for existing lists and todos.
- Track different project todos by creating a todo list for each project.
- Managers and team leads track their team's todos. Just create a new list for each person.
Check out the code at:
https://github.com/daudahmad/todoism
For queries and suggestions:
Daud Ahmad
daudak@pk.ibm.com


#include <russian_stem.h>
Public Member Functions | |
| void | operator() (string_typeT &text) |
Private Member Functions | |
| void | step_1 (string_typeT &text) |
| void | step_2 (string_typeT &text) |
| void | step_3 (string_typeT &text) |
| void | step_4 (string_typeT &text) |
| void stemming::russian_stem< string_typeT >::operator() | ( | string_typeT & | text | ) | [inline] |
| text | string to stem |
| void stemming::russian_stem< string_typeT >::step_1 | ( | string_typeT & | text | ) | [inline, private] |
Step 1: Search for a PERFECTIVE GERUND ending. If one is found remove it,
and that is then the end of step 1. Otherwise try and remove a REFLEXIVE ending,
and then search in turn for
(1) an ADJECTIVAL,
(2) a VERB or
(3) a NOUN ending.
As soon as one of the endings (1) to (3) is found remove it, and terminate step 1.
| void stemming::russian_stem< string_typeT >::step_2 | ( | string_typeT & | text | ) | [inline, private] |
If the word ends with и, then remove it.
| void stemming::russian_stem< string_typeT >::step_3 | ( | string_typeT & | text | ) | [inline, private] |
Search for a DERIVATIONAL (ост, ость) ending in R2 (i.e., the entire ending must lie in R2), and if one is found, then remove it.
| void stemming::russian_stem< string_typeT >::step_4 | ( | string_typeT & | text | ) | [inline, private] |
(1) Undouble н, or
(2) if the word ends with a SUPERLATIVE (ейш or ейше) ending, remove it and undouble н, or
(3) if the word ends ь then remove it.


Main Page
About The Shop:
Hello All Customer We open At 6AM Until At 7PM Wellcome All
Our Branches:
Seattle
Tokyo
Dubai
Paris
Lima


Why not?
Still working out some CSS issues... Check back 2/18/20.
I realize this may cost me a few interviews.
Used FullCalendar.io


VISIT SITE
Bastian bux is the consequence of reducing everything surrounding a dj and producer to its essential element: the music. that is the intention of bux: be stripped of all artifice and be judged by his work.
VISIT SITE
A system that young people around the world with a club culture and techno enthusiasts feel identified. We generated a simple logo that is the basis for generating a geometric and liquid system.


I have over 12 years of experience in motion graphics and interactive production. I've worked on a wide variety of projects including websites, banners, out of home, digital billboards, pitches and various web/app/AR/VR prototypes.
Skills include: Photoshop • Illustrator • After Effects • HTML5/js/CSS • Trapcode Suite • Rowbyte Plexus • GSAP (Greensock Animation Platform) • Digital & Traditional Illustration • Timeline & Programmatic Animation • SVG animation • Cinemagraphs • GIFs • Flash
Working knowledge of: Cinema 4D • Sass • Node • Grunt • jQuery • Bootstrap • Unreal Engine 4 • Unity3D • Processing • Augmented Reality • Virtual Reality
Vendors: Sizmek • DoubleClick (DCM + Studio) • Atlas • FlashTalking


{% load staticfiles %}
We suppose the dead pages were not what you were looking for. So please go to our homepage.


| Client's name and final decision maker | John Han |
|---|---|
| Client's business (website) name | Lee Energy |
| Redesign or brand new website | Brand new website |
| Type of website | Informational, Marketing |
| Client's goals | He wants to build a website that helps customers easily find out and access information about his business in order to expand his business and make it more professional. |
| Audience(s) | Issues, Concerns, Needs | Approach |
|---|---|---|
ClientsAges 35 and up, male & female. They are small business or grocery store owners. They are computer savvy, using PC, Mac, and Smart Phone with Varied resolution sizes. |
|
|
VendorsThey are the companies that sell energy-efficient electrical products. Ages 22 and up, male & female, Computer savvy, Using PC, Mac and Smart Phone with Varied resolution sizes, Always online with varied connections |
|
|
PartnersThey are the public utility providers. Ages 22 and up, male & female, Computer savvy, Using PC, Mac and Smart Phone with Varied resolution sizes, Always online with varied connections |
|
|


{% extends "base.html" %} {% load bootstrap %} {% load i18n %} {% block page_title %}Greendoors Mail{% endblock %} {% block body_class %}{{ block.super }}{% endblock %} {% block content %}
Thank you for your downloading the Bristol Green Doors app. This page explains how any personal data collected in the process of using this application will be stored and used.
Your email address will be used to provide you with a personalised list of the features you scanned during the Bristol Green Doors weekend of 13-14 September.
If you have opted in to taking part in the University of Bristol research study, we will be in touch about the next stage of the research when it is ready. This may involve an online survey or an interview, and a financial incentive in the form of gift vouchers will be provided to compensate for your time. You can opt-out at any time, and submission of your email address does not obligate you to participate in the study. If you have previously opted out but would like to participate, please send us an email.
If you have opted in to receiving information from Bristol Green Doors, you will be added to the mailing list for their monthly newsletter, which provides helpful information about how to save energy and money. They may also contact you about future Bristol Green Doors events. To opt out, send us an email.
Your email address will only be used for these purposes and will not be passed on to any third parties.
The details about the QR codes scanned are held in order to provide you with a personalised report, which you can access on the website. Information about how the app is used, such as which buttons are pressed, are also collected in order to determine which features are most or least popular.
Information about user behaviour and frequency of features used will be used to improve the user experience. The links provided in the personalised report will be tracked to so that University of Bristol can determine the effectiveness of the Bristol Green Doors and their events. Anonymous data may be written up and published or shared in the academic community.
Anonymous data may be written up and published or shared in the academic community.
Your email address and the data collected will be stored for the duration of the Digital Green Doors study.
The University of Bristol is your data controller. As your data controller, the University has notified its activities to the Office of the Information Commissioner as required under the Data Protection Act 1998 (the "Act") and is listed in the Public Register of Data Controllers. Personal information will only be collected and/or processed by the University in accordance with the Act.
Except as set out in this policy or as required by law, your personal data will not be provided to any third party without your prior written consent
The information you provide to us will be held on our computers in the UK. It may be accessed by or given to third parties some of whom may be located outside the European Economic Area who act for us for the purposes set out in this policy or for other purposes approved by you. Those parties process information and may provide support services to the University or on the University's behalf.
Countries outside the European Economic Area do not always have strong data protection laws. However, we will always take steps to ensure that your information is used by third parties in accordance with this policy.
{% endblock %}


Below is a link to my portfolio on GitHub. It contains everything I have done independently or in pairs to this date.


On August 27, 2015, Linda Heilpern passed away. During the 10 years of running her business, Cooking Light with Lotsa Flavor, she hosted unique food events, delivered home-cooked meals and provided cooking classes. Her dedication to the art of preparing delicious, satisfying food was greatly enhanced by her warm, playful and generous nature. She truly delighted in sharing her passion for cooking with others, and in doing so she touched the lives of hundreds of people.
 The people who give you their food give you their heart."
Friends, clients or students of Linda's who would like to share their memories are encouraged to contact her family by e-mailing to linda@lotsaflavor.com.


Benefits of up to Rs 1.6 lakh on Jeep Compass
by Jaiveer MehraJeep dealers are offering substantial benefits on the 2019 model year Compass all through November 2019.
Jeep is offering big discounts on select variants of the Compass all through November. The Compass SUV is being offered with benefits of up to Rs 1.6 lakh on select engine-gearbox combinations and trim levels.
The entry-level Sport trim can be had with benefits of up to Rs 1.6 lakh for the 4x2 diesel model, while the petrol equivalent comes with benefits of up to Rs 70,000. The Sport Plus is being offered with substantial benefits of up to Rs 1.1 lakh for the diesel variant, and up to Rs 50,000 for the petrol.
The Longitude, Longitude (O) and Limited trims in diesel-manual 4x2 spec are being offered with benefits of up to Rs 1.4 lakh, with the Limited (O) trim getting more substantial discounts of up to Rs 1.6 lakh.
In comparison, the petrol-automatic Longitude (O) and Limited trims get benefits of up to Rs 1.1 lakh, and the Limited (O) trims comes at a discount of Rs 1.40 lakh.
The above-mentioned benefits do not apply to the Limited Plus, Limited Plus 4x4, Limited 4X4 and Trailhawks.
The Compass is available with two engine options – a 173hp, 2.0-litre turbo-diesel and a 163hp, 1.4-litre turbo-petrol. The diesel mill is available in both BS4 and BS6 spec (the latter offered only in the Trailhawk). The BS4-compliant unit is paired with a 6-speed manual gearbox as standard, and the BS6-compliant unit is offered solely with a 9-speed automatic. The diesels also get an optional four-wheel drive on higher variants, a feature that's standard on the Trailhawk. The BS4-compliant petrol engine can be had with either a 6-speed manual or a 7-speed dual-clutch automatic gearbox.
Jeep is expected to give the Compass a mid-cycle facelift sometime next year and is also working on introducing the BS6-compliant diesel motor and 9-speed automatic gearbox from the Trailhawk on all variants in the Compass line-up. Also, the 1.4 turbo-petrol is set to be upgraded to meet BS6 norms.
Another model in the works is said to be a 7-seater derivative of the Compass but it isn't expected to launch before 2021.
As for its rivals, the Compass takes on the MG Hector, Tata Harrier and the Kia Seltos.
Disclaimer: Discounts vary from city to city. Please check with your local dealer for exact discounts, which may not match figures quoted here.
Jeep Compass
Rs 17.93 lakh * on road price (New Delhi)


A short history of computing
Feb 24, 2006
Today I rounded off our Year 6 unit on Victorian Mathematics (which I meant to do last half term, when it was still their history topic, but you know how it is…), with a very quick tour of some bits of the history of computing and calculation. I have my father’s old 7 figure log tables, slide rule and first Sinclair calculator, which makes it that bit more personal.
One really great thing is how easy all the education-technology makes it to teach such anachronistic topics as slide rules: being able to demonstrate one on the big board via a visualizer is so much easier than holding up our yard long wooden demonstration slide rule that I found in the maths store. And of course there’s a virtual slide rule on the net for them to practise with.
Once I’d told them that log 10 was 1, and log 100 was 2, most of them got the idea, and a good number worked out log 0.1. Having convinced the class of the rules for multiplication, division, powers and roots, one bright spark asked “So what about things that don’t end in zeros?”, and so we had a go at using some log tables.
Another then wanted to know how they could work out the tables. I explained that they used computers, which was met with some scepticism. The notion that people used to be called computers struk them as really strange, but here’s the OED:
Computer: One who computes; a calculator, reckoner; spec. a person employed to make calculations in an observatory, in surveying, etc.
It then occured to them that this wasn’t a particularly reliable approach, which led us beautifully on to the story of Babbage and his Engines.
We had a look at some of the stuff from the Science Museum site, and they weren’t at all surprised to learn that the first programmer was a woman. Alas, I’ve not found a virtual Analytical Engine to show off, but I’ve put a link onto Moodle to a virtual Curta, so they can get something of a feel for mechanical calculators.
Homework’s a wiki based resarch task on and around Babbage. Coincidentaly, I spotted a piece in today’s TES about a calculator exhibition at Swindon’s Museum of Computing. School trip? Perhaps not.
Throughout the lesson, I had Dale Jone’s Pythonesque post in the the back of my mind.
http://eduspaces.net/mberry/weblog/8209.html
Share


This project template sets up the basic structure for a
Framework
Expansion Card.
This template is sized to fit in the 3D printable enclosure
that Framework has released, which allows for a larger PCB than
the aluminum housings that consumer Framework Expansion Cards use.
(c)2021 Framework Computer Inc


$projectname $projectnumber ($datetime)
Copyright AllSeen Alliance, Inc. All Rights Reserved.
AllSeen, AllSeen Alliance, and AllJoyn are trademarks of the
AllSeen Alliance, Inc in the United States and other jurisdictions.

MAY CONTAIN U.S. AND INTERNATIONAL EXPORT CONTROLLED INFORMATION


Innovation
Gesture Technology
Approaches
- Microsoft Kinect
- Webcams & GetUserMedia
- Other third-party, e.g. LeapMotion
Microsoft Kinect
- Provides 3D motion detection
- Originally for Xbox
- Windows version released Feb 2012
- OpenKinect: OpenSource community
- Very interesting but:
- Requires a Kinect (i.e. not ubiquitous)
- Requires significant programming effort
A local example
- NZPost Noise Ink, Auckland Arts Festival 2011
Webcams
- Webcams are (almost) ubiquitous
- New APIs (e.g. GetUserMedia) mean the browser can directly interact with the webcam
Webcam Swiper
- Basic recognition of movement between left and right sides of the screen
- Simply counts the number of pixels whose colour has changed
- The Webcam Swiper example
Browser compatibility
The way it works
- User navigates to URL
- Browser detects GetUserMedia call, and asks user for permission every time
The bigger picture
- GetUserMedia is part of WebRTC
- WebRTC aims to allow use of multimedia capture for peer-to-peer communication using the browser
- A.K.A the "Skype-killer"
Face detection: FaceKat
- A simple game using your face for navigation to avoid obstacles
- The example
The state of the art: Google
The state of the art: Toyota
Uses?
Potential for Learning Media
- Could create simple interactives that use the webcam to respond to gross movements
- Could use face detection to identify and interact with faces via webcam
- Watch out for "Gorilla Arm!"


Event Detail
New Event
Details
Comments
0">({{dtComment.length}})
User
{{user.U_NAME}}
Location
{{loc.Name}}
Start Date
Due Date
All Day
Business Partner
(No BP)
{{bp.CardName}}
Recurring Pattern
{{pat.Name}}
Created {{common.formatCreateDate(event.CntctDate, 'on ')}}
, by {{getUserName(event.AssignedBy)}}


Klopp says Gomez ‘better than good’ after Sterling clash
by Agency ReportLiverpool manager Jurgen Klopp said Friday that defender Joe Gomez was “better than good” after his altercation with England teammate Raheem Sterling earlier this month.
Manchester City forward Sterling initially clashed with Reds defender Gomez towards the end of the Premier League match between the sides on November 10 at Anfield.
The pair were then involved in a fracas the following day on England duty, with Sterling later apologising at a team meeting and on social media.
Sterling then sat out England’s Euro 2020 qualifier against Montenegro as punishment but returned to the starting line-up in the 4-0 victory over Kosovo on Sunday.
Klopp said Gomez, who was left with a scratch on his face following the clash, had not been affected by the incident and the German had no issues with how the situation was handled.
“He is good, better than good,” said Klopp. “The people involved were fine pretty quick. Things like this happen in football. Absolutely nothing to say about it.
“The FA (Football Association) dealt with it how they saw right and I cannot judge that as I was not aware of the circumstances.”
(AFP)


{% extends "base.html" %} {% block title %}Contact: {{ name }} — {{ block.super }}{% endblock %} {% block content %}
You need to join or sign in to send messages. Don't worry, we'll redirect you straight back here!


This application lets you search and view the boundaries of National Topographic System (NTS) maps, a
system used by Natural Resources Canada for providing general topographic maps of the country. It is not
meant to be replacement for published topographical maps, but simply a online lookup of these maps
based on name, title, and coordinates.
A map sheet is classified by a string containing a number identifying the 1:1,000,000 scale map series
that contains the sheet (e.g., 30), a letter identifying a 1:250,000 scale map area (e.g., M), and
finally a number identifying the 1:50,000 scale map sheet itself. The town of Lanigan, Saskatchewan,
for example, is found on the map 72P14.
In addition to its name, an NTS map has north, south, east, and west coordinates (expressed in terms of
latitude and longitude), as well as a title. The coordinates that bound 72P14 are:
- n = 52 lat
- s = 51.75 lat
- e = -105 lng
- w = -105.5 lng
and the title is
LANIGAN.
To use this application, press the search icon, enter a combination of the name, title, or coordinates
of the maps you want to locate, and press return. You can sort and page through the results and can click
on individual maps to see their boundaries.
- If the search results get in the way of the map, just close the control and press the search icon later when
you want to resume working with it.
- When searching on a name or title, a left-most substring search is performed. Searching on a title
value of LANG would result in LANG RIVER, LANGRUTH, LANGENBURG,
etc.
- When searching on a coordinate, a left-most matching-digit search is performed. Search on an coordinate
of 52.2 would result in 52.20, 52.25, 52.26, etc.
- When searching on more than one field, only records that match all entered values will be returned.
Although everyone is free to use this site, the information is provided on an "as is" basis with no
guarantees of completeness, accuracy, usefulness, or timeliness, and without any warranties of any
kind whatsoever, express or implied. As such, Mr. Staflund assumes no responsibility or liability
for any errors and omissions in the content of this site and advises everyone to use published topographical
maps for planning their trips.


Sorry, your browser does not support WebSockets (part of the HTML5 specification).
Please use a recent version of one of these browsers:
Google Chrome
(prefered):
Windows, Apple Mac, Linux
Firefox:
Windows, Apple Mac, Linux
Safari:
Windows, Apple Mac, iPad


Ammi Culture
Ammi Culture was originally founded in 2007 as an e-retail business for fringes and notions..
In 2014, it was rebranded to support personal and professional development, people engagement, and business strategy services.
More than an HR and business management consulting services, at the heart of Ammi Culture has always been the mission to foster the growth of knowledge and resources sharing in our collective communities (residential, workplace, professional, associations/interest groups).
No community exists in a vacuum. What we do in one directly influences what we experience through interactions with another.
Ammi is the Hebrew word for "My People." Culture is the shared ideas, customs, beliefs, knowledge, and behaviors of a group of people (community) appreciated through generational experiences.
"My People's Culture"
Because no two people, groups, or organizations are identical, Ammi Culture's services are fashioned to produce solutions that are unique to the individual, group, and organization with consideration for positive interactions of influence.
BIO- Kim Jackson
BIO- Kim Jackson
BIO- Kim Jackson is a staunch Business Management Professional with an expertise in Human Resources. With over 10 years of experience in the private, public, and non-profit sector she has proven the ability to drive change using realized insight and mastering the art of building relationships. Kim’s expertise and a passion for cultivating healthy, diverse, and inclusive workplace environments allows her to successfully deliver programs, policies, and processes that meet various needs across all disciplines in business.
Kim is able to operate at the highest level possible due to her dedication and desire for continued learning.She holds a BA in Global Business Management from the University of Phoenix, a MS in Human Resources Management from Villanova University, and a Certificate of Diversity and Inclusion, PHR from Cornell University.  In addition to serving the corporate world and her family, Kim has found time over the last six years to serve her local community center as well.
No matter what capacity, in every role, Kim has earned the respect and confidence of her colleagues. She continues to serve as professional development coach in formal and informal capacity. Whether it’s business development or servant leadership Kim continues to shine, creating impact wherever she goes, leaving an organization better than it was before she came.
Info
Industry
Human Resources
Headquarters
Type
Sole Proprietorship
Founded
2014
Specialties
Human Resources , Talent Acquisition Strategy, Performance Management , Compensation Strategy, Diversity and Inclusion Program Design, Employee Engagement Programs, HR Policy and Adminstration, Training and Development, Personal Development Coaching, Professional Development, and Business Management


The Only person you need to be better than
Is the person you were yesterday
The best preparation for tomorrow is doing your best today.
H. Jackson Brown, Jr.What we think, we become.
BuddhaMom says: alcohol is your enemy.
Jesus says: Love your enemy.
ME: i need one more enemy shot.

Norman Vincent PealeNothing is worth having, If comes easy.
Prove them if they are wrong. Apologize if you are.
Work until your IDOLS become your RIVALS.
DrakeIf it doesn't challenge you, it won't change you.
End is there where you stop.
Del Del Del Del Del Del Del Del Del Del
Del Del Del Del Del Del Del Del Del
Death works from home too
Stay focused and never give up.
Doesn't matter how good you are you will be replaced.
Dreams are just dreams until you make them reality.
Be the change you want to see in the world.
Talk is cheap, show me the code.
Quite people have the loudest minds .
I look at people and think, really?
that's the sperm that won?!


--- layout: post title: Net::SSH 1.1.2 post_id: 86 categories: - announcements date: 2007-06-18 12:40:00.000000000 -06:00 author: Jamis permalink: 2007/6/18/net-ssh-1-1-2.html ---
Net::SSH 1.1.2 is now available! You can install it via RubyGems:
gem install net-ssh
Or download the source package of your choice from the project site:
http://rubyforge.org/frs/?group_id=274&release_id=12444
Net::SSH is a pure-Ruby implementation of the SSH2 client protocol. Version 1.1.2 is a bug-fix release, and addresses the following issues:
All users of Net::SSH 1.1.0 and 1.1.1 are encouraged to upgrade.


|
CppNoddy
0.92
|
#include <TrackerFile.h>
Public Member Functions | |
| TrackerFile (int prec=12) | |
| TrackerFile (std::string filename, int prec=12) | |
| ~TrackerFile () | |
| void | precision (unsigned prec) |
| void | push_ptr (double *scalar, std::string desc="") |
| void | push_ptr (D_complex *scalar, std::string desc="") |
| void | push_ptr (DenseVector< double > *ptr_to_vector, std::string desc="") |
| void | push_ptr (DenseVector< D_complex > *ptr_to_vector, std::string desc="") |
| void | push_ptr (OneD_Node_Mesh< double > *ptr_to_mesh, std::string desc="") |
| void | push_ptr (OneD_Node_Mesh< D_complex > *ptr_to_mesh, std::string desc="") |
| void | push_ptr (OneD_Node_Mesh< D_complex, D_complex > *ptr_to_mesh, std::string desc="") |
| void | newline () |
| void | set_filename (std::string filename) |
| void | header () |
| void | update () |
Protected Attributes | |
| std::ofstream | m_dumpFile |
Definition at line 17 of file TrackerFile.h.
| CppNoddy::TrackerFile::TrackerFile | ( | int | prec = 12 | ) |
Definition at line 12 of file TrackerFile.cpp.
| CppNoddy::TrackerFile::TrackerFile | ( | std::string | filename, |
| int | prec = 12 |
||
| ) |
Definition at line 16 of file TrackerFile.cpp.
References m_dumpFile.
| CppNoddy::TrackerFile::~TrackerFile | ( | ) |
Definition at line 23 of file TrackerFile.cpp.
References m_dumpFile.
| void CppNoddy::TrackerFile::header | ( | ) |
Definition at line 81 of file TrackerFile.cpp.
References m_dumpFile, and CppNoddy::Utility::stringify().
Referenced by main().
| void CppNoddy::TrackerFile::newline | ( | ) |
| void CppNoddy::TrackerFile::precision | ( | unsigned | prec | ) |
| void CppNoddy::TrackerFile::push_ptr | ( | D_complex * | scalar, |
| std::string | desc = "" |
||
| ) |
Definition at line 32 of file TrackerFile.cpp.
| void CppNoddy::TrackerFile::push_ptr | ( | DenseVector< D_complex > * | ptr_to_vector, |
| std::string | desc = "" |
||
| ) |
Definition at line 47 of file TrackerFile.cpp.
| void CppNoddy::TrackerFile::push_ptr | ( | DenseVector< double > * | ptr_to_vector, |
| std::string | desc = "" |
||
| ) |
Definition at line 42 of file TrackerFile.cpp.
| void CppNoddy::TrackerFile::push_ptr | ( | double * | scalar, |
| std::string | desc = "" |
||
| ) |
Definition at line 27 of file TrackerFile.cpp.
Referenced by main().
| void CppNoddy::TrackerFile::push_ptr | ( | OneD_Node_Mesh< D_complex > * | ptr_to_mesh, |
| std::string | desc = "" |
||
| ) |
Definition at line 57 of file TrackerFile.cpp.
| void CppNoddy::TrackerFile::push_ptr | ( | OneD_Node_Mesh< D_complex, D_complex > * | ptr_to_mesh, |
| std::string | desc = "" |
||
| ) |
Definition at line 62 of file TrackerFile.cpp.
| void CppNoddy::TrackerFile::push_ptr | ( | OneD_Node_Mesh< double > * | ptr_to_mesh, |
| std::string | desc = "" |
||
| ) |
Definition at line 52 of file TrackerFile.cpp.
| void CppNoddy::TrackerFile::set_filename | ( | std::string | filename | ) |
Definition at line 70 of file TrackerFile.cpp.
References m_dumpFile.
Referenced by main().
| void CppNoddy::TrackerFile::update | ( | ) |
Definition at line 118 of file TrackerFile.cpp.
References m_dumpFile.
Referenced by main().
|
mutableprotected |
Definition at line 52 of file TrackerFile.h.
Referenced by header(), newline(), precision(), set_filename(), TrackerFile(), update(), and ~TrackerFile().
© 2012
R.E. Hewitt


Abandoned baby giraffe bonds with dog at animal orphanage
Jazz and Hunter have struck up an unlikely friendship at the The Rhino Orphanage in South Africa.
A baby giraffe abandoned at birth has befriended a dog after being rescued and taken to an animal orphanage in South Africa.
Resident watchdog Hunter quickly began to care for the newcomer, and orphanage caretaker Janie Van Heerden said the pair bonded immediately.


1. CHARTING THE FUTURE OF LIBRARIES
EdLab has been tracking developments affecting the future of libraries with a special interest in the implications for the renovation and future development of the Gottesman Libraries at Teachers College, the world's largest library dedicated to the study of education. Because EdLab is located within the Gottesman Libraries this project has special relevance and immediate opportunities for applying the results of investigations and analyses.
Efforts began during the 1999-2000 academic year with a series of seminars devoted to exploring the future of libraries, particularly those in academic settings. These seminars led to the identification of three new roles for academic libraries:
- A center of technology to support scholarship
- An intellectual social center
- A source for content and services beyond the campus
EdLab has been instrumental in positioning the Gottesman Libraries to play these new roles. EdLab designed PocketKnowledge, a digital archiving system that gathers and organizes the intellectual property of the college community as a foundation for further academic work. EdLab developed the Collaboration Support System to enhance the physical library as a "campus crossroads" to facilitate academic exchanges. EdLab created the Document Delivery System to provide access to course materials to students anywhere in the world.
EdLab staff have played a continuing role in the design of the renovation of Russell Hall to support next-generation library services. Led by the Media Design Group, EdLab staff have worked to enhance the design of the already renovated floors of Russell Hall through additional signage, technology, and furnishings, and they have been heavily involved in planning for the renovation of the fourth and fifth floors.


The Sample Dialog
- Original Dialog
- Dialog after sized bottom-right
- Dialog after sized left-top
Introduction
This resizable dialog class can automatically adjusts controls position
and/or size as dialog is sized. the reposition and resize is direction
sensitive (left and right, top and bottom can be handled differently
respectively) and behave one of six ways: NONE, RESIZE, REPOS, RELATIVE,
ZOOM, DELTA_ZOOM (see below for more information).
Background
This class was derived from the Flicker-Free
Resizing Dialog (thanks Andy Brown). Andy Brown had solved the flicker
problem (which really puzzled me once) and his class supports resizing in
NONE, RESIZE, REPOS, RELATIVE mode.
However I need more controllable reposition and/or resize handler, I
think someone else need it too. So I enhanced Andy Brown's class and wrote
this class which added the following features:
- Reposition and resize is direction sensitive. e.g. Andy Brown's
class treat dialog's sizing left and right as the same sizing
(x-direction). This class can treat them differently.
- Zoom control as dialog is zoomed.
- Be able to adjust more than one controls' position and/size
respectively, which are at the same X-/y-level. e.g. this class can
resize two controls which are at the same horizontal line as 50% as
dialog's changed-width, in another words, if dialog's width is increased
10 pixels, this class increase each control's width 5 pixels.
Using the code
- Add ResizeDlg.cpp and ResizeDlg.h to your project or
makefile;
- Add "#Include ResizeDlg.h" to stdafx.h file or your
dialog header file;
- Make your dialog-derived class inherit from
CResizeDlg
instead of CDialog by replacing all instances of
"CDialog " with "CResizeDlg " in your dialog
header and implementation files.
- Add a handler for
WM_INITDIALOG in your dialog class if
you haven't done so, as described below.
WM_INITDIALOG (OnInitDialog)
In your OnInitDialog handler you should call the base
class's OnInitDialog and call AddControl for
those controls that are to be automatically repositioned and/or sized when
the dialog is sized. here is an example.
BOOL CMyDialog::OnInitDialog()
{
CResizeDlg::OnInitDialog();
AddControl(IDOK, CST_REPOS, CST_REPOS, CST_NONE, CST_NONE, 1);
AddControl(IDCANCEL, CST_REPOS, CST_REPOS, CST_NONE, CST_NONE, 1);
return TRUE;
}
How Controls Reposition and/or Size
This class allow controls dynamically repositioned and/or sized in each
direction (left, top, right, bottom) as one of the following ways.
CST_NONE |
do not reposition and size in this direction; |
CST_RESIZE |
size controls as much as dialog's changed-size in
this direction.
ctrlRect.right += deltaX; |
CST_REPOS |
reposition controls as much as dialog's change-size
in this direction.
ctrlRect.left += deltaX;
ctrlRect.right += deltaX; |
CST_RELATIVE |
reposition controls with user-defined proportion
(make controls always at the same proportional position in dialog).
newCx = ctrlRect.Width();
ctrlRect.left = (int)(m_xRatio *
pnRect->Width() - newCx / 2.0);
ctrlRect.right = ctrlRect.left + newCx; |
CST_ZOOM |
reposition and size controls automatically
ctrlRect.left = (int)(1.0 * ctrlRect.left
* (double)pnRect->Width() / pR0->Width());
ctrlRect.right = (int)(1.0 * ctrlRect.right
* (double)pnRect->Width() / pR0->Width()); |
CST_DELTA_ZOOM |
reposition and size controls proportionally, both
proportion can be set respectively.
newCx = ctrlRect.Width();
ctrlRect.right = (int)(ctrlRect.left +
deltaX0 * m_xRatio + newCx + deltaX0 * m_cxRatio);
ctrlRect.left += (int)(deltaX0 * m_xRatio); |
Usage of AddControl
You should call AddControl to set how controls behave as
dialog is sized in OnInitDialog . It's prototype as
below:
void AddControl( UINT nID, int xl, int xr, int yt,
int yb, int bFlickerFree = 0,
double xRatio = -1.0, double cxRatio = -1.0,
double yRatio = -1.0, double cyRatio = -1.0 ); where
nID |
control's resource ID |
xl |
how controls reposition and/or resize when dialog
resize left. set it one of CST_xx. |
xr |
how controls reposition and/or resize when dialog
resize right. set it one of CST_xx. |
yt |
how controls reposition and/or resize when dialog
resize top. set it one of CST_xx. |
yb |
how controls reposition and/or resize when dialog
resize bottom. set it one of CST_xx. |
bFlickerFree |
whether try to avoid flickering when reposition
and/or resize this control |
xRatio |
user-defined x-direction reposition proportion.
valid only when xl or xr is CST_RELATIVE or CST_DELTA_ZOOM. set it
to 0.0~1.0. |
cxRatio |
user-defined x-direction resize proportion. valid
only when xl or xr is CST_DELTA_ZOOM. set it to 0.0~1.0. |
yRatio |
user-defined y-direction reposition proportion.
valid only when yt or yb is CST_RELATIVE or CST_DELTA_ZOOM. set it
to 0.0~1.0. |
cyRatio |
user-defined y-direction resize proportion. valid
only when yt or yb is CST_DELTA_ZOOM. set it to
0.0~1.0. |
Typical use of AddControl
- keep a edit control resize horizontally as dialog sized.
AddControl(edit-ID, CST_RESIZE, CST_RESIZE,
CST_NONE, CST_NONE, 1);
- keep a top-right button at the same top-right position.
AddControl(button-ID, CST_REPOS, CST_REPOS,
CST_NONE, CST_NONE, 1);
- Keep a button at the fixed distance to bottom and horizontal-center.
AddControl(button-ID, CST_RELATIVE, CST_RELATIVE,
CST_REPOS, CST_REPOS, 1, 1.0);
- two edit controls are in a horizontal-line, make left edit control
resize and right one keep the same size when dialog left-sized, or left
one keep the same size and right one resize when dialog size right.
AddControl(left-edit-ID, CST_RESIZE,
CST_NONE, CST_NONE, CST_NONE, CST_NONE, 1);
AddControl(right-edit-ID, CST_REPOS,
CST_RESIZE, CST_NONE, CST_NONE, 1);
- two edit controls as example 4. make them size share the same of
dialog's changed-width. In another words, if dialog's width increase 10
pixels, then each of the edit-control increase its width 5 pixels
respectively.
AddControl(left-edit-ID, CST_DELTA_ZOOM, CST_DELTA_ZOOM,
CST_NONE, CST_NONE, 1, 0.0, 0.5);
AddControl(right-edit-ID, CST_DELTA_ZOOM, CST_DELTA_ZOOM,
CST_NONE, CST_NONE, 1, 0.5, 0.5); where
0.0, 0.5 means left-edit control do not
change its position and resize as 50% as dialog's changed-width.
0.5, 0.5 means right-edit control change its
position as 50%, because left control resize, so it must reposition, and
resize as 50% as dialog's changed-width.
Attention
- Resize-grip (, at the bottom-right of dialog) 's resource ID
(IDC_DLGSIZEBOX) is defined in ResizeDlg.h. You should set it another
unused resource ID if you have used it in somewhere else.
- Do not set flicker-free for group-controls in dialog (set
bFlickerFree to 0 in calling AddControl ).
History
- Sep 26, 2004 -Initial public release.
Robert Python
|
Click here
to view Robert Python's online profile. |
Other popular Dialog and Windows articles:
|
|
|


Before Change
"{0}MoleculeType")):
mon_name = m.get("id")
sites = []
states = {}
for ctype in m.iterfind(_ns("{0}ListOfComponentTypes/"
"{0}ComponentType")):
c_name = ctype.get("id")
sites.append(c_name)
After Change
if states_list is not None:
for s in states_list.iterfind(_ns("{}AllowedState")):
state = s.get("id")
if re.match("[0-9]*$", state):
new_state = "_" + state
while new_state in states[c_name]:
new_state = "_" + new_state
self._renamed_states[mon_name][state] = \
new_state
state = new_state
states[c_name].append(state)
if self._renamed_states[mon_name]:
self._log.info("Monomer "{}" states were renamed as "
"follows: {}".format(


| 16357 |
READ_PHONE_STATE |
getLine1Number |
activity |
onCreate |
Unknown |
android.intent.action.MAIN |
Unknown |
| 16358 |
READ_PHONE_STATE |
getSubscriberId |
activity |
onCreate |
Unknown |
android.intent.action.MAIN |
Unknown |
| 16359 |
READ_PHONE_STATE |
getDeviceId |
activity |
onCreate |
Unknown |
android.intent.action.MAIN |
Unknown |
| 37113 |
READ_PHONE_STATE |
getLine1Number |
activity |
onCreate |
Unknown |
android.intent.action.MAIN |
Unknown |
| 37114 |
READ_PHONE_STATE |
getSubscriberId |
activity |
onCreate |
Unknown |
android.intent.action.MAIN |
Unknown |
| 37115 |
READ_PHONE_STATE |
getDeviceId |
activity |
onCreate |
Unknown |
android.intent.action.MAIN |
Unknown |
| 61675 |
READ_PHONE_STATE |
getLine1Number |
activity |
onCreate |
Unknown |
android.intent.action.MAIN |
Unknown |
| 61676 |
READ_PHONE_STATE |
getSubscriberId |
activity |
onCreate |
Unknown |
android.intent.action.MAIN |
Unknown |
| 61677 |
READ_PHONE_STATE |
getDeviceId |
activity |
onCreate |
Unknown |
android.intent.action.MAIN |
Unknown |
| 78625 |
READ_PHONE_STATE |
getLine1Number |
activity |
onCreate |
Unknown |
android.intent.action.MAIN |
Unknown |
| 78626 |
READ_PHONE_STATE |
getSubscriberId |
activity |
onCreate |
Unknown |
android.intent.action.MAIN |
Unknown |
| 78627 |
READ_PHONE_STATE |
getDeviceId |
activity |
onCreate |
Unknown |
android.intent.action.MAIN |
Unknown |