Merge branch 'master' into 1100-local

Conflicts:
	lib/linguist/languages.yml
This commit is contained in:
Arfon Smith
2014-06-23 10:28:41 +01:00
185 changed files with 41417 additions and 888 deletions

2
.gitignore vendored
View File

@@ -1 +1,3 @@
Gemfile.lock
.bundle/
vendor/

View File

@@ -2,11 +2,8 @@ before_install:
- sudo apt-get install libicu-dev -y
- gem update --system 2.1.11
rvm:
- 1.8.7
- 1.9.2
- 1.9.3
- 2.0.0
- 2.1.1
- ree
notifications:
disabled: true

View File

@@ -1,7 +1,2 @@
source 'https://rubygems.org'
gemspec
if RUBY_VERSION < "1.9.3"
# escape_utils 1.0.0 requires 1.9.3 and above
gem "escape_utils", "0.3.2"
end

View File

@@ -106,8 +106,50 @@ To update the `samples.json` after adding new files to [`samples/`](https://gith
bundle exec rake samples
### A note on language extensions
Linguist has a number of methods available to it for identifying the language of a particular file. The initial lookup is based upon the extension of the file, possible file extensions are defined in an array called `extensions`. Take a look at this example for example for `Perl`:
```
Perl:
type: programming
ace_mode: perl
color: "#0298c3"
extensions:
- .pl
- .PL
- .perl
- .ph
- .plx
- .pm
- .pod
- .psgi
interpreters:
- perl
```
Any of the extensions defined are valid but the first in this array should be the most popular.
### Testing
Sometimes getting the tests running can be too much work, especially if you don't have much Ruby experience. It's okay: be lazy and let our build bot [Travis](http://travis-ci.org/#!/github/linguist) run the tests for you. Just open a pull request and the bot will start cranking away.
Here's our current build status, which is hopefully green: [![Build Status](https://secure.travis-ci.org/github/linguist.png?branch=master)](http://travis-ci.org/github/linguist)
### Releasing
If you are the current maintainer of this gem:
0. Create a branch for the release: `git checkout -b cut-release-vxx.xx.xx`
0. Make sure your local dependencies are up to date: `bundle install`
0. Ensure that samples are updated: `bundle exec rake samples`
0. Ensure that tests are green: `bundle exec rake test`
0. Bump gem version in `lib/linguist/version.rb`. For example, [like this](https://github.com/github/linguist/commit/8d2ea90a5ba3b2fe6e1508b7155aa4632eea2985).
0. Make a PR to github/linguist. For example, [#1238](https://github.com/github/linguist/pull/1238).
0. Build a local gem: `gem build github-linguist.gemspec`
0. Testing:
0. Bump the Gemfile and Gemfile.lock versions for an app which relies on this gem
0. Install the new gem locally
0. Test behavior locally, branch deploy, whatever needs to happen
0. Merge github/linguist PR
0. Tag and push: `git tag vx.xx.xx; git push --tags`
0. Push to rubygems.org -- `gem push github-linguist-2.10.12.gem`

View File

@@ -1,6 +1,8 @@
require File.expand_path('../lib/linguist/version', __FILE__)
Gem::Specification.new do |s|
s.name = 'github-linguist'
s.version = '2.10.12'
s.version = Linguist::VERSION
s.summary = "GitHub Language detection"
s.description = 'We use this library at GitHub to detect blob languages, highlight code, ignore binary files, suppress generated files in diffs, and generate language breakdown graphs.'
@@ -11,10 +13,10 @@ Gem::Specification.new do |s|
s.files = Dir['lib/**/*']
s.executables << 'linguist'
s.add_dependency 'charlock_holmes', '~> 0.6.6'
s.add_dependency 'escape_utils', '>= 0.3.1'
s.add_dependency 'charlock_holmes', '~> 0.7.3'
s.add_dependency 'escape_utils', '~> 1.0.1'
s.add_dependency 'mime-types', '~> 1.19'
s.add_dependency 'pygments.rb', '~> 0.5.4'
s.add_dependency 'pygments.rb', '~> 0.6.0'
s.add_development_dependency 'json'
s.add_development_dependency 'mocha'

View File

@@ -4,3 +4,4 @@ require 'linguist/heuristics'
require 'linguist/language'
require 'linguist/repository'
require 'linguist/samples'
require 'linguist/version'

View File

@@ -112,6 +112,12 @@ module Linguist
end
end
def ruby_encoding
if hash = detect_encoding
hash[:ruby_encoding]
end
end
# Try to guess the encoding
#
# Returns: a Hash, with :encoding, :confidence, :type
@@ -241,7 +247,31 @@ module Linguist
def lines
@lines ||=
if viewable? && data
data.split(/\r\n|\r|\n/, -1)
# `data` is usually encoded as ASCII-8BIT even when the content has
# been detected as a different encoding. However, we are not allowed
# to change the encoding of `data` because we've made the implicit
# guarantee that each entry in `lines` is encoded the same way as
# `data`.
#
# Instead, we re-encode each possible newline sequence as the
# detected encoding, then force them back to the encoding of `data`
# (usually a binary encoding like ASCII-8BIT). This means that the
# byte sequence will match how newlines are likely encoded in the
# file, but we don't have to change the encoding of `data` as far as
# Ruby is concerned. This allows us to correctly parse out each line
# without changing the encoding of `data`, and
# also--importantly--without having to duplicate many (potentially
# large) strings.
begin
encoded_newlines = ["\r\n", "\r", "\n"].
map { |nl| nl.encode(ruby_encoding, "ASCII-8BIT").force_encoding(data.encoding) }
data.split(Regexp.union(encoded_newlines), -1)
rescue Encoding::ConverterNotFoundError
# The data is not splittable in the detected encoding. Assume it's
# one big line.
[data]
end
else
[]
end

View File

@@ -63,7 +63,8 @@ module Linguist
generated_jni_header? ||
composer_lock? ||
node_modules? ||
vcr_cassette?
vcr_cassette? ||
generated_by_zephir?
end
# Internal: Is the blob an XCode project file?
@@ -237,6 +238,13 @@ module Linguist
!!name.match(/composer.lock/)
end
# Internal: Is the blob a generated by Zephir
#
# Returns true or false.
def generated_by_zephir?
!!name.match(/.\.zep\.(?:c|h|php)$/)
end
# Is the blob a VCR Cassette file?
#
# Returns true or false

View File

@@ -24,7 +24,6 @@ module Linguist
@extension_index = Hash.new { |h,k| h[k] = [] }
@interpreter_index = Hash.new { |h,k| h[k] = [] }
@filename_index = Hash.new { |h,k| h[k] = [] }
@primary_extension_index = {}
# Valid Languages types
TYPES = [:data, :markup, :programming, :prose]
@@ -80,12 +79,6 @@ module Linguist
@extension_index[extension] << language
end
if @primary_extension_index.key?(language.primary_extension)
raise ArgumentError, "Duplicate primary extension: #{language.primary_extension}"
end
@primary_extension_index[language.primary_extension] = language
language.interpreters.each do |interpreter|
@interpreter_index[interpreter] << language
end
@@ -191,8 +184,7 @@ module Linguist
# Returns all matching Languages or [] if none were found.
def self.find_by_filename(filename)
basename, extname = File.basename(filename), File.extname(filename)
langs = [@primary_extension_index[extname]] +
@filename_index[basename] +
langs = @filename_index[basename] +
@extension_index[extname]
langs.compact.uniq
end
@@ -299,15 +291,6 @@ module Linguist
@interpreters = attributes[:interpreters] || []
@filenames = attributes[:filenames] || []
unless @primary_extension = attributes[:primary_extension]
raise ArgumentError, "#{@name} is missing primary extension"
end
# Prepend primary extension unless its already included
if primary_extension && !extensions.include?(primary_extension)
@extensions = [primary_extension] + extensions
end
# Set popular, and searchable flags
@popular = attributes.key?(:popular) ? attributes[:popular] : false
@searchable = attributes.key?(:searchable) ? attributes[:searchable] : true
@@ -395,20 +378,6 @@ module Linguist
# Returns the extensions Array
attr_reader :extensions
# Deprecated: Get primary extension
#
# Defaults to the first extension but can be overridden
# in the languages.yml.
#
# The primary extension can not be nil. Tests should verify this.
#
# This attribute is only used by app/helpers/gists_helper.rb for
# creating the language dropdown. It really should be using `name`
# instead. Would like to drop primary extension.
#
# Returns the extension String.
attr_reader :primary_extension
# Public: Get interpreters
#
# Examples
@@ -426,6 +395,27 @@ module Linguist
#
# Returns the extensions Array
attr_reader :filenames
# Public: Return all possible extensions for language
def all_extensions
(extensions + [primary_extension]).uniq
end
# Deprecated: Get primary extension
#
# Defaults to the first extension but can be overridden
# in the languages.yml.
#
# The primary extension can not be nil. Tests should verify this.
#
# This method is only used by app/helpers/gists_helper.rb for creating
# the language dropdown. It really should be using `name` instead.
# Would like to drop primary extension.
#
# Returns the extension String.
def primary_extension
extensions.first
end
# Public: Get URL escaped name.
#
@@ -568,9 +558,8 @@ module Linguist
:group_name => options['group'],
:searchable => options.key?('searchable') ? options['searchable'] : true,
:search_term => options['search_term'],
:extensions => options['extensions'].sort,
:extensions => [options['extensions'].first] + options['extensions'][1..-1].sort,
:interpreters => options['interpreters'].sort,
:primary_extension => options['primary_extension'],
:filenames => options['filenames'],
:popular => popular.include?(name)
)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -98,9 +98,16 @@
# AngularJS
- (^|/)angular([^.]*)(\.min)?\.js$
# D3.js
- (^|\/)d3(\.v\d+)?([^.]*)(\.min)?\.js$
# React
- (^|/)react(-[^.]*)?(\.min)?\.js$
# Modernizr
- (^|/)modernizr\-\d\.\d+(\.\d+)?(\.min)?\.js$
- (^|/)modernizr\.custom\.\d+\.js$
## Python ##
# django
@@ -141,7 +148,7 @@
- (^|/)[Mm]icrosoft([Mm]vc)?([Aa]jax|[Vv]alidation)(\.debug)?\.js$
# NuGet
- ^[Pp]ackages/
- ^[Pp]ackages\/.+\.\d+\/
# ExtJS
- (^|/)extjs/.*?\.js$
@@ -161,6 +168,9 @@
- (^|/)extjs/src/
- (^|/)extjs/welcome/
# Html5shiv
- (^|/)html5shiv(\.min)?\.js$
# Samples folders
- ^[Ss]amples/
@@ -189,3 +199,12 @@
# Mercury --use-subdirs
- Mercury/
# R packages
- ^vignettes/
- ^inst/extdata/
# Octicons
- octicons.css
- octicons.min.css
- sprockets-octicons.scss

3
lib/linguist/version.rb Normal file
View File

@@ -0,0 +1,3 @@
module Linguist
VERSION = "2.12.0"
end

File diff suppressed because it is too large Load Diff

350
samples/Assembly/FASM.asm Normal file
View File

@@ -0,0 +1,350 @@
; flat assembler interface for Win32
; Copyright (c) 1999-2014, Tomasz Grysztar.
; All rights reserved.
format PE console
section '.text' code readable executable
start:
mov [con_handle],STD_OUTPUT_HANDLE
mov esi,_logo
call display_string
call get_params
jc information
call init_memory
mov esi,_memory_prefix
call display_string
mov eax,[memory_end]
sub eax,[memory_start]
add eax,[additional_memory_end]
sub eax,[additional_memory]
shr eax,10
call display_number
mov esi,_memory_suffix
call display_string
call [GetTickCount]
mov [start_time],eax
call preprocessor
call parser
call assembler
call formatter
call display_user_messages
movzx eax,[current_pass]
inc eax
call display_number
mov esi,_passes_suffix
call display_string
call [GetTickCount]
sub eax,[start_time]
xor edx,edx
mov ebx,100
div ebx
or eax,eax
jz display_bytes_count
xor edx,edx
mov ebx,10
div ebx
push edx
call display_number
mov dl,'.'
call display_character
pop eax
call display_number
mov esi,_seconds_suffix
call display_string
display_bytes_count:
mov eax,[written_size]
call display_number
mov esi,_bytes_suffix
call display_string
xor al,al
jmp exit_program
information:
mov esi,_usage
call display_string
mov al,1
jmp exit_program
get_params:
mov [input_file],0
mov [output_file],0
mov [symbols_file],0
mov [memory_setting],0
mov [passes_limit],100
call [GetCommandLine]
mov esi,eax
mov edi,params
find_command_start:
lodsb
cmp al,20h
je find_command_start
cmp al,22h
je skip_quoted_name
skip_name:
lodsb
cmp al,20h
je find_param
or al,al
jz all_params
jmp skip_name
skip_quoted_name:
lodsb
cmp al,22h
je find_param
or al,al
jz all_params
jmp skip_quoted_name
find_param:
lodsb
cmp al,20h
je find_param
cmp al,'-'
je option_param
cmp al,0Dh
je all_params
or al,al
jz all_params
cmp [input_file],0
jne get_output_file
mov [input_file],edi
jmp process_param
get_output_file:
cmp [output_file],0
jne bad_params
mov [output_file],edi
process_param:
cmp al,22h
je string_param
copy_param:
stosb
lodsb
cmp al,20h
je param_end
cmp al,0Dh
je param_end
or al,al
jz param_end
jmp copy_param
string_param:
lodsb
cmp al,22h
je string_param_end
cmp al,0Dh
je param_end
or al,al
jz param_end
stosb
jmp string_param
option_param:
lodsb
cmp al,'m'
je memory_option
cmp al,'M'
je memory_option
cmp al,'p'
je passes_option
cmp al,'P'
je passes_option
cmp al,'s'
je symbols_option
cmp al,'S'
je symbols_option
bad_params:
stc
ret
get_option_value:
xor eax,eax
mov edx,eax
get_option_digit:
lodsb
cmp al,20h
je option_value_ok
cmp al,0Dh
je option_value_ok
or al,al
jz option_value_ok
sub al,30h
jc invalid_option_value
cmp al,9
ja invalid_option_value
imul edx,10
jo invalid_option_value
add edx,eax
jc invalid_option_value
jmp get_option_digit
option_value_ok:
dec esi
clc
ret
invalid_option_value:
stc
ret
memory_option:
lodsb
cmp al,20h
je memory_option
cmp al,0Dh
je bad_params
or al,al
jz bad_params
dec esi
call get_option_value
or edx,edx
jz bad_params
cmp edx,1 shl (32-10)
jae bad_params
mov [memory_setting],edx
jmp find_param
passes_option:
lodsb
cmp al,20h
je passes_option
cmp al,0Dh
je bad_params
or al,al
jz bad_params
dec esi
call get_option_value
or edx,edx
jz bad_params
cmp edx,10000h
ja bad_params
mov [passes_limit],dx
jmp find_param
symbols_option:
mov [symbols_file],edi
find_symbols_file_name:
lodsb
cmp al,20h
jne process_param
jmp find_symbols_file_name
param_end:
dec esi
string_param_end:
xor al,al
stosb
jmp find_param
all_params:
cmp [input_file],0
je bad_params
clc
ret
include 'system.inc'
include '..\errors.inc'
include '..\symbdump.inc'
include '..\preproce.inc'
include '..\parser.inc'
include '..\exprpars.inc'
include '..\assemble.inc'
include '..\exprcalc.inc'
include '..\formats.inc'
include '..\x86_64.inc'
include '..\avx.inc'
include '..\tables.inc'
include '..\messages.inc'
section '.data' data readable writeable
include '..\version.inc'
_copyright db 'Copyright (c) 1999-2014, Tomasz Grysztar',0Dh,0Ah,0
_logo db 'flat assembler version ',VERSION_STRING,0
_usage db 0Dh,0Ah
db 'usage: fasm <source> [output]',0Dh,0Ah
db 'optional settings:',0Dh,0Ah
db ' -m <limit> set the limit in kilobytes for the available memory',0Dh,0Ah
db ' -p <limit> set the maximum allowed number of passes',0Dh,0Ah
db ' -s <file> dump symbolic information for debugging',0Dh,0Ah
db 0
_memory_prefix db ' (',0
_memory_suffix db ' kilobytes memory)',0Dh,0Ah,0
_passes_suffix db ' passes, ',0
_seconds_suffix db ' seconds, ',0
_bytes_suffix db ' bytes.',0Dh,0Ah,0
align 4
include '..\variable.inc'
con_handle dd ?
memory_setting dd ?
start_time dd ?
bytes_count dd ?
displayed_count dd ?
character db ?
last_displayed rb 2
params rb 1000h
options rb 1000h
buffer rb 4000h
stack 10000h
section '.idata' import data readable writeable
dd 0,0,0,rva kernel_name,rva kernel_table
dd 0,0,0,0,0
kernel_table:
ExitProcess dd rva _ExitProcess
CreateFile dd rva _CreateFileA
ReadFile dd rva _ReadFile
WriteFile dd rva _WriteFile
CloseHandle dd rva _CloseHandle
SetFilePointer dd rva _SetFilePointer
GetCommandLine dd rva _GetCommandLineA
GetEnvironmentVariable dd rva _GetEnvironmentVariable
GetStdHandle dd rva _GetStdHandle
VirtualAlloc dd rva _VirtualAlloc
VirtualFree dd rva _VirtualFree
GetTickCount dd rva _GetTickCount
GetSystemTime dd rva _GetSystemTime
GlobalMemoryStatus dd rva _GlobalMemoryStatus
dd 0
kernel_name db 'KERNEL32.DLL',0
_ExitProcess dw 0
db 'ExitProcess',0
_CreateFileA dw 0
db 'CreateFileA',0
_ReadFile dw 0
db 'ReadFile',0
_WriteFile dw 0
db 'WriteFile',0
_CloseHandle dw 0
db 'CloseHandle',0
_SetFilePointer dw 0
db 'SetFilePointer',0
_GetCommandLineA dw 0
db 'GetCommandLineA',0
_GetEnvironmentVariable dw 0
db 'GetEnvironmentVariableA',0
_GetStdHandle dw 0
db 'GetStdHandle',0
_VirtualAlloc dw 0
db 'VirtualAlloc',0
_VirtualFree dw 0
db 'VirtualFree',0
_GetTickCount dw 0
db 'GetTickCount',0
_GetSystemTime dw 0
db 'GetSystemTime',0
_GlobalMemoryStatus dw 0
db 'GlobalMemoryStatus',0
section '.reloc' fixups data readable discardable

503
samples/Assembly/SYSTEM.inc Normal file
View File

@@ -0,0 +1,503 @@
; flat assembler interface for Win32
; Copyright (c) 1999-2014, Tomasz Grysztar.
; All rights reserved.
CREATE_NEW = 1
CREATE_ALWAYS = 2
OPEN_EXISTING = 3
OPEN_ALWAYS = 4
TRUNCATE_EXISTING = 5
FILE_SHARE_READ = 1
FILE_SHARE_WRITE = 2
FILE_SHARE_DELETE = 4
GENERIC_READ = 80000000h
GENERIC_WRITE = 40000000h
STD_INPUT_HANDLE = 0FFFFFFF6h
STD_OUTPUT_HANDLE = 0FFFFFFF5h
STD_ERROR_HANDLE = 0FFFFFFF4h
MEM_COMMIT = 1000h
MEM_RESERVE = 2000h
MEM_DECOMMIT = 4000h
MEM_RELEASE = 8000h
MEM_FREE = 10000h
MEM_PRIVATE = 20000h
MEM_MAPPED = 40000h
MEM_RESET = 80000h
MEM_TOP_DOWN = 100000h
PAGE_NOACCESS = 1
PAGE_READONLY = 2
PAGE_READWRITE = 4
PAGE_WRITECOPY = 8
PAGE_EXECUTE = 10h
PAGE_EXECUTE_READ = 20h
PAGE_EXECUTE_READWRITE = 40h
PAGE_EXECUTE_WRITECOPY = 80h
PAGE_GUARD = 100h
PAGE_NOCACHE = 200h
init_memory:
xor eax,eax
mov [memory_start],eax
mov eax,esp
and eax,not 0FFFh
add eax,1000h-10000h
mov [stack_limit],eax
mov eax,[memory_setting]
shl eax,10
jnz allocate_memory
push buffer
call [GlobalMemoryStatus]
mov eax,dword [buffer+20]
mov edx,dword [buffer+12]
cmp eax,0
jl large_memory
cmp edx,0
jl large_memory
shr eax,2
add eax,edx
jmp allocate_memory
large_memory:
mov eax,80000000h
allocate_memory:
mov edx,eax
shr edx,2
mov ecx,eax
sub ecx,edx
mov [memory_end],ecx
mov [additional_memory_end],edx
push PAGE_READWRITE
push MEM_COMMIT
push eax
push 0
call [VirtualAlloc]
or eax,eax
jz not_enough_memory
mov [memory_start],eax
add eax,[memory_end]
mov [memory_end],eax
mov [additional_memory],eax
add [additional_memory_end],eax
ret
not_enough_memory:
mov eax,[additional_memory_end]
shl eax,1
cmp eax,4000h
jb out_of_memory
jmp allocate_memory
exit_program:
movzx eax,al
push eax
mov eax,[memory_start]
test eax,eax
jz do_exit
push MEM_RELEASE
push 0
push eax
call [VirtualFree]
do_exit:
call [ExitProcess]
get_environment_variable:
mov ecx,[memory_end]
sub ecx,edi
cmp ecx,4000h
jbe buffer_for_variable_ok
mov ecx,4000h
buffer_for_variable_ok:
push ecx
push edi
push esi
call [GetEnvironmentVariable]
add edi,eax
cmp edi,[memory_end]
jae out_of_memory
ret
open:
push 0
push 0
push OPEN_EXISTING
push 0
push FILE_SHARE_READ
push GENERIC_READ
push edx
call [CreateFile]
cmp eax,-1
je file_error
mov ebx,eax
clc
ret
file_error:
stc
ret
create:
push 0
push 0
push CREATE_ALWAYS
push 0
push FILE_SHARE_READ
push GENERIC_WRITE
push edx
call [CreateFile]
cmp eax,-1
je file_error
mov ebx,eax
clc
ret
write:
push 0
push bytes_count
push ecx
push edx
push ebx
call [WriteFile]
or eax,eax
jz file_error
clc
ret
read:
mov ebp,ecx
push 0
push bytes_count
push ecx
push edx
push ebx
call [ReadFile]
or eax,eax
jz file_error
cmp ebp,[bytes_count]
jne file_error
clc
ret
close:
push ebx
call [CloseHandle]
ret
lseek:
movzx eax,al
push eax
push 0
push edx
push ebx
call [SetFilePointer]
ret
display_string:
push [con_handle]
call [GetStdHandle]
mov ebp,eax
mov edi,esi
or ecx,-1
xor al,al
repne scasb
neg ecx
sub ecx,2
push 0
push bytes_count
push ecx
push esi
push ebp
call [WriteFile]
ret
display_character:
push ebx
mov [character],dl
push [con_handle]
call [GetStdHandle]
mov ebx,eax
push 0
push bytes_count
push 1
push character
push ebx
call [WriteFile]
pop ebx
ret
display_number:
push ebx
mov ecx,1000000000
xor edx,edx
xor bl,bl
display_loop:
div ecx
push edx
cmp ecx,1
je display_digit
or bl,bl
jnz display_digit
or al,al
jz digit_ok
not bl
display_digit:
mov dl,al
add dl,30h
push ecx
call display_character
pop ecx
digit_ok:
mov eax,ecx
xor edx,edx
mov ecx,10
div ecx
mov ecx,eax
pop eax
or ecx,ecx
jnz display_loop
pop ebx
ret
display_user_messages:
mov [displayed_count],0
call show_display_buffer
cmp [displayed_count],1
jb line_break_ok
je make_line_break
mov ax,word [last_displayed]
cmp ax,0A0Dh
je line_break_ok
cmp ax,0D0Ah
je line_break_ok
make_line_break:
mov word [buffer],0A0Dh
push [con_handle]
call [GetStdHandle]
push 0
push bytes_count
push 2
push buffer
push eax
call [WriteFile]
line_break_ok:
ret
display_block:
add [displayed_count],ecx
cmp ecx,1
ja take_last_two_characters
jb block_displayed
mov al,[last_displayed+1]
mov ah,[esi]
mov word [last_displayed],ax
jmp block_ok
take_last_two_characters:
mov ax,[esi+ecx-2]
mov word [last_displayed],ax
block_ok:
push ecx
push [con_handle]
call [GetStdHandle]
pop ecx
push 0
push bytes_count
push ecx
push esi
push eax
call [WriteFile]
block_displayed:
ret
fatal_error:
mov [con_handle],STD_ERROR_HANDLE
mov esi,error_prefix
call display_string
pop esi
call display_string
mov esi,error_suffix
call display_string
mov al,0FFh
jmp exit_program
assembler_error:
mov [con_handle],STD_ERROR_HANDLE
call display_user_messages
push dword 0
mov ebx,[current_line]
get_error_lines:
mov eax,[ebx]
cmp byte [eax],0
je get_next_error_line
push ebx
test byte [ebx+7],80h
jz display_error_line
mov edx,ebx
find_definition_origin:
mov edx,[edx+12]
test byte [edx+7],80h
jnz find_definition_origin
push edx
get_next_error_line:
mov ebx,[ebx+8]
jmp get_error_lines
display_error_line:
mov esi,[ebx]
call display_string
mov esi,line_number_start
call display_string
mov eax,[ebx+4]
and eax,7FFFFFFFh
call display_number
mov dl,']'
call display_character
pop esi
cmp ebx,esi
je line_number_ok
mov dl,20h
call display_character
push esi
mov esi,[esi]
movzx ecx,byte [esi]
inc esi
call display_block
mov esi,line_number_start
call display_string
pop esi
mov eax,[esi+4]
and eax,7FFFFFFFh
call display_number
mov dl,']'
call display_character
line_number_ok:
mov esi,line_data_start
call display_string
mov esi,ebx
mov edx,[esi]
call open
mov al,2
xor edx,edx
call lseek
mov edx,[esi+8]
sub eax,edx
jz line_data_displayed
push eax
xor al,al
call lseek
mov ecx,[esp]
mov edx,[additional_memory]
lea eax,[edx+ecx]
cmp eax,[additional_memory_end]
ja out_of_memory
call read
call close
pop ecx
mov esi,[additional_memory]
get_line_data:
mov al,[esi]
cmp al,0Ah
je display_line_data
cmp al,0Dh
je display_line_data
cmp al,1Ah
je display_line_data
or al,al
jz display_line_data
inc esi
loop get_line_data
display_line_data:
mov ecx,esi
mov esi,[additional_memory]
sub ecx,esi
call display_block
line_data_displayed:
mov esi,cr_lf
call display_string
pop ebx
or ebx,ebx
jnz display_error_line
mov esi,error_prefix
call display_string
pop esi
call display_string
mov esi,error_suffix
call display_string
mov al,2
jmp exit_program
make_timestamp:
push buffer
call [GetSystemTime]
movzx ecx,word [buffer]
mov eax,ecx
sub eax,1970
mov ebx,365
mul ebx
mov ebp,eax
mov eax,ecx
sub eax,1969
shr eax,2
add ebp,eax
mov eax,ecx
sub eax,1901
mov ebx,100
div ebx
sub ebp,eax
mov eax,ecx
xor edx,edx
sub eax,1601
mov ebx,400
div ebx
add ebp,eax
movzx ecx,word [buffer+2]
mov eax,ecx
dec eax
mov ebx,30
mul ebx
add ebp,eax
cmp ecx,8
jbe months_correction
mov eax,ecx
sub eax,7
shr eax,1
add ebp,eax
mov ecx,8
months_correction:
mov eax,ecx
shr eax,1
add ebp,eax
cmp ecx,2
jbe day_correction_ok
sub ebp,2
movzx ecx,word [buffer]
test ecx,11b
jnz day_correction_ok
xor edx,edx
mov eax,ecx
mov ebx,100
div ebx
or edx,edx
jnz day_correction
mov eax,ecx
mov ebx,400
div ebx
or edx,edx
jnz day_correction_ok
day_correction:
inc ebp
day_correction_ok:
movzx eax,word [buffer+6]
dec eax
add eax,ebp
mov ebx,24
mul ebx
movzx ecx,word [buffer+8]
add eax,ecx
mov ebx,60
mul ebx
movzx ecx,word [buffer+10]
add eax,ecx
mov ebx,60
mul ebx
movzx ecx,word [buffer+12]
add eax,ecx
adc edx,0
ret
error_prefix db 'error: ',0
error_suffix db '.'
cr_lf db 0Dh,0Ah,0
line_number_start db ' [',0
line_data_start db ':',0Dh,0Ah,0

7060
samples/Assembly/X86_64.inc Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,664 @@
//
// detail/impl/epoll_reactor.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_DETAIL_IMPL_EPOLL_REACTOR_IPP
#define BOOST_ASIO_DETAIL_IMPL_EPOLL_REACTOR_IPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#if defined(BOOST_ASIO_HAS_EPOLL)
#include <cstddef>
#include <sys/epoll.h>
#include <boost/asio/detail/epoll_reactor.hpp>
#include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/error.hpp>
#if defined(BOOST_ASIO_HAS_TIMERFD)
# include <sys/timerfd.h>
#endif // defined(BOOST_ASIO_HAS_TIMERFD)
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace detail {
epoll_reactor::epoll_reactor(boost::asio::io_service& io_service)
: boost::asio::detail::service_base<epoll_reactor>(io_service),
io_service_(use_service<io_service_impl>(io_service)),
mutex_(),
interrupter_(),
epoll_fd_(do_epoll_create()),
timer_fd_(do_timerfd_create()),
shutdown_(false)
{
// Add the interrupter's descriptor to epoll.
epoll_event ev = { 0, { 0 } };
ev.events = EPOLLIN | EPOLLERR | EPOLLET;
ev.data.ptr = &interrupter_;
epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, interrupter_.read_descriptor(), &ev);
interrupter_.interrupt();
// Add the timer descriptor to epoll.
if (timer_fd_ != -1)
{
ev.events = EPOLLIN | EPOLLERR;
ev.data.ptr = &timer_fd_;
epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, timer_fd_, &ev);
}
}
epoll_reactor::~epoll_reactor()
{
if (epoll_fd_ != -1)
close(epoll_fd_);
if (timer_fd_ != -1)
close(timer_fd_);
}
void epoll_reactor::shutdown_service()
{
mutex::scoped_lock lock(mutex_);
shutdown_ = true;
lock.unlock();
op_queue<operation> ops;
while (descriptor_state* state = registered_descriptors_.first())
{
for (int i = 0; i < max_ops; ++i)
ops.push(state->op_queue_[i]);
state->shutdown_ = true;
registered_descriptors_.free(state);
}
timer_queues_.get_all_timers(ops);
io_service_.abandon_operations(ops);
}
void epoll_reactor::fork_service(boost::asio::io_service::fork_event fork_ev)
{
if (fork_ev == boost::asio::io_service::fork_child)
{
if (epoll_fd_ != -1)
::close(epoll_fd_);
epoll_fd_ = -1;
epoll_fd_ = do_epoll_create();
if (timer_fd_ != -1)
::close(timer_fd_);
timer_fd_ = -1;
timer_fd_ = do_timerfd_create();
interrupter_.recreate();
// Add the interrupter's descriptor to epoll.
epoll_event ev = { 0, { 0 } };
ev.events = EPOLLIN | EPOLLERR | EPOLLET;
ev.data.ptr = &interrupter_;
epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, interrupter_.read_descriptor(), &ev);
interrupter_.interrupt();
// Add the timer descriptor to epoll.
if (timer_fd_ != -1)
{
ev.events = EPOLLIN | EPOLLERR;
ev.data.ptr = &timer_fd_;
epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, timer_fd_, &ev);
}
update_timeout();
// Re-register all descriptors with epoll.
mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_);
for (descriptor_state* state = registered_descriptors_.first();
state != 0; state = state->next_)
{
ev.events = state->registered_events_;
ev.data.ptr = state;
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, state->descriptor_, &ev);
if (result != 0)
{
boost::system::error_code ec(errno,
boost::asio::error::get_system_category());
boost::asio::detail::throw_error(ec, "epoll re-registration");
}
}
}
}
void epoll_reactor::init_task()
{
io_service_.init_task();
}
int epoll_reactor::register_descriptor(socket_type descriptor,
epoll_reactor::per_descriptor_data& descriptor_data)
{
descriptor_data = allocate_descriptor_state();
{
mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
descriptor_data->reactor_ = this;
descriptor_data->descriptor_ = descriptor;
descriptor_data->shutdown_ = false;
}
epoll_event ev = { 0, { 0 } };
ev.events = EPOLLIN | EPOLLERR | EPOLLHUP | EPOLLPRI | EPOLLET;
descriptor_data->registered_events_ = ev.events;
ev.data.ptr = descriptor_data;
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, descriptor, &ev);
if (result != 0)
return errno;
return 0;
}
int epoll_reactor::register_internal_descriptor(
int op_type, socket_type descriptor,
epoll_reactor::per_descriptor_data& descriptor_data, reactor_op* op)
{
descriptor_data = allocate_descriptor_state();
{
mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
descriptor_data->reactor_ = this;
descriptor_data->descriptor_ = descriptor;
descriptor_data->shutdown_ = false;
descriptor_data->op_queue_[op_type].push(op);
}
epoll_event ev = { 0, { 0 } };
ev.events = EPOLLIN | EPOLLERR | EPOLLHUP | EPOLLPRI | EPOLLET;
descriptor_data->registered_events_ = ev.events;
ev.data.ptr = descriptor_data;
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, descriptor, &ev);
if (result != 0)
return errno;
return 0;
}
void epoll_reactor::move_descriptor(socket_type,
epoll_reactor::per_descriptor_data& target_descriptor_data,
epoll_reactor::per_descriptor_data& source_descriptor_data)
{
target_descriptor_data = source_descriptor_data;
source_descriptor_data = 0;
}
void epoll_reactor::start_op(int op_type, socket_type descriptor,
epoll_reactor::per_descriptor_data& descriptor_data, reactor_op* op,
bool is_continuation, bool allow_speculative)
{
if (!descriptor_data)
{
op->ec_ = boost::asio::error::bad_descriptor;
post_immediate_completion(op, is_continuation);
return;
}
mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
if (descriptor_data->shutdown_)
{
post_immediate_completion(op, is_continuation);
return;
}
if (descriptor_data->op_queue_[op_type].empty())
{
if (allow_speculative
&& (op_type != read_op
|| descriptor_data->op_queue_[except_op].empty()))
{
if (op->perform())
{
descriptor_lock.unlock();
io_service_.post_immediate_completion(op, is_continuation);
return;
}
if (op_type == write_op)
{
if ((descriptor_data->registered_events_ & EPOLLOUT) == 0)
{
epoll_event ev = { 0, { 0 } };
ev.events = descriptor_data->registered_events_ | EPOLLOUT;
ev.data.ptr = descriptor_data;
if (epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev) == 0)
{
descriptor_data->registered_events_ |= ev.events;
}
else
{
op->ec_ = boost::system::error_code(errno,
boost::asio::error::get_system_category());
io_service_.post_immediate_completion(op, is_continuation);
return;
}
}
}
}
else
{
if (op_type == write_op)
{
descriptor_data->registered_events_ |= EPOLLOUT;
}
epoll_event ev = { 0, { 0 } };
ev.events = descriptor_data->registered_events_;
ev.data.ptr = descriptor_data;
epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
}
}
descriptor_data->op_queue_[op_type].push(op);
io_service_.work_started();
}
void epoll_reactor::cancel_ops(socket_type,
epoll_reactor::per_descriptor_data& descriptor_data)
{
if (!descriptor_data)
return;
mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
op_queue<operation> ops;
for (int i = 0; i < max_ops; ++i)
{
while (reactor_op* op = descriptor_data->op_queue_[i].front())
{
op->ec_ = boost::asio::error::operation_aborted;
descriptor_data->op_queue_[i].pop();
ops.push(op);
}
}
descriptor_lock.unlock();
io_service_.post_deferred_completions(ops);
}
void epoll_reactor::deregister_descriptor(socket_type descriptor,
epoll_reactor::per_descriptor_data& descriptor_data, bool closing)
{
if (!descriptor_data)
return;
mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
if (!descriptor_data->shutdown_)
{
if (closing)
{
// The descriptor will be automatically removed from the epoll set when
// it is closed.
}
else
{
epoll_event ev = { 0, { 0 } };
epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, descriptor, &ev);
}
op_queue<operation> ops;
for (int i = 0; i < max_ops; ++i)
{
while (reactor_op* op = descriptor_data->op_queue_[i].front())
{
op->ec_ = boost::asio::error::operation_aborted;
descriptor_data->op_queue_[i].pop();
ops.push(op);
}
}
descriptor_data->descriptor_ = -1;
descriptor_data->shutdown_ = true;
descriptor_lock.unlock();
free_descriptor_state(descriptor_data);
descriptor_data = 0;
io_service_.post_deferred_completions(ops);
}
}
void epoll_reactor::deregister_internal_descriptor(socket_type descriptor,
epoll_reactor::per_descriptor_data& descriptor_data)
{
if (!descriptor_data)
return;
mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
if (!descriptor_data->shutdown_)
{
epoll_event ev = { 0, { 0 } };
epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, descriptor, &ev);
op_queue<operation> ops;
for (int i = 0; i < max_ops; ++i)
ops.push(descriptor_data->op_queue_[i]);
descriptor_data->descriptor_ = -1;
descriptor_data->shutdown_ = true;
descriptor_lock.unlock();
free_descriptor_state(descriptor_data);
descriptor_data = 0;
}
}
void epoll_reactor::run(bool block, op_queue<operation>& ops)
{
// This code relies on the fact that the task_io_service queues the reactor
// task behind all descriptor operations generated by this function. This
// means, that by the time we reach this point, any previously returned
// descriptor operations have already been dequeued. Therefore it is now safe
// for us to reuse and return them for the task_io_service to queue again.
// Calculate a timeout only if timerfd is not used.
int timeout;
if (timer_fd_ != -1)
timeout = block ? -1 : 0;
else
{
mutex::scoped_lock lock(mutex_);
timeout = block ? get_timeout() : 0;
}
// Block on the epoll descriptor.
epoll_event events[128];
int num_events = epoll_wait(epoll_fd_, events, 128, timeout);
#if defined(BOOST_ASIO_HAS_TIMERFD)
bool check_timers = (timer_fd_ == -1);
#else // defined(BOOST_ASIO_HAS_TIMERFD)
bool check_timers = true;
#endif // defined(BOOST_ASIO_HAS_TIMERFD)
// Dispatch the waiting events.
for (int i = 0; i < num_events; ++i)
{
void* ptr = events[i].data.ptr;
if (ptr == &interrupter_)
{
// No need to reset the interrupter since we're leaving the descriptor
// in a ready-to-read state and relying on edge-triggered notifications
// to make it so that we only get woken up when the descriptor's epoll
// registration is updated.
#if defined(BOOST_ASIO_HAS_TIMERFD)
if (timer_fd_ == -1)
check_timers = true;
#else // defined(BOOST_ASIO_HAS_TIMERFD)
check_timers = true;
#endif // defined(BOOST_ASIO_HAS_TIMERFD)
}
#if defined(BOOST_ASIO_HAS_TIMERFD)
else if (ptr == &timer_fd_)
{
check_timers = true;
}
#endif // defined(BOOST_ASIO_HAS_TIMERFD)
else
{
// The descriptor operation doesn't count as work in and of itself, so we
// don't call work_started() here. This still allows the io_service to
// stop if the only remaining operations are descriptor operations.
descriptor_state* descriptor_data = static_cast<descriptor_state*>(ptr);
descriptor_data->set_ready_events(events[i].events);
ops.push(descriptor_data);
}
}
if (check_timers)
{
mutex::scoped_lock common_lock(mutex_);
timer_queues_.get_ready_timers(ops);
#if defined(BOOST_ASIO_HAS_TIMERFD)
if (timer_fd_ != -1)
{
itimerspec new_timeout;
itimerspec old_timeout;
int flags = get_timeout(new_timeout);
timerfd_settime(timer_fd_, flags, &new_timeout, &old_timeout);
}
#endif // defined(BOOST_ASIO_HAS_TIMERFD)
}
}
void epoll_reactor::interrupt()
{
epoll_event ev = { 0, { 0 } };
ev.events = EPOLLIN | EPOLLERR | EPOLLET;
ev.data.ptr = &interrupter_;
epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, interrupter_.read_descriptor(), &ev);
}
int epoll_reactor::do_epoll_create()
{
#if defined(EPOLL_CLOEXEC)
int fd = epoll_create1(EPOLL_CLOEXEC);
#else // defined(EPOLL_CLOEXEC)
int fd = -1;
errno = EINVAL;
#endif // defined(EPOLL_CLOEXEC)
if (fd == -1 && (errno == EINVAL || errno == ENOSYS))
{
fd = epoll_create(epoll_size);
if (fd != -1)
::fcntl(fd, F_SETFD, FD_CLOEXEC);
}
if (fd == -1)
{
boost::system::error_code ec(errno,
boost::asio::error::get_system_category());
boost::asio::detail::throw_error(ec, "epoll");
}
return fd;
}
int epoll_reactor::do_timerfd_create()
{
#if defined(BOOST_ASIO_HAS_TIMERFD)
# if defined(TFD_CLOEXEC)
int fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
# else // defined(TFD_CLOEXEC)
int fd = -1;
errno = EINVAL;
# endif // defined(TFD_CLOEXEC)
if (fd == -1 && errno == EINVAL)
{
fd = timerfd_create(CLOCK_MONOTONIC, 0);
if (fd != -1)
::fcntl(fd, F_SETFD, FD_CLOEXEC);
}
return fd;
#else // defined(BOOST_ASIO_HAS_TIMERFD)
return -1;
#endif // defined(BOOST_ASIO_HAS_TIMERFD)
}
epoll_reactor::descriptor_state* epoll_reactor::allocate_descriptor_state()
{
mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_);
return registered_descriptors_.alloc();
}
void epoll_reactor::free_descriptor_state(epoll_reactor::descriptor_state* s)
{
mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_);
registered_descriptors_.free(s);
}
void epoll_reactor::do_add_timer_queue(timer_queue_base& queue)
{
mutex::scoped_lock lock(mutex_);
timer_queues_.insert(&queue);
}
void epoll_reactor::do_remove_timer_queue(timer_queue_base& queue)
{
mutex::scoped_lock lock(mutex_);
timer_queues_.erase(&queue);
}
void epoll_reactor::update_timeout()
{
#if defined(BOOST_ASIO_HAS_TIMERFD)
if (timer_fd_ != -1)
{
itimerspec new_timeout;
itimerspec old_timeout;
int flags = get_timeout(new_timeout);
timerfd_settime(timer_fd_, flags, &new_timeout, &old_timeout);
return;
}
#endif // defined(BOOST_ASIO_HAS_TIMERFD)
interrupt();
}
int epoll_reactor::get_timeout()
{
// By default we will wait no longer than 5 minutes. This will ensure that
// any changes to the system clock are detected after no longer than this.
return timer_queues_.wait_duration_msec(5 * 60 * 1000);
}
#if defined(BOOST_ASIO_HAS_TIMERFD)
int epoll_reactor::get_timeout(itimerspec& ts)
{
ts.it_interval.tv_sec = 0;
ts.it_interval.tv_nsec = 0;
long usec = timer_queues_.wait_duration_usec(5 * 60 * 1000 * 1000);
ts.it_value.tv_sec = usec / 1000000;
ts.it_value.tv_nsec = usec ? (usec % 1000000) * 1000 : 1;
return usec ? 0 : TFD_TIMER_ABSTIME;
}
#endif // defined(BOOST_ASIO_HAS_TIMERFD)
struct epoll_reactor::perform_io_cleanup_on_block_exit
{
explicit perform_io_cleanup_on_block_exit(epoll_reactor* r)
: reactor_(r), first_op_(0)
{
}
~perform_io_cleanup_on_block_exit()
{
if (first_op_)
{
// Post the remaining completed operations for invocation.
if (!ops_.empty())
reactor_->io_service_.post_deferred_completions(ops_);
// A user-initiated operation has completed, but there's no need to
// explicitly call work_finished() here. Instead, we'll take advantage of
// the fact that the task_io_service will call work_finished() once we
// return.
}
else
{
// No user-initiated operations have completed, so we need to compensate
// for the work_finished() call that the task_io_service will make once
// this operation returns.
reactor_->io_service_.work_started();
}
}
epoll_reactor* reactor_;
op_queue<operation> ops_;
operation* first_op_;
};
epoll_reactor::descriptor_state::descriptor_state()
: operation(&epoll_reactor::descriptor_state::do_complete)
{
}
operation* epoll_reactor::descriptor_state::perform_io(uint32_t events)
{
mutex_.lock();
perform_io_cleanup_on_block_exit io_cleanup(reactor_);
mutex::scoped_lock descriptor_lock(mutex_, mutex::scoped_lock::adopt_lock);
// Exception operations must be processed first to ensure that any
// out-of-band data is read before normal data.
static const int flag[max_ops] = { EPOLLIN, EPOLLOUT, EPOLLPRI };
for (int j = max_ops - 1; j >= 0; --j)
{
if (events & (flag[j] | EPOLLERR | EPOLLHUP))
{
while (reactor_op* op = op_queue_[j].front())
{
if (op->perform())
{
op_queue_[j].pop();
io_cleanup.ops_.push(op);
}
else
break;
}
}
}
// The first operation will be returned for completion now. The others will
// be posted for later by the io_cleanup object's destructor.
io_cleanup.first_op_ = io_cleanup.ops_.front();
io_cleanup.ops_.pop();
return io_cleanup.first_op_;
}
void epoll_reactor::descriptor_state::do_complete(
io_service_impl* owner, operation* base,
const boost::system::error_code& ec, std::size_t bytes_transferred)
{
if (owner)
{
descriptor_state* descriptor_data = static_cast<descriptor_state*>(base);
uint32_t events = static_cast<uint32_t>(bytes_transferred);
if (operation* op = descriptor_data->perform_io(events))
{
op->complete(*owner, ec, 0);
}
}
}
} // namespace detail
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#endif // defined(BOOST_ASIO_HAS_EPOLL)
#endif // BOOST_ASIO_DETAIL_IMPL_EPOLL_REACTOR_IPP

View File

@@ -0,0 +1,82 @@
;; @file macros-advanced.cl
;;
;; @breif Advanced macro practices - defining your own macros
;;
;; Macro definition skeleton:
;; (defmacro name (parameter*)
;; "Optional documentation string"
;; body-form*)
;;
;; Note that backquote expression is most often used in the `body-form`
;;
; `primep` test a number for prime
(defun primep (n)
"test a number for prime"
(if (< n 2) (return-from primep))
(do ((i 2 (1+ i)) (p t (not (zerop (mod n i)))))
((> i (sqrt n)) p)
(when (not p) (return))))
; `next-prime` return the next prime bigger than the specified number
(defun next-prime (n)
"return the next prime bigger than the speicified number"
(do ((i (1+ n) (1+ i)))
((primep i) i)))
;
; The recommended procedures to writting a new macro are as follows:
; 1. Write a sample call to the macro and the code it should expand into
(do-primes (p 0 19)
(format t "~d " p))
; Expected expanded codes
(do ((p (next-prime (- 0 1)) (next-prime p)))
((> p 19))
(format t "~d " p))
; 2. Write code that generate the hardwritten expansion from the arguments in
; the sample call
(defmacro do-primes (var-and-range &rest body)
(let ((var (first var-and-range))
(start (second var-and-range))
(end (third var-and-range)))
`(do ((,var (next-prime (- ,start 1)) (next-prime ,var)))
((> ,var ,end))
,@body)))
; 2-1. More concise implementations with the 'parameter list destructuring' and
; '&body' synonym, it also emits more friendly messages on incorrent input.
(defmacro do-primes ((var start end) &body body)
`(do ((,var (next-prime (- ,start 1)) (next-prime ,var)))
((> ,var ,end))
,@body))
; 2-2. Test the result of macro expansion with the `macroexpand-1` function
(macroexpand-1 '(do-primes (p 0 19) (format t "~d " p)))
; 3. Make sure the macro abstraction does not "leak"
(defmacro do-primes ((var start end) &body body)
(let ((end-value-name (gensym)))
`(do ((,var (next-prime (- ,start 1)) (next-prime ,var))
(,end-value-name ,end))
((> ,var ,end-value-name))
,@body)))
; 3-1. Rules to observe to avoid common and possible leaks
; a. include any subforms in the expansion in positions that will be evaluated
; in the same order as the subforms appear in the macro call
; b. make sure subforms are evaluated only once by creating a variable in the
; expansion to hold the value of evaluating the argument form, and then
; using that variable anywhere else the value is needed in the expansion
; c. use `gensym` at macro expansion time to create variable names used in the
; expansion
;
; Appendix I. Macro-writting macros, 'with-gensyms', to guranttee that rule c
; gets observed.
; Example usage of `with-gensyms`
(defmacro do-primes-a ((var start end) &body body)
"do-primes implementation with macro-writting macro 'with-gensyms'"
(with-gensyms (end-value-name)
`(do ((,var (next-prime (- ,start 1)) (next-prime ,var))
(,end-value-name ,end))
((> ,var ,end-value-name))
,@body)))
; Define the macro, note how comma is used to interpolate the value of the loop
; expression
(defmacro with-gensyms ((&rest names) &body body)
`(let ,(loop for n in names collect `(,n (gensym)))
,@body)
)

View File

@@ -0,0 +1,475 @@
#|
ESCUELA POLITECNICA SUPERIOR - UNIVERSIDAD AUTONOMA DE MADRID
INTELIGENCIA ARTIFICIAL
Motor de inferencia
Basado en parte en "Paradigms of AI Programming: Case Studies
in Common Lisp", de Peter Norvig, 1992
|#
;;;;;;;;;;;;;;;;;;;;;
;;;; Global variables
;;;;;;;;;;;;;;;;;;;;;
(defvar *hypothesis-list*)
(defvar *rule-list*)
(defvar *fact-list*)
;;;;;;;;;;;;;;;;;;;;;
;;;; Constants
;;;;;;;;;;;;;;;;;;;;;
(defconstant +fail+ nil "Indicates unification failure")
(defconstant +no-bindings+ '((nil))
"Indicates unification success, with no variables.")
(defconstant *mundo-abierto* nil)
;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; Functions for the user
;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Resets *fact-list* to NIL
(defun erase-facts () (setq *fact-list* nil))
(defun set-hypothesis-list (h) (setq *hypothesis-list* h))
;; Returns a list of solutions, each one satisfying all the hypothesis contained
;; in *hypothesis-list*
(defun motor-inferencia ()
(consulta *hypothesis-list*))
;;;;;;;;;;;;;;;;;;;;;;;;
;;;; Auxiliary functions
;;;;;;;;;;;;;;;;;;;;;;;;
#|____________________________________________________________________________
FUNCTION: CONSULTA
COMMENTS:
CONSULTA receives a list of hypothesis (variable <hypotheses>), and returns
a list of binding lists (each binding list being a solution).
EXAMPLES:
hypotheses is:
((brothers ?x ?y) (neighbours juan ?x)).
That is, we are searching the brothers of the possible neighbors of Juan.
The function can return in this case:
(((?x . sergio) (?y . javier)) ((?x . julian) (?y . mario)) ((?x . julian) (?y . pedro))).
That is, the neighbors of Juan (Sergio and Julian) have 3 brothers in total(Javier, Mario, Pedro)
____________________________________________________________________________|#
(defun consulta (hypotheses)
(if (null hypotheses) (list +no-bindings+)
(mapcan #'(lambda (b)
(mapcar #'(lambda (x) (une-bindings-con-bindings b x))
(consulta (subst-bindings b (rest hypotheses)))))
(find-hypothesis-value (first hypotheses)))))
#|____________________________________________________________________________
FUNCTION: FIND-HYPOTHESIS-VALUE
COMMENTS:
This function manages the query a single query (only one hypothesis) given a binding list.
It tries (in the following order) to:
- Answer the query from *fact-list*
- Answer the query from the rules in *rule-list*
- Ask the user
The function returns a list of solutions (list of binding lists).
EXAMPLES:
If hypothesis is (brothers ?x ?y)
and the function returns:
(((?x . sergio) (?y . javier)) ((?x . julian) (?y . maria)) ((?x . alberto) (?y . pedro))).
Means that Sergio and Javier and brothers, Julian and Mario are brothers, and Alberto and Pedro are brothers.
____________________________________________________________________________|#
(defun find-hypothesis-value (hypothesis)
(let (rules)
(cond
((equality? hypothesis)
(value-from-equality hypothesis))
((value-from-facts hypothesis))
((setq good-rules (find-rules hypothesis))
(value-from-rules hypothesis good-rules))
(t (ask-user hypothesis)))))
; une-bindings-con-bindings takes two binding lists and returns a binding list
; Assumes that b1 and b2 are not +fail+
(defun une-bindings-con-bindings (b1 b2)
(cond
((equal b1 +no-bindings+) b2)
((equal b2 +no-bindings+) b1)
(T (append b1 b2))))
#|____________________________________________________________________________
FUNCTION: VALUE-FROM-FACTS
COMMENTS:
Returns all the solutions of <hypothesis> obtained directly from *fact-list*
EXAMPLES:
> (setf *fact-list* '((man luis) (man pedro)(woman mart)(man daniel)(woman laura)))
> (value-from-facts '(man ?x))
returns:
(((?X . LUIS)) ((?X . PEDRO)) ((?X . DANIEL)))
____________________________________________________________________________|#
(defun value-from-facts (hypothesis)
(mapcan #'(lambda(x) (let ((aux (unify hypothesis x)))
(when aux (list aux)))) *fact-list*))
#|____________________________________________________________________________
FUNCTION: FIND-RULES
COMMENTS:
Returns the rules in *rule-list* whose THENs unify with the term given in <hypothesis>
The variables in the rules that satisfy this requirement are renamed.
EXAMPLES:
> (setq *rule-list*
'((R1 (pertenece ?E (?E . ?_)))
(R2 (pertenece ?E (?_ . ?Xs)) :- ((pertenece ?E ?Xs)))))
Then:
> (FIND-RULES (PERTENECE 1 (2 5)))
returns:
((R2 (PERTENECE ?E.1 (?_ . ?XS.2)) :- ((PERTENECE ?E.1 ?XS.2))))
That is, only the THEN of rule R2 unify with <hypothesis>
However,
> (FIND-RULES (PERTENECE 1 (1 6 7)))
returns:
((R1 (PERTENECE ?E.6 (?E.6 . ?_)))
(R2 (PERTENECE ?E.7 (?_ . ?XS.8)) :- ((PERTENECE ?E.7 ?XS.8))))
So the THEN of both rules unify with <hypothesis>
____________________________________________________________________________|#
(defun find-rules (hypothesis)
(mapcan #'(lambda(b) (let ((renamed-rule (rename-variables b)))
(when (in-then? hypothesis renamed-rule)
(list renamed-rule)))) *rule-list*))
(defun in-then? (hypothesis rule)
(unless (null (rule-then rule))
(not (equal +fail+ (unify hypothesis (rule-then rule))))))
#|____________________________________________________________________________
FUNCTION: VALUE-FROM-RULES
COMMENTS:
Returns all the solutions to <hypothesis> found using all the rules given in
the list <rules>. Note that a single rule can have multiple solutions.
____________________________________________________________________________|#
(defun value-from-rules (hypothesis rules)
(mapcan #'(lambda (r) (eval-rule hypothesis r)) rules))
(defun limpia-vinculos (termino bindings)
(unify termino (subst-bindings bindings termino)))
#|____________________________________________________________________________
FUNCTION: EVAL-RULE
COMMENTS:
Returns all the solutions found using the rule given as input argument.
EXAMPLES:
> (setq *rule-list*
'((R1 (pertenece ?E (?E . ?_)))
(R2 (pertenece ?E (?_ . ?Xs)) :- ((pertenece ?E ?Xs)))))
Then:
> (EVAL-RULE
(PERTENECE 1 (1 6 7))
(R1 (PERTENECE ?E.42 (?E.42 . ?_))))
returns:
(((NIL)))
That is, the query (PERTENECE 1 (1 6 7)) can be proven from the given rule, and
no binding in the variables in the query is necessary (in fact, the query has no variables).
On the other hand:
> (EVAL-RULE
(PERTENECE 1 (7))
(R2 (PERTENECE ?E.49 (?_ . ?XS.50)) :- ((PERTENECE ?E.49 ?XS.50))))
returns:
NIL
That is, the query can not be proven from the rule R2.
____________________________________________________________________________|#
(defun eval-rule (hypothesis rule)
(let ((bindings-then
(unify (rule-then rule) hypothesis)))
(unless (equal +fail+ bindings-then)
(if (rule-ifs rule)
(mapcar #'(lambda(b) (limpia-vinculos hypothesis (append bindings-then b)))
(consulta (subst-bindings bindings-then (rule-ifs rule))))
(list (limpia-vinculos hypothesis bindings-then))))))
(defun ask-user (hypothesis)
(let ((question hypothesis))
(cond
((variables-in question) +fail+)
((not-in-fact-list? question) +fail+)
(*mundo-abierto*
(format t "~%Es cierto el hecho ~S? (T/nil)" question)
(cond
((read) (add-fact question) +no-bindings+)
(T (add-fact (list 'NOT question)) +fail+)))
(T +fail+))))
; value-from-equality:
(defun value-from-equality (hypothesis)
(let ((new-bindings (unify (second hypothesis) (third hypothesis))))
(if (not (equal +fail+ new-bindings))
(list new-bindings))))
#|____________________________________________________________________________
FUNCTION: UNIFY
COMMENTS:
Finds the most general unifier of two input expressions, taking into account the
bindings specified in the input <bingings>
In case the two expressions can unify, the function returns the total bindings necessary
for that unification. Otherwise, returns +fail+
EXAMPLES:
> (unify '1 '1)
((NIL)) ;; which is the constant +no-bindings+
> (unify 1 '2)
nil ;; which is the constant +fail+
> (unify '?x 1)
((?x . 1))
> (unify '(1 1) ?x)
((? x 1 1))
> (unify '?_ '?x)
((NIL))
> (unify '(p ?x 1 2) '(p ?y ?_ ?_))
((?x . ?y))
> (unify '(?a . ?_) '(1 2 3))
((?a . 1))
> (unify '(?_ ?_) '(1 2))
((nil))
> (unify '(?a . ?b) '(1 2 3))
((?b 2 3) (?a . 1))
> (unify '(?a . ?b) '(?v . ?d))
((?b . ?d) (?a . ?v))
> (unify '(?eval (+ 1 1)) '1)
nil
> (unify '(?eval (+ 1 1)) '2)
(nil))
____________________________________________________________________________|#
(defun unify (x y &optional (bindings +no-bindings+))
"See if x and y match with given bindings. If they do,
return a binding list that would make them equal [p 303]."
(cond ((eq bindings +fail+) +fail+)
((eql x y) bindings)
((eval? x) (unify-eval x y bindings))
((eval? y) (unify-eval y x bindings))
((variable? x) (unify-var x y bindings))
((variable? y) (unify-var y x bindings))
((and (consp x) (consp y))
(unify (rest x) (rest y)
(unify (first x) (first y) bindings)))
(t +fail+)))
;; rename-variables: renombra ?X por ?X.1, ?Y por ?Y.2 etc. salvo ?_ que no se renombra
(defun rename-variables (x)
"Replace all variables in x with new ones. Excepto ?_"
(sublis (mapcar #'(lambda (var)
(if (anonymous-var? var)
(make-binding var var)
(make-binding var (new-variable var))))
(variables-in x))
x))
;;;; Auxiliary Functions
(defun unify-var (var x bindings)
"Unify var with x, using (and maybe extending) bindings [p 303]."
(cond ((or (anonymous-var? var)(anonymous-var? x)) bindings)
((get-binding var bindings)
(unify (lookup var bindings) x bindings))
((and (variable? x) (get-binding x bindings))
(unify var (lookup x bindings) bindings))
((occurs-in? var x bindings)
+fail+)
(t (extend-bindings var x bindings))))
(defun variable? (x)
"Is x a variable (a symbol starting with ?)?"
(and (symbolp x) (eql (char (symbol-name x) 0) #\?)))
(defun get-binding (var bindings)
"Find a (variable . value) pair in a binding list."
(assoc var bindings))
(defun binding-var (binding)
"Get the variable part of a single binding."
(car binding))
(defun binding-val (binding)
"Get the value part of a single binding."
(cdr binding))
(defun make-binding (var val) (cons var val))
(defun lookup (var bindings)
"Get the value part (for var) from a binding list."
(binding-val (get-binding var bindings)))
(defun extend-bindings (var val bindings)
"Add a (var . value) pair to a binding list."
(append
(unless (eq bindings +no-bindings+) bindings)
(list (make-binding var val))))
(defun occurs-in? (var x bindings)
"Does var occur anywhere inside x?"
(cond ((eq var x) t)
((and (variable? x) (get-binding x bindings))
(occurs-in? var (lookup x bindings) bindings))
((consp x) (or (occurs-in? var (first x) bindings)
(occurs-in? var (rest x) bindings)))
(t nil)))
(defun subst-bindings (bindings x)
"Substitute the value of variables in bindings into x,
taking recursively bound variables into account."
(cond ((eq bindings +fail+) +fail+)
((eq bindings +no-bindings+) x)
((and (listp x) (eq '?eval (car x)))
(subst-bindings-quote bindings x))
((and (variable? x) (get-binding x bindings))
(subst-bindings bindings (lookup x bindings)))
((atom x) x)
(t (cons (subst-bindings bindings (car x)) ;; s/reuse-cons/cons
(subst-bindings bindings (cdr x))))))
(defun unifier (x y)
"Return something that unifies with both x and y (or fail)."
(subst-bindings (unify x y) x))
(defun variables-in (exp)
"Return a list of all the variables in EXP."
(unique-find-anywhere-if #'variable? exp))
(defun unique-find-anywhere-if (predicate tree &optional found-so-far)
"Return a list of leaves of tree satisfying predicate,
with duplicates removed."
(if (atom tree)
(if (funcall predicate tree)
(pushnew tree found-so-far)
found-so-far)
(unique-find-anywhere-if
predicate
(first tree)
(unique-find-anywhere-if predicate (rest tree)
found-so-far))))
(defun find-anywhere-if (predicate tree)
"Does predicate apply to any atom in the tree?"
(if (atom tree)
(funcall predicate tree)
(or (find-anywhere-if predicate (first tree))
(find-anywhere-if predicate (rest tree)))))
(defun new-variable (var)
"Create a new variable. Assumes user never types variables of form ?X.9"
(gentemp (format nil "~S." var)))
; (gentemp "?") )
;;;
(defun anonymous-var? (x)
(eq x '?_))
(defun subst-bindings-quote (bindings x)
"Substitute the value of variables in bindings into x,
taking recursively bound variables into account."
(cond ((eq bindings +fail+) +fail+)
((eq bindings +no-bindings+) x)
((and (variable? x) (get-binding x bindings))
(if (variable? (lookup x bindings))
(subst-bindings-quote bindings (lookup x bindings))
(subst-bindings-quote bindings (list 'quote (lookup x bindings)))
)
)
((atom x) x)
(t (cons (subst-bindings-quote bindings (car x)) ;; s/reuse-cons/cons
(subst-bindings-quote bindings (cdr x))))))
(defun eval? (x)
(and (consp x) (eq (first x) '?eval)))
(defun unify-eval (x y bindings)
(let ((exp (subst-bindings-quote bindings (second x))))
(if (variables-in exp)
+fail+
(unify (eval exp) y bindings))))
(defun rule-ifs (rule) (fourth rule))
(defun rule-then (rule) (second rule))
(defun equality? (term)
(and (consp term) (eql (first term) '?=)))
(defun in-fact-list? (expresion)
(some #'(lambda(x) (equal x expresion)) *fact-list*))
(defun not-in-fact-list? (expresion)
(if (eq (car expresion) 'NOT)
(in-fact-list? (second expresion))
(in-fact-list? (list 'NOT expresion))))
;; add-fact:
(defun add-fact (fact)
(setq *fact-list* (cons fact *fact-list*)))
(defun variable? (x)
"Is x a variable (a symbol starting with ?) except ?eval and ?="
(and (not (equal x '?eval)) (not (equal x '?=))
(symbolp x) (eql (char (symbol-name x) 0) #\?)))
;; EOF

View File

@@ -0,0 +1,130 @@
MODULE ObxControls;
(**
project = "BlackBox"
organization = "www.oberon.ch"
contributors = "Oberon microsystems"
version = "System/Rsrc/About"
copyright = "System/Rsrc/About"
license = "Docu/BB-License"
changes = ""
issues = ""
**)
IMPORT Dialog, Ports, Properties, Views;
CONST beginner = 0; advanced = 1; expert = 2; guru = 3; (* user classes *)
TYPE
View = POINTER TO RECORD (Views.View)
size: INTEGER (* border size in mm *)
END;
VAR
data*: RECORD
class*: INTEGER; (* current user class *)
list*: Dialog.List; (* list of currently available sizes, derived from class *)
width*: INTEGER (* width of next view to be opened. Derived from
class, or entered through a text entry field *)
END;
predef: ARRAY 6 OF INTEGER; (* table of predefined sizes *)
PROCEDURE SetList;
BEGIN
IF data.class = beginner THEN
data.list.SetLen(1);
data.list.SetItem(0, "default")
ELSIF data.class = advanced THEN
data.list.SetLen(4);
data.list.SetItem(0, "default");
data.list.SetItem(1, "small");
data.list.SetItem(2, "medium");
data.list.SetItem(3, "large");
ELSE
data.list.SetLen(6);
data.list.SetItem(0, "default");
data.list.SetItem(1, "small");
data.list.SetItem(2, "medium");
data.list.SetItem(3, "large");
data.list.SetItem(4, "tiny");
data.list.SetItem(5, "huge");
END
END SetList;
(* View *)
PROCEDURE (v: View) CopyFromSimpleView (source: Views.View);
BEGIN
v.size := source(View).size
END CopyFromSimpleView;
PROCEDURE (v: View) Restore (f: Views.Frame; l, t, r, b: INTEGER);
BEGIN (* fill view with a red square of size v.size *)
IF v.size = 0 THEN v.size := predef[0] END; (* lazy initialization of size *)
f.DrawRect(0, 0, v.size, v.size, Ports.fill, Ports.red)
END Restore;
PROCEDURE (v: View) HandlePropMsg (VAR msg: Views.PropMessage);
BEGIN
WITH msg: Properties.SizePref DO
IF v.size = 0 THEN v.size := predef[0] END; (* lazy initialization of size *)
msg.w := v.size; msg.h := v.size (* tell environment about desired width and height *)
ELSE (* ignore other messages *)
END
END HandlePropMsg;
(* notifiers *)
PROCEDURE ClassNotify* (op, from, to: INTEGER);
BEGIN (* react to change in data.class *)
IF op = Dialog.changed THEN
IF (to = beginner) OR (to = advanced) & (data.list.index > 3) THEN
(* if class is reduced, make sure that selection contains legal elements *)
data.list.index := 0; data.width := predef[0]; (* modify interactor *)
Dialog.Update(data) (* redraw controls where necessary *)
END;
SetList;
Dialog.UpdateList(data.list) (* reconstruct list box contents *)
END
END ClassNotify;
PROCEDURE ListNotify* (op, from, to: INTEGER);
BEGIN (* reacto to change in data.list (index to was selected) *)
IF op = Dialog.changed THEN
data.width := predef[to]; (* modify interactor *)
Dialog.Update(data) (* redraw controls where necessary *)
END
END ListNotify;
(* guards *)
PROCEDURE ListGuard* (VAR par: Dialog.Par);
BEGIN (* disable list box for a beginner *)
par.disabled := data.class = beginner
END ListGuard;
PROCEDURE WidthGuard* (VAR par: Dialog.Par);
BEGIN (* make text entry field read-only if user is not guru *)
par.readOnly := data.class # guru
END WidthGuard;
(* commands *)
PROCEDURE Open*;
VAR v: View;
BEGIN
NEW(v); (* create and initialize a new view *)
v.size := data.width * Ports.mm; (* define view's size in function of class *)
Views.OpenAux(v, "Example") (* open the view in a window *)
END Open;
BEGIN (* initialization of global variables *)
predef[0] := 40; predef[1] := 30; predef[2] := 50; (* predefined sizes *)
predef[3] := 70; predef[4] := 20; predef[5] := 100;
data.class := beginner; (* default values *)
data.list.index := 0;
data.width := predef[0];
SetList
END ObxControls.

View File

@@ -0,0 +1,71 @@
MODULE ObxFact;
(**
project = "BlackBox"
organization = "www.oberon.ch"
contributors = "Oberon microsystems"
version = "System/Rsrc/About"
copyright = "System/Rsrc/About"
license = "Docu/BB-License"
changes = ""
issues = ""
**)
IMPORT
Stores, Models, TextModels, TextControllers, Integers;
PROCEDURE Read(r: TextModels.Reader; VAR x: Integers.Integer);
VAR i, len, beg: INTEGER; ch: CHAR; buf: POINTER TO ARRAY OF CHAR;
BEGIN
r.ReadChar(ch);
WHILE ~r.eot & (ch <= " ") DO r.ReadChar(ch) END;
ASSERT(~r.eot & (((ch >= "0") & (ch <= "9")) OR (ch = "-")));
beg := r.Pos() - 1; len := 0;
REPEAT INC(len); r.ReadChar(ch) UNTIL r.eot OR (ch < "0") OR (ch > "9");
NEW(buf, len + 1);
i := 0; r.SetPos(beg);
REPEAT r.ReadChar(buf[i]); INC(i) UNTIL i = len;
buf[i] := 0X;
Integers.ConvertFromString(buf^, x)
END Read;
PROCEDURE Write(w: TextModels.Writer; x: Integers.Integer);
VAR i: INTEGER;
BEGIN
IF Integers.Sign(x) < 0 THEN w.WriteChar("-") END;
i := Integers.Digits10Of(x);
IF i # 0 THEN
REPEAT DEC(i); w.WriteChar(Integers.ThisDigit10(x, i)) UNTIL i = 0
ELSE w.WriteChar("0")
END
END Write;
PROCEDURE Compute*;
VAR beg, end, i, n: INTEGER; ch: CHAR;
s: Stores.Operation;
r: TextModels.Reader; w: TextModels.Writer; attr: TextModels.Attributes;
c: TextControllers.Controller;
x: Integers.Integer;
BEGIN
c := TextControllers.Focus();
IF (c # NIL) & c.HasSelection() THEN
c.GetSelection(beg, end);
r := c.text.NewReader(NIL); r.SetPos(beg); r.ReadChar(ch);
WHILE ~r.eot & (beg < end) & (ch <= " ") DO r.ReadChar(ch); INC(beg) END;
IF ~r.eot & (beg < end) THEN
r.ReadPrev; Read(r, x);
end := r.Pos(); r.ReadPrev; attr :=r.attr;
IF (Integers.Sign(x) > 0) & (Integers.Compare(x, Integers.Long(MAX(LONGINT))) <= 0) THEN
n := SHORT(Integers.Short(x)); i := 2; x := Integers.Long(1);
WHILE i <= n DO x := Integers.Product(x, Integers.Long(i)); INC(i) END;
Models.BeginScript(c.text, "computation", s);
c.text.Delete(beg, end);
w := c.text.NewWriter(NIL); w.SetPos(beg); w.SetAttr(attr);
Write(w, x);
Models.EndScript(c.text, s)
END
END
END
END Compute;
END ObxFact.

View File

@@ -0,0 +1,169 @@
#!/usr/bin/env bin/crystal --run
require "../../spec_helper"
describe "Codegen: const" do
it "define a constant" do
run("A = 1; A").to_i.should eq(1)
end
it "support nested constant" do
run("class B; A = 1; end; B::A").to_i.should eq(1)
end
it "support constant inside a def" do
run("
class Foo
A = 1
def foo
A
end
end
Foo.new.foo
").to_i.should eq(1)
end
it "finds nearest constant first" do
run("
A = 1
class Foo
A = 2.5_f32
def foo
A
end
end
Foo.new.foo
").to_f32.should eq(2.5)
end
it "allows constants with same name" do
run("
A = 1
class Foo
A = 2.5_f32
def foo
A
end
end
A
Foo.new.foo
").to_f32.should eq(2.5)
end
it "constants with expression" do
run("
A = 1 + 1
A
").to_i.should eq(2)
end
it "finds global constant" do
run("
A = 1
class Foo
def foo
A
end
end
Foo.new.foo
").to_i.should eq(1)
end
it "define a constant in lib" do
run("lib Foo; A = 1; end; Foo::A").to_i.should eq(1)
end
it "invokes block in const" do
run("require \"prelude\"; A = [\"1\"].map { |x| x.to_i }; A[0]").to_i.should eq(1)
end
it "declare constants in right order" do
run("A = 1 + 1; B = true ? A : 0; B").to_i.should eq(2)
end
it "uses correct types lookup" do
run("
module A
class B
def foo
1
end
end
C = B.new;
end
def foo
A::C.foo
end
foo
").to_i.should eq(1)
end
it "codegens variable assignment in const" do
run("
class Foo
def initialize(@x)
end
def x
@x
end
end
A = begin
f = Foo.new(1)
f
end
def foo
A.x
end
foo
").to_i.should eq(1)
end
it "declaring var" do
run("
BAR = begin
a = 1
while 1 == 2
b = 2
end
a
end
class Foo
def compile
BAR
end
end
Foo.new.compile
").to_i.should eq(1)
end
it "initialize const that might raise an exception" do
run("
require \"prelude\"
CONST = (raise \"OH NO\" if 1 == 2)
def doit
CONST
rescue
end
doit.nil?
").to_b.should be_true
end
end

View File

@@ -0,0 +1,79 @@
#!/usr/bin/env bin/crystal --run
require "../../spec_helper"
describe "Type inference: declare var" do
it "types declare var" do
assert_type("a :: Int32") { int32 }
end
it "types declare var and reads it" do
assert_type("a :: Int32; a") { int32 }
end
it "types declare var and changes its type" do
assert_type("a :: Int32; while 1 == 2; a = 'a'; end; a") { union_of(int32, char) }
end
it "declares instance var which appears in initialize" do
result = assert_type("
class Foo
@x :: Int32
end
Foo.new") { types["Foo"] }
mod = result.program
foo = mod.types["Foo"] as NonGenericClassType
foo.instance_vars["@x"].type.should eq(mod.int32)
end
it "declares instance var of generic class" do
result = assert_type("
class Foo(T)
@x :: T
end
Foo(Int32).new") do
foo = types["Foo"] as GenericClassType
foo_i32 = foo.instantiate([int32] of Type | ASTNode)
foo_i32.lookup_instance_var("@x").type.should eq(int32)
foo_i32
end
end
it "declares instance var of generic class after reopen" do
result = assert_type("
class Foo(T)
end
f = Foo(Int32).new
class Foo(T)
@x :: T
end
f") do
foo = types["Foo"] as GenericClassType
foo_i32 = foo.instantiate([int32] of Type | ASTNode)
foo_i32.lookup_instance_var("@x").type.should eq(int32)
foo_i32
end
end
it "declares an instance variable in initialize" do
assert_type("
class Foo
def initialize
@x :: Int32
end
def x
@x
end
end
Foo.new.x
") { int32 }
end
end

View File

@@ -0,0 +1,515 @@
module Crystal
class ASTNode
def transform(transformer)
transformer.before_transform self
node = transformer.transform self
transformer.after_transform self
node
end
end
class Transformer
def before_transform(node)
end
def after_transform(node)
end
def transform(node : Expressions)
exps = [] of ASTNode
node.expressions.each do |exp|
new_exp = exp.transform(self)
if new_exp
if new_exp.is_a?(Expressions)
exps.concat new_exp.expressions
else
exps << new_exp
end
end
end
if exps.length == 1
exps[0]
else
node.expressions = exps
node
end
end
def transform(node : Call)
if node_obj = node.obj
node.obj = node_obj.transform(self)
end
transform_many node.args
if node_block = node.block
node.block = node_block.transform(self)
end
if node_block_arg = node.block_arg
node.block_arg = node_block_arg.transform(self)
end
node
end
def transform(node : And)
node.left = node.left.transform(self)
node.right = node.right.transform(self)
node
end
def transform(node : Or)
node.left = node.left.transform(self)
node.right = node.right.transform(self)
node
end
def transform(node : StringInterpolation)
transform_many node.expressions
node
end
def transform(node : ArrayLiteral)
transform_many node.elements
if node_of = node.of
node.of = node_of.transform(self)
end
node
end
def transform(node : HashLiteral)
transform_many node.keys
transform_many node.values
if of_key = node.of_key
node.of_key = of_key.transform(self)
end
if of_value = node.of_value
node.of_value = of_value.transform(self)
end
node
end
def transform(node : If)
node.cond = node.cond.transform(self)
node.then = node.then.transform(self)
node.else = node.else.transform(self)
node
end
def transform(node : Unless)
node.cond = node.cond.transform(self)
node.then = node.then.transform(self)
node.else = node.else.transform(self)
node
end
def transform(node : IfDef)
node.cond = node.cond.transform(self)
node.then = node.then.transform(self)
node.else = node.else.transform(self)
node
end
def transform(node : MultiAssign)
transform_many node.targets
transform_many node.values
node
end
def transform(node : SimpleOr)
node.left = node.left.transform(self)
node.right = node.right.transform(self)
node
end
def transform(node : Def)
transform_many node.args
node.body = node.body.transform(self)
if receiver = node.receiver
node.receiver = receiver.transform(self)
end
if block_arg = node.block_arg
node.block_arg = block_arg.transform(self)
end
node
end
def transform(node : Macro)
transform_many node.args
node.body = node.body.transform(self)
if receiver = node.receiver
node.receiver = receiver.transform(self)
end
if block_arg = node.block_arg
node.block_arg = block_arg.transform(self)
end
node
end
def transform(node : PointerOf)
node.exp = node.exp.transform(self)
node
end
def transform(node : SizeOf)
node.exp = node.exp.transform(self)
node
end
def transform(node : InstanceSizeOf)
node.exp = node.exp.transform(self)
node
end
def transform(node : IsA)
node.obj = node.obj.transform(self)
node.const = node.const.transform(self)
node
end
def transform(node : RespondsTo)
node.obj = node.obj.transform(self)
node
end
def transform(node : Case)
node.cond = node.cond.transform(self)
transform_many node.whens
if node_else = node.else
node.else = node_else.transform(self)
end
node
end
def transform(node : When)
transform_many node.conds
node.body = node.body.transform(self)
node
end
def transform(node : ImplicitObj)
node
end
def transform(node : ClassDef)
node.body = node.body.transform(self)
if superclass = node.superclass
node.superclass = superclass.transform(self)
end
node
end
def transform(node : ModuleDef)
node.body = node.body.transform(self)
node
end
def transform(node : While)
node.cond = node.cond.transform(self)
node.body = node.body.transform(self)
node
end
def transform(node : Generic)
node.name = node.name.transform(self)
transform_many node.type_vars
node
end
def transform(node : ExceptionHandler)
node.body = node.body.transform(self)
transform_many node.rescues
if node_ensure = node.ensure
node.ensure = node_ensure.transform(self)
end
node
end
def transform(node : Rescue)
node.body = node.body.transform(self)
transform_many node.types
node
end
def transform(node : Union)
transform_many node.types
node
end
def transform(node : Hierarchy)
node.name = node.name.transform(self)
node
end
def transform(node : Metaclass)
node.name = node.name.transform(self)
node
end
def transform(node : Arg)
if default_value = node.default_value
node.default_value = default_value.transform(self)
end
if restriction = node.restriction
node.restriction = restriction.transform(self)
end
node
end
def transform(node : BlockArg)
node.fun = node.fun.transform(self)
node
end
def transform(node : Fun)
transform_many node.inputs
if output = node.output
node.output = output.transform(self)
end
node
end
def transform(node : Block)
node.args.map! { |exp| exp.transform(self) as Var }
node.body = node.body.transform(self)
node
end
def transform(node : FunLiteral)
node.def.body = node.def.body.transform(self)
node
end
def transform(node : FunPointer)
if obj = node.obj
node.obj = obj.transform(self)
end
node
end
def transform(node : Return)
transform_many node.exps
node
end
def transform(node : Break)
transform_many node.exps
node
end
def transform(node : Next)
transform_many node.exps
node
end
def transform(node : Yield)
if scope = node.scope
node.scope = scope.transform(self)
end
transform_many node.exps
node
end
def transform(node : Include)
node.name = node.name.transform(self)
node
end
def transform(node : Extend)
node.name = node.name.transform(self)
node
end
def transform(node : RangeLiteral)
node.from = node.from.transform(self)
node.to = node.to.transform(self)
node
end
def transform(node : Assign)
node.target = node.target.transform(self)
node.value = node.value.transform(self)
node
end
def transform(node : Nop)
node
end
def transform(node : NilLiteral)
node
end
def transform(node : BoolLiteral)
node
end
def transform(node : NumberLiteral)
node
end
def transform(node : CharLiteral)
node
end
def transform(node : StringLiteral)
node
end
def transform(node : SymbolLiteral)
node
end
def transform(node : RegexLiteral)
node
end
def transform(node : Var)
node
end
def transform(node : MetaVar)
node
end
def transform(node : InstanceVar)
node
end
def transform(node : ClassVar)
node
end
def transform(node : Global)
node
end
def transform(node : Require)
node
end
def transform(node : Path)
node
end
def transform(node : Self)
node
end
def transform(node : LibDef)
node.body = node.body.transform(self)
node
end
def transform(node : FunDef)
if body = node.body
node.body = body.transform(self)
end
node
end
def transform(node : TypeDef)
node
end
def transform(node : StructDef)
node
end
def transform(node : UnionDef)
node
end
def transform(node : EnumDef)
node
end
def transform(node : ExternalVar)
node
end
def transform(node : IndirectRead)
node.obj = node.obj.transform(self)
node
end
def transform(node : IndirectWrite)
node.obj = node.obj.transform(self)
node.value = node.value.transform(self)
node
end
def transform(node : TypeOf)
transform_many node.expressions
node
end
def transform(node : Primitive)
node
end
def transform(node : Not)
node
end
def transform(node : TypeFilteredNode)
node
end
def transform(node : TupleLiteral)
transform_many node.exps
node
end
def transform(node : Cast)
node.obj = node.obj.transform(self)
node.to = node.to.transform(self)
node
end
def transform(node : DeclareVar)
node.var = node.var.transform(self)
node.declared_type = node.declared_type.transform(self)
node
end
def transform(node : Alias)
node.value = node.value.transform(self)
node
end
def transform(node : TupleIndexer)
node
end
def transform(node : Attribute)
node
end
def transform_many(exps)
exps.map! { |exp| exp.transform(self) } if exps
end
end
end

31
samples/E/Extends.E Normal file
View File

@@ -0,0 +1,31 @@
# from
# http://wiki.erights.org/wiki/Walnut/Ordinary_Programming/Objects_and_Functions
def makeVehicle(self) {
def vehicle {
to milesTillEmpty() {
return self.milesPerGallon() * self.getFuelRemaining()
}
}
return vehicle
}
def makeCar() {
var fuelRemaining := 20
def car extends makeVehicle(car) {
to milesPerGallon() {return 19}
to getFuelRemaining() {return fuelRemaining}
}
return car
}
def makeJet() {
var fuelRemaining := 2000
def jet extends makeVehicle(jet) {
to milesPerGallon() {return 2}
to getFuelRemaining() {return fuelRemaining}
}
return jet
}
def car := makeCar()
println(`The car can go ${car.milesTillEmpty()} miles.`)

21
samples/E/Functions.E Normal file
View File

@@ -0,0 +1,21 @@
# from
# http://wiki.erights.org/wiki/Walnut/Ordinary_Programming/Objects_and_Functions
def makeCar(var name) {
var x := 0
var y := 0
def car {
to moveTo(newX,newY) {
x := newX
y := newY
}
to getX() {return x}
to getY() {return y}
to setName(newName) {name := newName}
to getName() {return name}
}
return car
}
# Now use the makeCar function to make a car, which we will move and print
def sportsCar := makeCar("Ferrari")
sportsCar.moveTo(10,20)
println(`The car ${sportsCar.getName()} is at X location ${sportsCar.getX()}`)

69
samples/E/Guards.E Normal file
View File

@@ -0,0 +1,69 @@
# from
# http://wiki.erights.org/wiki/Walnut/Advanced_Topics/Build_your_Own_Guards
def makeVOCPair(brandName :String) :near {
var myTempContents := def none {}
def brand {
to __printOn(out :TextWriter) :void {
out.print(brandName)
}
}
def ProveAuth {
to __printOn(out :TextWriter) :void {
out.print(`<$brandName prover>`)
}
to getBrand() :near { return brand }
to coerce(specimen, optEjector) :near {
def sealedBox {
to getBrand() :near { return brand }
to offerContent() :void {
myTempContents := specimen
}
}
return sealedBox
}
}
def CheckAuth {
to __printOn(out :TextWriter) :void {
out.print(`<$brandName checker template>`)
}
to getBrand() :near { return brand }
match [`get`, authList :any[]] {
def checker {
to __printOn(out :TextWriter) :void {
out.print(`<$brandName checker>`)
}
to getBrand() :near { return brand }
to coerce(specimenBox, optEjector) :any {
myTempContents := null
if (specimenBox.__respondsTo("offerContent", 0)) {
# XXX Using __respondsTo/2 here is a kludge
specimenBox.offerContent()
} else {
myTempContents := specimenBox
}
for auth in authList {
if (auth == myTempContents) {
return auth
}
}
myTempContents := none
throw.eject(optEjector,
`Unmatched $brandName authorization`)
}
}
}
match [`__respondsTo`, [`get`, _]] {
true
}
match [`__respondsTo`, [_, _]] {
false
}
match [`__getAllegedType`, []] {
null.__getAllegedType()
}
}
return [ProveAuth, CheckAuth]
}

14
samples/E/IO.E Normal file
View File

@@ -0,0 +1,14 @@
# E sample from
# http://wiki.erights.org/wiki/Walnut/Ordinary_Programming/InputOutput
#File objects for hardwired files:
def file1 := <file:myFile.txt>
def file2 := <file:/home/marcs/myFile.txt>
#Using a variable for a file name:
def filePath := "c:\\docs\\myFile.txt"
def file3 := <file>[filePath]
#Using a single character to specify a Windows drive
def file4 := <file:c:/docs/myFile.txt>
def file5 := <c:/docs/myFile.txt>
def file6 := <c:\docs\myFile.txt>

9
samples/E/Promises.E Normal file
View File

@@ -0,0 +1,9 @@
# E snippet from
# http://wiki.erights.org/wiki/Walnut/Distributed_Computing/Promises
when (tempVow) -> {
#...use tempVow
} catch prob {
#.... report problem
} finally {
#....log event
}

18
samples/E/minChat.E Normal file
View File

@@ -0,0 +1,18 @@
# from
# http://wiki.erights.org/wiki/Walnut/Secure_Distributed_Computing/Auditing_minChat
pragma.syntax("0.9")
to send(message) {
when (friend<-receive(message)) -> {
chatUI.showMessage("self", message)
} catch prob {chatUI.showMessage("system", "connection lost")}
}
to receive(message) {chatUI.showMessage("friend", message)}
to receiveFriend(friendRcvr) {
bind friend := friendRcvr
chatUI.showMessage("system", "friend has arrived")
}
to save(file) {file.setText(makeURIFromObject(chatController))}
to load(file) {
bind friend := getObjectFromURI(file.getText())
friend <- receiveFriend(chatController)
}

View File

@@ -0,0 +1,76 @@
*Basic example of transport model from GAMS model library
$Title A Transportation Problem (TRNSPORT,SEQ=1)
$Ontext
This problem finds a least cost shipping schedule that meets
requirements at markets and supplies at factories.
Dantzig, G B, Chapter 3.3. In Linear Programming and Extensions.
Princeton University Press, Princeton, New Jersey, 1963.
This formulation is described in detail in:
Rosenthal, R E, Chapter 2: A GAMS Tutorial. In GAMS: A User's Guide.
The Scientific Press, Redwood City, California, 1988.
The line numbers will not match those in the book because of these
comments.
$Offtext
Sets
i canning plants / seattle, san-diego /
j markets / new-york, chicago, topeka / ;
Parameters
a(i) capacity of plant i in cases
/ seattle 350
san-diego 600 /
b(j) demand at market j in cases
/ new-york 325
chicago 300
topeka 275 / ;
Table d(i,j) distance in thousands of miles
new-york chicago topeka
seattle 2.5 1.7 1.8
san-diego 2.5 1.8 1.4 ;
Scalar f freight in dollars per case per thousand miles /90/ ;
Parameter c(i,j) transport cost in thousands of dollars per case ;
c(i,j) = f * d(i,j) / 1000 ;
Variables
x(i,j) shipment quantities in cases
z total transportation costs in thousands of dollars ;
Positive Variable x ;
Equations
cost define objective function
supply(i) observe supply limit at plant i
demand(j) satisfy demand at market j ;
cost .. z =e= sum((i,j), c(i,j)*x(i,j)) ;
supply(i) .. sum(j, x(i,j)) =l= a(i) ;
demand(j) .. sum(i, x(i,j)) =g= b(j) ;
Model transport /all/ ;
Solve transport using lp minimizing z ;
Display x.l, x.m ;
$ontext
#user model library stuff
Main topic Basic GAMS
Featured item 1 Trnsport model
Featured item 2
Featured item 3
Featured item 4
Description
Basic example of transport model from GAMS model library
$offtext

View File

@@ -0,0 +1,9 @@
static const char* SimpleFragmentShader = STRINGIFY(
varying vec4 FrontColor;
void main(void)
{
gl_FragColor = FrontColor;
}
);

View File

@@ -0,0 +1,48 @@
#version 330 core
// cross-unit recursion
void main() {}
// two-level recursion
float cbar(int);
void cfoo(float)
{
cbar(2);
}
// four-level, out of order
void CB();
void CD();
void CA() { CB(); }
void CC() { CD(); }
// high degree
void CBT();
void CDT();
void CAT() { CBT(); CBT(); CBT(); }
void CCT() { CDT(); CDT(); CBT(); }
// not recursive
void norA() {}
void norB() { norA(); }
void norC() { norA(); }
void norD() { norA(); }
void norE() { norB(); }
void norF() { norB(); }
void norG() { norE(); }
void norH() { norE(); }
void norI() { norE(); }
// not recursive, but with a call leading into a cycle if ignoring direction
void norcA() { }
void norcB() { norcA(); }
void norcC() { norcB(); }
void norcD() { norcC(); norcB(); } // head of cycle
void norcE() { norcD(); } // lead into cycle

View File

@@ -0,0 +1,2 @@
#!/usr/bin/env groovy
println "Hello World"

View File

@@ -0,0 +1,9 @@
html {
head {
component "bootstrap"
title "Bootstrap Template"
}
html {
}
}

View File

@@ -0,0 +1,9 @@
html {
head {
title "Example Template"
}
body {
p "This is a quick template example"
}
}

View File

@@ -0,0 +1,60 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
<html>
<head>
$Common_meta()$
<title>
Android API Differences Report
</title>
<body>
<div class="body">
$Header()$
<div class="content">
<h2>Android API Differences Report</h2>
<p>This document details the changes in the Android framework API. It shows
additions, modifications, and removals for packages, classes, methods, and
fields. Each reference to an API change includes a brief description of the
API and an explanation of the change and suggested workaround, where available.</p>
<p>The differences described in this report are based a comparison of the APIs
whose versions are specified in the upper-right corner of this page. It compares a
newer "to" API to an older "from" version, noting any changes relative to the
older API. So, for example, indicated API removals are no longer present in the "to"
API.</p>
<p>For more information about the Android framework API and SDK,
see the <a href="http://code.google.com/android/index.html" target="_top">Android product site</a>.</p>
$if(no_delta)$
<h3>Congratulation!</h3>
No differences were detected between the two provided APIs.
$endif$
$if(removed_packages)$
$Table(name="Removed Packages", rows=removed_packages:{$it.from:ModelElementRow()$})$
<br/>
$endif$
$if(added_packages)$
$Table(name="Added Packages", rows=added_packages:{$it.to:PackageAddedLink()$}:SimpleTableRow())$
<br/>
$endif$
$if(changed_packages)$
$Table(name="Changed Packages", rows=changed_packages:{$it.to:PackageChangedLink()$}:SimpleTableRow())$
<br/>
$endif$
</div>
</div>
</body>
</html>

31
samples/HTML/pages.html Normal file
View File

@@ -0,0 +1,31 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<title>Related Pages</title>
<link href="qt.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div class=header>
<a class=headerLink href="index.html">Main Page</a> &middot;
<a class=headerLink href="classoverview.html">Class Overview</a> &middot;
<a class=headerLink href="hierarchy.html">Hierarchy</a> &middot;
<a class=headerLink href="annotated.html">All Classes</a>
</div>
<!-- Generated by Doxygen 1.8.1.2 -->
</div><!-- top -->
<div class="header">
<div class="headertitle">
<div class="title">Related Pages</div> </div>
</div><!--header-->
<div class="contents">
<div class="textblock">Here is a list of all related documentation pages:</div><div class="directory">
<table class="directory">
<tr id="row_0_" class="even"><td class="entry"><img src="ftv2node.png" alt="o" width="16" height="22" /><a class="el" href="classoverview.html" target="_self">Class Overview</a></td><td class="desc"></td></tr>
<tr id="row_1_"><td class="entry"><img src="ftv2lastnode.png" alt="\" width="16" height="22" /><a class="el" href="thelayoutsystem.html" target="_self">The Layout System</a></td><td class="desc"></td></tr>
</table>
</div><!-- directory -->
</div><!-- contents -->
<div class="footer" />Generated with <a href="http://www.doxygen.org/index.html">Doxygen</a> 1.8.1.2</div>
</body>
</html>

6
samples/Haskell/Hello.hs Normal file
View File

@@ -0,0 +1,6 @@
import Data.Char
main :: IO ()
main = do
let hello = "hello world"
putStrLn $ map toUpper hello

33
samples/Haskell/Main.hs Normal file
View File

@@ -0,0 +1,33 @@
module Main where
import Sudoku
import Data.Maybe
sudoku :: Sudoku
sudoku = [8, 0, 1, 3, 4, 0, 0, 0, 0,
4, 3, 0, 8, 0, 0, 1, 0, 7,
0, 0, 0, 0, 6, 0, 0, 0, 3,
2, 0, 8, 0, 5, 0, 0, 0, 9,
0, 0, 9, 0, 0, 0, 7, 0, 0,
6, 0, 0, 0, 7, 0, 8, 0, 4,
3, 0, 0, 0, 1, 0, 0, 0, 0,
1, 0, 5, 0, 0, 6, 0, 4, 2,
0, 0, 0, 0, 2, 4, 3, 0, 8]
{-
sudoku :: Sudoku
sudoku = [8, 6, 1, 3, 4, 7, 2, 9, 5,
4, 3, 2, 8, 9, 5, 1, 6, 7,
9, 5, 7, 1, 6, 2, 4, 8, 3,
2, 7, 8, 4, 5, 1, 6, 3, 9,
5, 4, 9, 6, 8, 3, 7, 2, 1,
6, 1, 3, 2, 7, 9, 8, 5, 4,
3, 2, 4, 9, 1, 8, 5, 7, 6,
1, 8, 5, 7, 3, 6, 9, 4, 2,
7, 9, 6, 5, 2, 4, 3, 1, 8]
-}
main :: IO ()
main = do
putStrLn $ pPrint sudoku ++ "\n\n"
putStrLn $ pPrint $ fromMaybe [] $ solve sudoku

46
samples/Haskell/Sudoku.hs Normal file
View File

@@ -0,0 +1,46 @@
module Sudoku
(
Sudoku,
solve,
isSolved,
pPrint
) where
import Data.Maybe
import Data.List
import Data.List.Split
type Sudoku = [Int]
solve :: Sudoku -> Maybe Sudoku
solve sudoku
| isSolved sudoku = Just sudoku
| otherwise = do
index <- elemIndex 0 sudoku
let sudokus = [nextTest sudoku index i | i <- [1..9],
checkRow (nextTest sudoku index i) index,
checkColumn (nextTest sudoku index i) index,
checkBox (nextTest sudoku index i) index]
listToMaybe $ mapMaybe solve sudokus
where nextTest sudoku index i = take index sudoku ++ [i] ++ drop (index+1) sudoku
checkRow sudoku index = (length $ getRow sudoku index) == (length $ nub $ getRow sudoku index)
checkColumn sudoku index = (length $ getColumn sudoku index) == (length $ nub $ getColumn sudoku index)
checkBox sudoku index = (length $ getBox sudoku index) == (length $ nub $ getBox sudoku index)
getRow sudoku index = filter (/=0) $ (chunksOf 9 sudoku) !! (quot index 9)
getColumn sudoku index = filter (/=0) $ (transpose $ chunksOf 9 sudoku) !! (mod index 9)
getBox sudoku index = filter (/=0) $ (map concat $ concatMap transpose $ chunksOf 3 $ map (chunksOf 3) $ chunksOf 9 sudoku)
!! (3 * (quot index 27) + (quot (mod index 9) 3))
isSolved :: Sudoku -> Bool
isSolved sudoku
| product sudoku == 0 = False
| map (length . nub) sudokuRows /= map length sudokuRows = False
| map (length . nub) sudokuColumns /= map length sudokuColumns = False
| map (length . nub) sudokuBoxes /= map length sudokuBoxes = False
| otherwise = True
where sudokuRows = chunksOf 9 sudoku
sudokuColumns = transpose sudokuRows
sudokuBoxes = map concat $ concatMap transpose $ chunksOf 3 $ map (chunksOf 3) $ chunksOf 9 sudoku
pPrint :: Sudoku -> String
pPrint sudoku = intercalate "\n" $ map (intercalate " " . map show) $ chunksOf 9 sudoku

View File

@@ -0,0 +1,6 @@
Version 1 of Trivial Extension by Andrew Plotkin begins here.
A cow is a kind of animal. A cow can be purple.
Trivial Extension ends here.

12
samples/Inform 7/story.ni Normal file
View File

@@ -0,0 +1,12 @@
"Test Case" by Andrew Plotkin.
Include Trivial Extension by Andrew Plotkin.
The Kitchen is a room.
[This kitchen is modelled after the one in Zork, although it lacks the detail to establish this to the player.]
A purple cow called Gelett is in the Kitchen.
Instead of examining Gelett:
say "You'd rather see than be one."

View File

@@ -0,0 +1,46 @@
theory HelloWorld
imports Main
begin
section{*Playing around with Isabelle*}
text{* creating a lemma with the name hello_world*}
lemma hello_world: "True" by simp
(*inspecting it*)
thm hello_world
text{* defining a string constant HelloWorld *}
definition HelloWorld :: "string" where
"HelloWorld \<equiv> ''Hello World!''"
(*reversing HelloWorld twice yilds HelloWorld again*)
theorem "rev (rev HelloWorld) = HelloWorld"
by (fact List.rev_rev_ident)
text{*now we delete the already proven List.rev_rev_ident lema and show it by hand*}
declare List.rev_rev_ident[simp del]
hide_fact List.rev_rev_ident
(*It's trivial since we can just 'execute' it*)
corollary "rev (rev HelloWorld) = HelloWorld"
apply(simp add: HelloWorld_def)
done
text{*does it hold in general?*}
theorem rev_rev_ident:"rev (rev l) = l"
proof(induction l)
case Nil thus ?case by simp
next
case (Cons l ls)
assume IH: "rev (rev ls) = ls"
have "rev (l#ls) = (rev ls) @ [l]" by simp
hence "rev (rev (l#ls)) = rev ((rev ls) @ [l])" by simp
also have "\<dots> = [l] @ rev (rev ls)" by simp
finally show "rev (rev (l#ls)) = l#ls" using IH by simp
qed
corollary "\<forall>(l::string). rev (rev l) = l" by(fastforce intro: rev_rev_ident)
end

View File

@@ -0,0 +1,24 @@
/*
invoke endpoint by calling in a browser:
http://<hanaserveradress>:<xsengineport(usually 8000)>/<path>/<to>/<endpoint>/helloHanaMath.xsjslib?x=4&y=2
e.g.:
http://192.168.178.20:8000/geekflyer/linguist/helloHanaEndpoint.xsjs?x=4&y=2
*/
var hanaMath = $.import("./helloHanaMath.xsjslib");
var x = parseFloat($.request.parameters.get("x"));
var y = parseFloat($.request.parameters.get("y"));
var result = hanaMath.multiply(x, y);
var output = {
title: "Hello HANA XS - do some simple math",
input: {x: x, y: y},
result: result
};
$.response.contentType = "application/json";
$.response.statusCode = $.net.http.OK;
$.response.setBody(JSON.stringify(output));

View File

@@ -0,0 +1,9 @@
/* simple hana xs demo library, which can be used by multiple endpoints */
function multiply(x, y) {
return x * y;
}
function add(x, y) {
return x + y;
}

View File

@@ -0,0 +1,7 @@
(function(window, angular) {
Array.prototype.last = function() {
return this[this.length-1];
};
var app = angular.module('ConwayGameOfLife', []);

View File

@@ -0,0 +1,3 @@
})(window, window.angular);

8
samples/Kit/demo.kit Normal file
View File

@@ -0,0 +1,8 @@
<!-- $pageTitle: The Kit Language -->
<section>
<h1><!-- $pageTitle --></h1>
<p>
<!-- @include "loremipsum" -->
</p>
</section>

View File

@@ -0,0 +1,59 @@
{**
* @param string $basePath web base path
* @param string $robots tell robots how to index the content of a page (optional)
* @param array $flashes flash messages
*}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="description" content="">
<meta name="author" content="">
<meta name="robots" content="{$robots}" n:ifset="$robots">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{ifset $title}{$title} {/ifset}Translation report</title>
<link rel="stylesheet" media="screen,projection,tv" href="{$cdnUrl}/css/style.css?v={$cssHash}">
<link rel="shortcut icon" href="{$cdnUrl}/favicon.png">
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
<![endif]-->
<script n:syntax="off">
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-33892654-4', 'khanovaskola.cz');
ga('send', 'pageview');
</script>
{block #head}{/block}
</head>
<body class="amara-guest history-empty">
<script> document.documentElement.className+=' js' </script>
{block #navbar}
{include _navbar.latte}
{/block}
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2" n:inner-foreach="$flashes as $flash">
{include _flash.latte, flash => $flash}
</div>
</div>
{include #content}
</div>
<footer>
</footer>
<script src="{$cdnUrl}/js/compiled.js?v={$jsHash}"></script>
{block #scripts}{/block}
</body>
</html>

View File

@@ -0,0 +1,243 @@
{var $title => "⚐ {$new->title}"}
{define author}
<a n:href="Author: authorId => $author->id" class="black">
<img src="{$author->avatar}" width="32" height="32" class="img-rounded">
<span class="{$class}">{$author->name|trim}</span>
</a>
<span data-toggle="tooltip" title="Total time {$author->shortName} translated on all videos.">
{$author->estimatedTimeTranslated|secondsToTime}{*
*}</span>{if $author->joined}, {/if}
{if $author->joined}joined {$author->joined|timeAgo}{/if}{*
*}{ifset $postfix}, {$postfix}{/ifset}
{/define}
{block #scripts}
<script src="{$amaraCallbackLink}"></script>
{/block}
{block #content}
{if isset($old)}
<h1>Diffing revision #{$old->revision} and #{$new->revision}</h1>
{else}
<h1>First revision</h1>
{/if}
{var $editor = $user->loggedIn && $new->language === 'cs'}
{var $rev = $new->video->siteRevision}
<div class="row">
<div class="col-md-7">
<p>
published <b>{$new->publishedAt|timeAgo}</b>{*
*}{ifset $old},
<span>
{$new->textChange * 100|number}&thinsp;% text change{*
*}</span>{*
*}{if $new->timeChange},
<span>
{$new->timeChange * 100|number}&thinsp;% timing change
</span>
{/if}
{/ifset}
</p>
{cache $new->id, expires => '+4 hours'}
<p>
{if isset($old) && $old->author->name !== $new->author->name}
{include author, author => $old->author, class => 'author-old'}
&mdash;
{include author, author => $new->author, class => 'author-new'}
{elseif isset($old)}
{include author, author => $new->author, class => 'author-new', postfix => 'authored both revisions'}
{else}
{include author, author => $new->author, class => 'author-new'}
{/if}
</p>
{/cache}
{var $threshold = 10}
{cache $new->id}
{var $done = $new->timeTranslated}
{var $outOf = $new->video->canonicalTimeTranslated}
{if $outOf}
<p n:if="$outOf > $done + $threshold" class="alert alert-warning">
Only {$done|time} translated out of {$outOf|time},
{(1-$done/$outOf) * 100|number}&thinsp;% ({$outOf - $done|time}) left
</p>
<p n:if="$outOf <= $done + $threshold" class="alert alert-success">
Seems complete: {$done|time} translated out of {$outOf|time}
</p>
{elseif $done}
<p n:if="$outOf <= $done + $threshold" class="alert alert-info">
Although {$done|time} is translated, there are no English subtitles for comparison.
</p>
{/if}
{/cache}
{if $editor}
{var $ksid = $new->video->siteId}
{if $ksid}
<a href="https://khanovaskola.cz/watch/default/?vid={$ksid}">
Video on khanovaskola.cz
{if $new->revision === $rev}
(on this revision)
{elseif $new->revision > $rev}
(on older revision #{$rev})
{else}
(on newer revision #{$rev})
{/if}
</a>
{/if}
{/if}
<h3 class="diff">{$diffs->title|noescape}</h3>
<div class="lead diff">{$diffs->description|noescape}</div>
<div class="diff subtitles">
<div n:foreach="$diffs->text as $line" class="line" data-context="{$line->context}">
{$line->text|noescape}&nbsp;
</div>
<div class="splitter template">
<span data-toggle="tooltip" data-placement="bottom" title="Expand">
<i class="fa fa-sort"></i> <i class="fa fa-ellipsis-h"></i>
</span>
</div>
</div>
{if $editor}
{if $new->approved}
<span class="text-success">
Revision has been approved{if $new->editor} by {$new->editor->name}{/if}.
</span>
<a n:href="amaraEdit, amaraId => $new->video->amaraId" n:block="editButton" class="btn btn-default">
<i class="fa fa-edit"></i>
Edit on Amara
</a>
<a n:href="khanAcademy" n:block="kaButton" class="btn btn-link">
on Khan Academy
</a>
{elseif $new->incomplete}
<span class="text-info">
Revision has been marked as incomplete by {if $new->editor}{$new->editor->name}{/if}.
</span>
{include editButton}
{include kaButton}
{* else $new->status === UNSET: *}
{elseif $new->video->siteId}
<div class="btn-group">
<a n:href="approve!" class="btn btn-default">
<i class="fa fa-thumbs-o-up"></i>
Approve (update kš)
</a>
<a n:href="markIncomplete!" class="btn btn-default">
<i class="fa fa-thumbs-o-down"></i>
Mark as incomplete
</a>
{include editButton}
</div>
{include kaButton}
{else}
<div class="btn-group">
<a n:href="redirectToAdd!" class="btn btn-default">
<i class="fa fa-plus-square-o"></i>
Approve (add to kš)
</a>
<a n:href="markIncomplete!" class="btn btn-default">
<i class="fa fa-thumbs-o-down"></i>
Mark as incomplete
</a>
{include editButton}
</div>
{include kaButton}
<div>
<h5>Filed under category:</h5>
{foreach $new->video->categories as $list}
&mdash; {$list|implode:' '}{sep}<br>{/sep}
{/foreach}
</div>
{/if}
{/if}
</div>
<div class="col-md-5">
<h4>All revisions:</h4>
<table class="table table-condensed revisions">
{foreach $new->video->getRevisionsIn($new->language) as $revision}
<tr n:class="$revision->revision === $new->revision ? 'active'">
<td class="revision">
<a n:href="this, revId => $revision->id">#{$revision->revision}</a>
</td>
<td>
<a n:href="Author: authorId => $revision->author->id" class="black">
<img src="{$revision->author->avatar}" width="32" height="32" class="img-rounded">
{$revision->author->name}
</a>
</td>
<td>
<span class="secondary">
{$revision->publishedAt|timeAgo}
</span>
</td>
<td>
{* vars $outOf, $threshold already set *}
{default $outOf = $new->video->canonicalTimeTranslated}
{if $outOf} {* ignore if canonical time not set *}
{var $done = $revision->timeTranslated}
<span n:if="$outOf > $done + $threshold" class="text-warning"
data-toggle="tooltip" title="Percent of lines translated">
{$done/$outOf * 100|number}&thinsp;%
</span>
<span n:if="$outOf <= $done + $threshold" class="text-success">
~100&thinsp;%
</span>
{/if}
</td>
<td>
{if $revision->incomplete || $revision->approved}
{var $i = $revision->incomplete}
<span n:class="$i ? 'text-warning' : 'text-success'">
{if $i}incomplete{else}approved{/if}
</span>
{/if}
</td>
{if $user->loggedIn && $revision->comments->count()}
</tr>
<tr class="row-noborder">
<td colspan="99">
<table class="comments">
<tr n:foreach="$revision->comments as $comment">
<td class="col-comment-author">
<span class="secondary" data-toggle="tooltip" data-placement="left"
title="{$comment->createdAt|timeAgo}">
{$comment->user->name}:
</span>
</td>
<td>
<span>
{$comment->text}
</span>
</td>
</tr>
</table>
</td>
{/if}
{if $user->loggedIn && $new->id === $revision->id}
</tr>
<tr class="row-noborder">
<td colspan="99">
{form commentForm}
<div class="input-group comment-input">
{input text, class => "form-control", placeholder => "Comment this revision (only visible to other editors)"}
<span class="input-group-btn">
<button class="btn btn-default" n:name="save">
<i class="fa fa-share"></i>
</button>
</span>
</div>
{/form}
</td>
{/if}
</tr>
{/foreach}
</table>
</div>
</div>

View File

@@ -0,0 +1,104 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>{{shop.name}} - {{page_title}}</title>
{{ 'textile.css' | global_asset_url | stylesheet_tag }}
{{ 'lightbox/v204/lightbox.css' | global_asset_url | stylesheet_tag }}
{{ 'prototype/1.6/prototype.js' | global_asset_url | script_tag }}
{{ 'scriptaculous/1.8.2/scriptaculous.js' | global_asset_url | script_tag }}
{{ 'lightbox/v204/lightbox.js' | global_asset_url | script_tag }}
{{ 'option_selection.js' | shopify_asset_url | script_tag }}
{{ 'layout.css' | asset_url | stylesheet_tag }}
{{ 'shop.js' | asset_url | script_tag }}
{{ content_for_header }}
</head>
<body id="page-{{template}}">
<p class="hide"><a href="#rightsiders">Skip to navigation.</a></p>
<!-- mini cart -->
{% if cart.item_count > 0 %}
<div id="minicart" style="display:none;"><div id="minicart-inner">
<div id="minicart-items">
<h2>There {{ cart.item_count | pluralize: 'is', 'are' }} {{ cart.item_count }} {{ cart.item_count | pluralize: 'item', 'items' }} in <a href="/cart" title="View your cart">your cart</a>!</h2><h4 style="font-size: 16px; margin: 0 0 10px 0; padding: 0;">Your subtotal is {{ cart.total_price | money }}.</h4>
{% for item in cart.items %}
<div class="thumb">
<div class="prodimage"><a href="{{item.product.url}}" onMouseover="tooltip('{{ item.quantity }} x {{ item.title }} ({{ item.variant.title }})', 200)"; onMouseout="hidetooltip()"><img src="{{ item.product.featured_image | product_img_url: 'thumb' }}" /></a></div>
</div>
{% endfor %}
</div>
<br style="clear:both;" />
</div></div>
{% endif %}
<div id="container">
<div id="header">
<!-- Begin Header -->
<h1 id="logo"><a href="/" title="Go Home">{{shop.name}}</a></h1>
<div id="cartlinks">
{% if cart.item_count > 0 %}
<h2 id="cartcount"><a href="/cart" onMouseover="tooltip('There {{ cart.item_count | pluralize: 'is', 'are' }} {{ cart.item_count }} {{ cart.item_count | pluralize: 'item', 'items' }} in your cart!', 200)"; onMouseout="hidetooltip()">{{ cart.item_count }} {{ cart.item_count | pluralize: 'thing', 'things' }}!</a></h2>
<a href="/cart" id="minicartswitch" onclick="superSwitch(this, 'minicart', 'Close Mini Cart'); return false;" id="cartswitch">View Mini Cart ({{ cart.total_price | money }})</a>
{% endif %}
</div>
<!-- End Header -->
</div>
<hr />
<div id="main">
<div id="content">
<div id="innercontent">
{{ content_for_layout }}
</div>
</div>
<hr />
<div id="rightsiders">
<ul class="rightlinks">
{% for link in linklists.main-menu.links %}
<li>{{ link.title | link_to: link.url }}</li>
{% endfor %}
</ul>
{% if tags %}
<ul class="rightlinks">
{% for tag in collection.tags %}
<li><span class="add-link">{{ '+' | link_to_add_tag: tag }}</span>{{ tag | highlight_active_tag | link_to_tag: tag }}</li>
{% endfor %}
</ul>
{% endif %}
<ul class="rightlinks">
{% for link in linklists.footer.links %}
<li>{{ link.title | link_to: link.url }}</li>
{% endfor %}
</ul>
</div>
<hr /><br style="clear:both;" />
<div id="footer">
<div class="footerinner">
All prices are in {{ shop.currency }}.
Powered by <a href="http://www.shopify.com" title="Shopify, Hosted E-Commerce">Shopify</a>.
</div>
</div>
</div>
</div>
<div id="tooltip"></div>
<img id="pointer" src="{{ 'arrow2.gif' | asset_url }}" />
</body>
</html>

View File

@@ -0,0 +1,70 @@
<h3>We have wonderful products!</h3>
<ul id="products">
<div id="productpage">
<div id="productimages"><div id="productimages-top"><div id="productimages-bottom">
{% for image in product.images %}
{% if forloop.first %}
<a href="{{ image | product_img_url: 'large' }}" class="productimage" rel="lightbox">
<img src="{{ image | product_img_url: 'medium'}}" alt="{{product.title | escape }}" />
</a>
{% else %}
<a href="{{ image | product_img_url: 'large' }}" class="productimage-small" rel="lightbox">
<img src="{{ image | product_img_url: 'small'}}" alt="{{product.title | escape }}" />
</a>
{% endif %}
{% endfor %}
</div></div></div>
<h2>{{ product.title }}</h2>
<ul id="details" class="hlist">
<li>Vendor: {{ product.vendor | link_to_vendor }}</li>
<li>Type: {{ product.type | link_to_type }}</li>
</ul>
<small>{{ product.price_min | money }}{% if product.price_varies %} - {{ product.price_max | money }}{% endif %}</small>
<div id="variant-add">
<form action="/cart/add" method="post">
<select id="variant-select" name="id" class="product-info-options">
{% for variant in product.variants %}
<option value="{{ variant.id }}">{{ variant.title }} - {{ variant.price | money }}</option>
{% endfor %}
</select>
<div id="price-field" class="price"></div>
<div style="text-align:center;"><input type="image" name="add" value="Add to Cart" id="add" src="{{ 'addtocart.gif' | asset_url }}" /></div>
</form>
</div>
<div class="description textile">
{{ product.description }}
</div>
</div>
<script type="text/javascript">
<!--
// prototype callback for multi variants dropdown selector
var selectCallback = function(variant, selector) {
if (variant && variant.available == true) {
// selected a valid variant
$('add').removeClassName('disabled'); // remove unavailable class from add-to-cart button
$('add').disabled = false; // reenable add-to-cart button
$('price-field').innerHTML = Shopify.formatMoney(variant.price, "{{shop.money_with_currency_format}}"); // update price field
} else {
// variant doesn't exist
$('add').addClassName('disabled'); // set add-to-cart button to unavailable class
$('add').disabled = true; // disable add-to-cart button
$('price-field').innerHTML = (variant) ? "Sold Out" : "Unavailable"; // update price-field message
}
};
// initialize multi selector for product
Event.observe(document, 'dom:loaded', function() {
new Shopify.OptionSelectors("variant-select", { product: {{ product | json }}, onVariantSelected: selectCallback });
});
-->
</script>
</ul>

View File

@@ -0,0 +1,35 @@
<$mt:Var name="num_cols" value="6"$>
<$mt:Var name="index" value="0"$>
<mt:Categories>
<$mt:Var name="index" op="++" setvar="index"$>
<mt:SetVarBlock name="categories{$index}">
<a href="<$mt:CategoryArchiveLink$>"><$mt:CategoryLabel remove_html="1"$></a>
</mt:SetVarBlock>
</mt:Categories>
<$mt:Var name="categories" function="count" setvar="cat_count"$>
<$mt:Var name="cat_count" op="%" value="$num_cols" setvar="modulus"$>
<mt:If name="modulus" gt="0">
<$mt:Var name="cat_count" op="-" value="$modulus" setvar="cat_count_minus_mod"$>
<$mt:Var name="cat_count_minus_mod" op="/" value="$num_cols" setvar="cats_per_col"$>
<$mt:Var name="cats_per_col" op="+" value="1" setvar="cats_per_col"$>
<mt:Else>
<$mt:Var name="cat_count" op="/" value="$num_cols" setvar="cats_per_col"$>
</mt:If>
<mt:SetVarTemplate name="for_inner">
<$mt:Var name="index" op="++" setvar="index"$>
<mt:Unless name="index" gt="$cat_count">
<$mt:Var name="categories{$index}"$>
</mt:Unless>
</mt:SetVarTemplate>
<$mt:Var name="index" value="0"$>
<$mt:Var name="col_num" value="1"$>
<mt:For from="1" to="$num_cols">
<div class="col<$mt:Var name="col_num"$>">
<mt:For from="1" to="$cats_per_col">
<$mt:Var name="for_inner"$>
</mt:For>
</div>
<$mt:Var name="col_num" op="++" setvar="col_num"$>
</mt:For>

View File

@@ -0,0 +1,232 @@
(* Content-type: application/vnd.wolfram.mathematica *)
(*** Wolfram Notebook File ***)
(* http://www.wolfram.com/nb *)
(* CreatedBy='Mathematica 9.0' *)
(*CacheID: 234*)
(* Internal cache information:
NotebookFileLineBreakTest
NotebookFileLineBreakTest
NotebookDataPosition[ 157, 7]
NotebookDataLength[ 7164, 223]
NotebookOptionsPosition[ 6163, 182]
NotebookOutlinePosition[ 6508, 197]
CellTagsIndexPosition[ 6465, 194]
WindowFrame->Normal*)
(* Beginning of Notebook Content *)
Notebook[{
Cell[CellGroupData[{
Cell[BoxData[
RowBox[{
RowBox[{"Solve", "[",
RowBox[{
RowBox[{"y", "'"}], "\[Equal]", " ", "xy"}], "]"}],
"\[IndentingNewLine]"}]], "Input",
CellChangeTimes->{{3.6112716342092056`*^9, 3.6112716549793935`*^9}}],
Cell[BoxData[
RowBox[{"{",
RowBox[{"{",
RowBox[{"xy", "\[Rule]",
SuperscriptBox["y", "\[Prime]",
MultilineFunction->None]}], "}"}], "}"}]], "Output",
CellChangeTimes->{3.6112716579295626`*^9}]
}, Open ]],
Cell[CellGroupData[{
Cell[BoxData[
RowBox[{"Log", "[",
RowBox[{"Sin", "[", "38", "]"}], "]"}]], "Input",
CellChangeTimes->{{3.611271663920905*^9, 3.6112716759275913`*^9}}],
Cell[BoxData[
RowBox[{"Log", "[",
RowBox[{"Sin", "[", "38", "]"}], "]"}]], "Output",
CellChangeTimes->{3.611271678256725*^9}]
}, Open ]],
Cell[CellGroupData[{
Cell[BoxData[
RowBox[{"N", "[",
RowBox[{"Log", "[",
RowBox[{"Sin", "[", "38", "]"}], "]"}], "]"}]], "Input",
NumberMarks->False],
Cell[BoxData[
RowBox[{"-", "1.2161514009320473`"}]], "Output",
CellChangeTimes->{3.611271682061942*^9}]
}, Open ]],
Cell[CellGroupData[{
Cell[BoxData[
RowBox[{"Abs", "[",
RowBox[{"-", "1.2161514009320473`"}], "]"}]], "Input",
NumberMarks->False],
Cell[BoxData["1.2161514009320473`"], "Output",
CellChangeTimes->{3.6112716842780695`*^9}]
}, Open ]],
Cell[CellGroupData[{
Cell[BoxData[
RowBox[{"RealDigits", "[", "1.2161514009320473`", "]"}]], "Input",
NumberMarks->False],
Cell[BoxData[
RowBox[{"{",
RowBox[{
RowBox[{"{",
RowBox[{
"1", ",", "2", ",", "1", ",", "6", ",", "1", ",", "5", ",", "1", ",", "4",
",", "0", ",", "0", ",", "9", ",", "3", ",", "2", ",", "0", ",", "4",
",", "7"}], "}"}], ",", "1"}], "}"}]], "Output",
CellChangeTimes->{3.611271685319129*^9}]
}, Open ]],
Cell[CellGroupData[{
Cell[BoxData[
RowBox[{
RowBox[{"Graph", "[",
RowBox[{"Log", "[", "x", "]"}], "]"}], "\[IndentingNewLine]"}]], "Input",
CellChangeTimes->{{3.611271689258354*^9, 3.611271702038085*^9}}],
Cell[BoxData[
RowBox[{"Graph", "[",
RowBox[{"Log", "[", "x", "]"}], "]"}]], "Output",
CellChangeTimes->{3.611271704295214*^9}]
}, Open ]],
Cell[BoxData[""], "Input",
CellChangeTimes->{{3.611271712769699*^9, 3.6112717423153887`*^9}}],
Cell[CellGroupData[{
Cell[BoxData[
RowBox[{
RowBox[{"Plot", "[",
RowBox[{
RowBox[{"Log", "[", "x", "]"}], ",", " ",
RowBox[{"{",
RowBox[{"x", ",", " ", "0", ",", " ", "10"}], "}"}]}], "]"}],
"\[IndentingNewLine]"}]], "Input",
CellChangeTimes->{{3.6112717573482485`*^9, 3.6112717747822456`*^9}}],
Cell[BoxData[
GraphicsBox[{{}, {},
{Hue[0.67, 0.6, 0.6], LineBox[CompressedData["
1:eJwVzXs81Pkex/GZH7XlsutSQprwqxTSZVfJGp9P6UYqlyxHUhTaLrq4JpVK
0SHRisGWjYiEbHSvb+Q27rllmYwaY6JpwxgZTI7zx/vxejz/eht4H3PyoRgM
Rsj0/t+1MEPjP1Zc8O6L0tCYkJERTokxP5YLLR+MQy2qZWSzX62gWcaFn9s7
5sVFyohY4ZvLs5Ya6AheLQxnyIgFe4fllag6yH4zayhMcYw0FU5SRl8bweS/
wyVFa0aJBsz2VDVrAl8V299DGKPk1yWJllEHmqD42vuI4RopiRvJlYS9bYLZ
a2c4j3pJyS8JbT7eeW/By6ht44vkEXKuxtRu1d4WOB5QmStjSUhO0eMleTda
4EZtHmU5PEyaORsUFte1QFHRg6WjFcNkkZ/bC+11rVC0s8n9nf8wqVGINGNo
tkFRzD3HsYohosXu0misbAdxXml1VdQgKSi80nXErBNo/oP47aliMqAxEGvn
1QlVgoRvezzExCjYznppYifkn+K6CVli8peV8m2BrBNM20LljlmfyXVurK97
RRfcVCpPCXg8QIIF14a2eLyHn6Y4909//UTSlWsvqm/qge1fVjduzhISa/Zp
jwjPHvCM6ZD7BQgJz9/E/GtIDyRsSj3Svl5ItJtj+uru9cBdE2PXZH4vSeDY
20arfYAT6Z3e8axecnFxw49TXR/gU5X5vDu5H4kfvE0RnxSAsqvDMcduPmFk
jD7rihGA7RmZ5qlYPuEo6vFq7gigR67QPetXPqnm+rJy2wUA0hVVHindZOmu
yQwfy17Y4OU185n7e/LpoNH9bqYQPPrPvwn+2kkOXT/zqim+DzJ72WEzdrcT
SprBJ7l9UD/Fag2c005SXasZhWV9kH51Z/aqhjZSo6dpc3WkD4L1tqolbGgj
JndzqmzdRPD67PLxVrNWIn7e0lS28BMs6Ba9FM1pJv7CZYLign6IeWFYmrqk
jvR4/jOrlNsPoqNsieZftcS5I9qsvrcf8tnmIzq6tcSiVnRKqDsALqbKTVU/
1RCFoiw1ragBULG3LYphVhNOuIF1yN7PkFMpYVXI35BSTZ2UdWpfgMls07e/
84QoGUQa8S0GgVn/55MIdixUWyWsOLtpEAIiTazYlglw2e3W2gVOg5BMOVFO
zolAxT/ZsvvwIJAvj7SczqbC+Hex37ubgxD8udJ0tkcmfOa55DRSQ8DwsFzc
6lkIdRyjZa/rhsAywLBSze45xKnVGt/eJwFLB1UN7sVq8O7aRRTqRsFbq7Mr
JqcdTlREeh8zGoeOsKZ1bgF8KDqu4qxtK4c/T0q26boJ4PbpwwMrXRn4N9vd
qamzDy6kTzqOiJmo6OOuteZtPzBaevBFmALy6nNqfwkTw5JA39BdxjPwSH3B
vlWGX6FXmvyb8suZeCtkhRV5NAh2wkNnrp+YhaOXrkQMdg/Bjt54ExZLCdti
v+y2+XcYBt54R1TnKyOH4R+txpOAmXr7Apu9quiaByGbG0dACaRePMmPmLmw
vX84Swpbvrh/M3RRQziRFnP5wih0lB1gupuqY0FCbZyewzcoiS731JeqY4Zj
3+qZP4yB74ygnoYGDcz5GOJ8uXwM9p88XaKSqonn9R26+EdlsMLPpMHeaw4K
rc1neaqOQ6OGqXLQurmYKexKyno4Ds8LLqSZKmhhhvxW6cjWCTjNNHaoe6+F
pidKHHi9E6DEC9vqXzwPGaH7eO6hkyDMNkhMD9fGsUD+Knv5JCQu1VF86qKD
h3vll15HyyE+1bfKS18XbTje/KqZ38E9cU+DikgXNYxUk++f/Q5jG7Nk6a/m
49yHih6fJ7+DQLghtCxKD9We/pFtf2wKMtir5td7LcDHFdUyrmgK8i8Fqfst
Z2H5rdC2ZGMGRrns36YgZWHfc/sj7Z4MNOfdzo2qX4jaWiITpSQGcpal5ddv
08c4nrYPVjPw3OurnG1P9ZGdfship5yB2+e7ZNUsMsAzD/MLtFcycb1/1W71
Kwb4qn7LsIcnE9P1vBfVSQ1QUbd5z75rTFz05m7Sjt2GeHJ9UIrOCybGLy8z
bn5liLETFcsURUz0lSi+5RrTGL/GlX1jDoXeRcP6V67R6DRvQNHcmsIjF5wn
7RJoPPVD0ph42kHOxe9U/qDR/97LrjtAYbQ0KC4+iUa6N+b4nPUUFqyTTSTf
pDFTFtw6bEOhrHSqPTuPRo1786Pv21IY36xytbyKxo0v5z7UdKEwNfPowctc
GuUeojTutDMDG2y21tIYpHQ98NxvFD7Sih+vbaBRfeZZ6YArhTx3zYMtbTRC
CmNNqTuFRgIdm48CGveGmxUf2kfhyuIw1h0hjasPiNIWelFoealL5iOiMZKf
HdA6bXujmw/6B2gk7zZK2PspPHlYnzU0RGN40raf1XwpDLc6L/tbMv0vikor
n/Yl1Y+tgVIayzZ/kIT6UcgpzIwZG6Px0d7RwA8HKcyIUPR7Nk7j8sLHN2/8
TmGeo8+G8Ekab1ncfmR7iMJiw8oF1t9pnF9RQuTTfiVZIpuaonFCb+xJ0WEK
/wc13qzo
"]]}},
AspectRatio->NCache[GoldenRatio^(-1), 0.6180339887498948],
Axes->True,
AxesLabel->{None, None},
AxesOrigin->{0, 0},
Method->{},
PlotRange->{{0, 10}, {-1.623796532045525, 2.3025850725858823`}},
PlotRangeClipping->True,
PlotRangePadding->{
Scaled[0.02],
Scaled[0.02]}]], "Output",
CellChangeTimes->{3.6112717778594217`*^9}]
}, Open ]]
},
WindowSize->{716, 833},
WindowMargins->{{Automatic, 214}, {Automatic, 26}},
FrontEndVersion->"9.0 for Microsoft Windows (64-bit) (January 25, 2013)",
StyleDefinitions->"Default.nb"
]
(* End of Notebook Content *)
(* Internal cache information *)
(*CellTagsOutline
CellTagsIndex->{}
*)
(*CellTagsIndex
CellTagsIndex->{}
*)
(*NotebookFileOutline
Notebook[{
Cell[CellGroupData[{
Cell[579, 22, 224, 6, 52, "Input"],
Cell[806, 30, 211, 6, 31, "Output"]
}, Open ]],
Cell[CellGroupData[{
Cell[1054, 41, 155, 3, 31, "Input"],
Cell[1212, 46, 130, 3, 31, "Output"]
}, Open ]],
Cell[CellGroupData[{
Cell[1379, 54, 137, 4, 31, "Input"],
Cell[1519, 60, 105, 2, 31, "Output"]
}, Open ]],
Cell[CellGroupData[{
Cell[1661, 67, 113, 3, 31, "Input"],
Cell[1777, 72, 90, 1, 31, "Output"]
}, Open ]],
Cell[CellGroupData[{
Cell[1904, 78, 102, 2, 31, "Input"],
Cell[2009, 82, 321, 8, 31, "Output"]
}, Open ]],
Cell[CellGroupData[{
Cell[2367, 95, 191, 4, 52, "Input"],
Cell[2561, 101, 131, 3, 31, "Output"]
}, Open ]],
Cell[2707, 107, 94, 1, 31, "Input"],
Cell[CellGroupData[{
Cell[2826, 112, 299, 8, 52, "Input"],
Cell[3128, 122, 3019, 57, 265, "Output"]
}, Open ]]
}
]
*)
(* End of internal cache information *)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,8 @@
(* ::Package:: *)
(* Problem12.m *)
(* Author: William Woodruff *)
(* Problem: What is the value of the first triangle number to have over five hundred divisors? *)
Do[If[Length[Divisors[Binomial[i + 1, 2]]] > 500,
Print[Binomial[i + 1, 2]]; Break[]], {i, 1000000}]

File diff suppressed because it is too large Load Diff

80
samples/Nix/nginx.nix Normal file
View File

@@ -0,0 +1,80 @@
{ stdenv, fetchurl, fetchgit, openssl, zlib, pcre, libxml2, libxslt, expat
, rtmp ? false
, fullWebDAV ? false
, syslog ? false
, moreheaders ? false, ...}:
let
version = "1.4.4";
mainSrc = fetchurl {
url = "http://nginx.org/download/nginx-${version}.tar.gz";
sha256 = "1f82845mpgmhvm151fhn2cnqjggw9w7cvsqbva9rb320wmc9m63w";
};
rtmp-ext = fetchgit {
url = git://github.com/arut/nginx-rtmp-module.git;
rev = "1cfb7aeb582789f3b15a03da5b662d1811e2a3f1";
sha256 = "03ikfd2l8mzsjwx896l07rdrw5jn7jjfdiyl572yb9jfrnk48fwi";
};
dav-ext = fetchgit {
url = git://github.com/arut/nginx-dav-ext-module.git;
rev = "54cebc1f21fc13391aae692c6cce672fa7986f9d";
sha256 = "1dvpq1fg5rslnl05z8jc39sgnvh3akam9qxfl033akpczq1bh8nq";
};
syslog-ext = fetchgit {
url = https://github.com/yaoweibin/nginx_syslog_patch.git;
rev = "165affd9741f0e30c4c8225da5e487d33832aca3";
sha256 = "14dkkafjnbapp6jnvrjg9ip46j00cr8pqc2g7374z9aj7hrvdvhs";
};
moreheaders-ext = fetchgit {
url = https://github.com/agentzh/headers-more-nginx-module.git;
rev = "refs/tags/v0.23";
sha256 = "12pbjgsxnvcf2ff2i2qdn39q4cm5czlgrng96j8ml4cgxvnbdh39";
};
in
stdenv.mkDerivation rec {
name = "nginx-${version}";
src = mainSrc;
buildInputs = [ openssl zlib pcre libxml2 libxslt
] ++ stdenv.lib.optional fullWebDAV expat;
patches = if syslog then [ "${syslog-ext}/syslog_1.4.0.patch" ] else [];
configureFlags = [
"--with-http_ssl_module"
"--with-http_spdy_module"
"--with-http_xslt_module"
"--with-http_sub_module"
"--with-http_dav_module"
"--with-http_gzip_static_module"
"--with-http_secure_link_module"
"--with-ipv6"
# Install destination problems
# "--with-http_perl_module"
] ++ stdenv.lib.optional rtmp "--add-module=${rtmp-ext}"
++ stdenv.lib.optional fullWebDAV "--add-module=${dav-ext}"
++ stdenv.lib.optional syslog "--add-module=${syslog-ext}"
++ stdenv.lib.optional moreheaders "--add-module=${moreheaders-ext}";
preConfigure = ''
export NIX_CFLAGS_COMPILE="$NIX_CFLAGS_COMPILE -I${libxml2 }/include/libxml2"
'';
# escape example
postInstall = ''
mv $out/sbin $out/bin ''' ''${
${ if true then ${ "" } else false }
'';
meta = {
description = "A reverse proxy and lightweight webserver";
maintainers = [ stdenv.lib.maintainers.raskin];
platforms = stdenv.lib.platforms.all;
inherit version;
};
}

View File

@@ -0,0 +1,72 @@
/** Replicate Imai, Jain and Ching Econometrica 2009 (incomplete).
**/
#include "IJCEmet2009.h"
Kapital::Kapital(L,const N,const entrant,const exit,const KP){
StateVariable(L,N);
this.entrant = entrant;
this.exit = exit;
this.KP = KP;
actual = Kbar*vals/(N-1);
upper = log(actual~.Inf);
}
Kapital::Transit(FeasA) {
decl ent =CV(entrant), stayout = FeasA[][exit.pos], tprob, sigu = CV(KP[SigU]);
if (!v && !ent) return { <0>, ones(stayout) };
tprob = ent ? probn( (upper-CV(KP[Kbe]))/sigu )
: probn( (upper-(CV(KP[Kb0])+CV(KP[Kb2])*upper[v])) / sigu );
tprob = tprob[1:] - tprob[:N-1];
return { vals, tprob.*(1-stayout)+(1.0~zeros(1,N-1)).*stayout };
}
FirmEntry::Run() {
Initialize();
GenerateSample();
BDP->BayesianDP();
}
FirmEntry::Initialize() {
Rust::Initialize(Reachable,0);
sige = new StDeviations("sige",<0.3,0.3>,0);
entrant = new LaggedAction("entrant",d);
KP = new array[Kparams];
KP[Kbe] = new Positive("be",0.5);
KP[Kb0] = new Free("b0",0.0);
KP[Kb1] = new Determined("b1",0.0);
KP[Kb2] = new Positive("b2",0.4);
KP[SigU] = new Positive("sigu",0.4);
EndogenousStates(K = new Kapital("K",KN,entrant,d,KP),entrant);
SetDelta(new Probability("delta",0.85));
kcoef = new Positive("kcoef",0.1);
ecost = new Negative("ec",-0.4);
CreateSpaces();
}
FirmEntry::GenerateSample() {
Volume = LOUD;
EM = new ValueIteration(0);
// EM -> Solve(0,0);
data = new DataSet(0,EM);
data->Simulate(DataN,DataT,0,FALSE);
data->Print("firmentry.xls");
BDP = new ImaiJainChing("FMH",data,EM,ecost,sige,kcoef,KP,delta);
}
/** Capital stock can be positive only for incumbents.
**/
FirmEntry::Reachable() { return CV(entrant)*CV(K) ? 0 : new FirmEntry() ; }
/** The one period return.
<DD>
<pre>U = </pre>
</DD>
**/
FirmEntry::Utility() {
decl ent = CV(entrant),
u =
ent*CV(ecost)+(1-ent)*CV(kcoef)*AV(K)
| 0.0;
return u;
}

View File

@@ -0,0 +1,63 @@
/** Client and Server classes for parallel optimization using CFMPI.**/
#include "ParallelObjective.h"
/** Set up MPI Client-Server support for objective optimization.
@param obj `Objective' to parallelize
@param DONOTUSECLIENT TRUE (default): client node does no object evaluation<br>FALSE after putting servers to work Client node does one evaluation.
**/
ParallelObjective(obj,DONOTUSECLIENT) {
if (isclass(obj.p2p)) {oxwarning("P2P object already exists for "+obj.L+". Nothing changed"); return;}
obj.p2p = new P2P(DONOTUSECLIENT,new ObjClient(obj),new ObjServer(obj));
}
ObjClient::ObjClient(obj) { this.obj = obj; }
ObjClient::Execute() { }
ObjServer::ObjServer(obj) {
this.obj = obj;
basetag = P2P::STOP_TAG+1;
iml = obj.NvfuncTerms;
Nparams = obj.nstruct;
}
/** Wait on the objective client.
**/
ObjServer::Loop(nxtmsgsz) {
Nparams = nxtmsgsz; //free param length is no greater than Nparams
if (Volume>QUIET) println("ObjServer server ",ID," Nparams ",Nparams);
Server::Loop(Nparams);
Recv(ANY_TAG); //receive the ending parameter vector
obj->Encode(Buffer[:Nparams-1]); //encode it.
}
/** Do the objective evaluation.
Receive structural parameter vector and `Objective::Encode`() it.
Call `Objective::vfunc`().
@return Nparams (max. length of next expected message);
**/
ObjServer::Execute() {
obj->Decode(Buffer[:obj.nfree-1]);
Buffer = obj.cur.V[] = obj->vfunc();
if (Volume>QUIET) println("Server Executive: ",ID," vfunc[0]= ",Buffer[0]);
return obj.nstruct;
}
CstrServer::CstrServer(obj) { ObjServer(obj); }
SepServer::SepServer(obj) { ObjServer(obj); }
CstrServer::Execute() {
obj->Encode(Buffer);
obj->Lagrangian(0);
return rows(Buffer = obj.cur->Vec());
}
/** Separable objective evaluations.
**/
SepServer::Execute() {
obj.Kvar.v = imod(Tag-basetag,obj.K);
obj->Encode(Buffer,TRUE);
Buffer = obj.Kvar->PDF() * obj->vfunc();
return obj.NvfuncTerms;
}

38
samples/Ox/particle.oxo Normal file
View File

@@ -0,0 +1,38 @@
nldge::ParticleLogLikeli()
{ decl it, ip,
mss, mbas, ms, my, mx, vw, vwi, dws,
mhi, mhdet, loglikeli, mData,
vxm, vxs, mxm=<>, mxsu=<>, mxsl=<>,
time, timeall, timeran=0, timelik=0, timefun=0, timeint=0, timeres=0;
mData = GetData(m_asY);
mhdet = sqrt((2*M_PI)^m_cY * determinant(m_mMSbE.^2)); // covariance determinant
mhi = invert(m_mMSbE.^2); // invert covariance of measurement shocks
ms = m_vSss + zeros(m_cPar, m_cS); // start particles
mx = m_vXss + zeros(m_cPar, m_cX); // steady state of state and policy
loglikeli = 0; // init likelihood
//timeall=timer();
for(it = 0; it < sizer(mData); it++)
{
mss = rann(m_cPar, m_cSS) * m_mSSbE; // state noise
fg(&ms, ms, mx, mss); // transition prior as proposal
mx = m_oApprox.FastInterpolate(ms); // interpolate
fy(&my, ms, mx, zeros(m_cPar, m_cMS)); // evaluate importance weights
my -= mData[it][]; // observation error
vw = exp(-0.5 * outer(my,mhi,'d')' )/mhdet; // vw = exp(-0.5 * sumr(my*mhi .*my ) )/mhdet;
vw = vw .== .NaN .? 0 .: vw; // no policy can happen for extrem particles
dws = sumc(vw);
if(dws==0) return -.Inf; // or extremely wrong parameters
loglikeli += log(dws/m_cPar) ; // loglikelihood contribution
//timelik += (timer()-time)/100;
//time=timer();
vwi = resample(vw/dws)-1; // selection step in c++
ms = ms[vwi][]; // on normalized weights
mx = mx[vwi][];
}
return loglikeli;
}

54
samples/Pan/test.pan Normal file
View File

@@ -0,0 +1,54 @@
object template pantest;
# Very simple pan test file
"/long/decimal" = 123;
"/long/octal" = 0755;
"/long/hexadecimal" = 0xFF;
"/double/simple" = 0.01;
"/double/pi" = 3.14159;
"/double/exponent" = 1e-8;
"/double/scientific" = 1.3E10;
"/string/single" = 'Faster, but escapes like \t, \n and \x3d don''t work, but '' should work.';
"/string/double" = "Slower, but escapes like \t, \n and \x3d do work";
variable TEST = 2;
"/x2" = to_string(TEST);
"/x2" ?= 'Default value';
"/x3" = 1 + 2 + value("/long/decimal");
"/x4" = undef;
"/x5" = null;
variable e ?= error("Test error message");
# include gmond config for services-monitoring
include { 'site/ganglia/gmond/services-monitoring' };
"/software/packages"=pkg_repl("httpd","2.2.3-43.sl5.3",PKG_ARCH_DEFAULT);
"/software/packages"=pkg_repl("php");
# Example function
function show_things_view_for_stuff = {
thing = ARGV[0];
foreach( i; mything; STUFF ) {
if ( thing == mything ) {
return( true );
} else {
return SELF;
};
};
false;
};
variable HERE = <<EOF;
; This example demonstrates an in-line heredoc style config file
[main]
awesome = true
EOF
variable small = false;#This should be highlighted normally again.

111
samples/Perl/PSGI.pod Normal file
View File

@@ -0,0 +1,111 @@
=pod
=head1 NAME
Catalyst::PSGI - How Catalyst and PSGI work together
=head1 SYNOPSIS
The L<PSGI> specification defines an interface between web servers and
Perl-based web applications and frameworks. It supports the writing of
portable applications that can be run using various methods (as a
standalone server, or using mod_perl, FastCGI, etc.). L<Plack> is an
implementation of the PSGI specification for running Perl applications.
Catalyst used to contain an entire set of C<< Catalyst::Engine::XXXX >>
classes to handle various web servers and environments (e.g. CGI,
FastCGI, mod_perl) etc.
This has been changed in Catalyst 5.9 so that all of that work is done
by Catalyst implementing the L<PSGI> specification, using L<Plack>'s
adaptors to implement that functionality.
This means that we can share common code, and share fixes for specific
web servers.
=head1 I already have an application
If you already have a Catalyst application, then you should be able to
upgrade to the latest release with little or no trouble (see the notes
in L<Catalyst::Upgrading> for specifics about your web server
deployment).
=head1 Writing your own PSGI file.
=head2 What is a .psgi file?
A C<< .psgi >> file lets you control how your application code reference
is built. Catalyst will automatically handle this for you, but it's
possible to do it manually by creating a C<myapp.psgi> file in the root
of your application.
=head2 Why would I want to write my own .psgi file?
Writing your own .psgi file allows you to use the alternate L<plackup> command
to start your application, and allows you to add classes and extensions
that implement L<Plack::Middleware>, such as L<Plack::Middleware::ErrorDocument>
or L<Plack::Middleware::AccessLog>.
The simplest C<.psgi> file for an application called C<TestApp> would be:
use strict;
use warnings;
use TestApp;
my $app = TestApp->psgi_app(@_);
Note that Catalyst will apply a number of middleware components for you
automatically, and these B<will not> be applied if you manually create a
psgi file yourself. Details of these components can be found below.
Additional information about psgi files can be found at:
L<http://search.cpan.org/dist/Plack/lib/Plack.pm#.psgi_files>
=head2 What is in the .psgi file Catalyst generates by default?
Catalyst generates an application which, if the C<using_frontend_proxy>
setting is on, is wrapped in L<Plack::Middleware::ReverseProxy>, and
contains some engine-specific fixes for uniform behaviour, as contained
in:
=over
=item L<Plack::Middleware::LighttpdScriptNameFix>
=item L<Plack::Middleware::IIS6ScriptNameFix>
=back
If you override the default by providing your own C<< .psgi >> file,
then none of these things will be done automatically for you by the PSGI
application returned when you call C<< MyApp->psgi_app >>. Thus, if you
need any of this functionality, you'll need to implement this in your
C<< .psgi >> file yourself.
An apply_default_middlewares method is supplied to wrap your application
in the default middlewares if you want this behaviour and you are providing
your own .psgi file.
This means that the auto-generated (no .psgi file) code looks something
like this:
use strict;
use warnings;
use TestApp;
my $app = TestApp->apply_default_middlewares(TestApp->psgi_app(@_));
=head1 SEE ALSO
L<Catalyst::Upgrading>, L<Plack>, L<PSGI::FAQ>, L<PSGI>.
=head1 AUTHORS
Catalyst Contributors, see Catalyst.pm
=head1 COPYRIGHT
This library is free software. You can redistribute it and/or modify
it under the same terms as Perl itself.
=cut

38
samples/Pike/Error.pmod Normal file
View File

@@ -0,0 +1,38 @@
#pike __REAL_VERSION__
constant Generic = __builtin.GenericError;
constant Index = __builtin.IndexError;
constant BadArgument = __builtin.BadArgumentError;
constant Math = __builtin.MathError;
constant Resource = __builtin.ResourceError;
constant Permission = __builtin.PermissionError;
constant Decode = __builtin.DecodeError;
constant Cpp = __builtin.CppError;
constant Compilation = __builtin.CompilationError;
constant MasterLoad = __builtin.MasterLoadError;
constant ModuleLoad = __builtin.ModuleLoadError;
//! Returns an Error object for any argument it receives. If the
//! argument already is an Error object or is empty, it does nothing.
object mkerror(mixed error)
{
if (error == UNDEFINED)
return error;
if (objectp(error) && error->is_generic_error)
return error;
if (arrayp(error))
return Error.Generic(@error);
if (stringp(error))
return Error.Generic(error);
return Error.Generic(sprintf("%O", error));
}

360
samples/Pike/FakeFile.pike Normal file
View File

@@ -0,0 +1,360 @@
#pike __REAL_VERSION__
//! A string wrapper that pretends to be a @[Stdio.File] object
//! in addition to some features of a @[Stdio.FILE] object.
//! This constant can be used to distinguish a FakeFile object
//! from a real @[Stdio.File] object.
constant is_fake_file = 1;
protected string data;
protected int ptr;
protected int(0..1) r;
protected int(0..1) w;
protected int mtime;
protected function read_cb;
protected function read_oob_cb;
protected function write_cb;
protected function write_oob_cb;
protected function close_cb;
//! @seealso
//! @[Stdio.File()->close()]
int close(void|string direction) {
direction = lower_case(direction||"rw");
int cr = has_value(direction, "r");
int cw = has_value(direction, "w");
if(cr) {
r = 0;
}
if(cw) {
w = 0;
}
// FIXME: Close callback
return 1;
}
//! @decl void create(string data, void|string type, void|int pointer)
//! @seealso
//! @[Stdio.File()->create()]
void create(string _data, void|string type, int|void _ptr) {
if(!_data) error("No data string given to FakeFile.\n");
data = _data;
ptr = _ptr;
mtime = time();
if(type) {
type = lower_case(type);
if(has_value(type, "r"))
r = 1;
if(has_value(type, "w"))
w = 1;
}
else
r = w = 1;
}
protected string make_type_str() {
string type = "";
if(r) type += "r";
if(w) type += "w";
return type;
}
//! @seealso
//! @[Stdio.File()->dup()]
this_program dup() {
return this_program(data, make_type_str(), ptr);
}
//! Always returns 0.
//! @seealso
//! @[Stdio.File()->errno()]
int errno() { return 0; }
//! Returns size and the creation time of the string.
Stdio.Stat stat() {
Stdio.Stat st = Stdio.Stat();
st->size = sizeof(data);
st->mtime=st->ctime=mtime;
st->atime=time();
return st;
}
//! @seealso
//! @[Stdio.File()->line_iterator()]
String.SplitIterator line_iterator(int|void trim) {
if(trim)
return String.SplitIterator( data-"\r", '\n' );
return String.SplitIterator( data, '\n' );
}
protected mixed id;
//! @seealso
//! @[Stdio.File()->query_id()]
mixed query_id() { return id; }
//! @seealso
//! @[Stdio.File()->set_id()]
void set_id(mixed _id) { id = _id; }
//! @seealso
//! @[Stdio.File()->read_function()]
function(:string) read_function(int nbytes) {
return lambda() { return read(nbytes); };
}
//! @seealso
//! @[Stdio.File()->peek()]
int(-1..1) peek(int|float|void timeout) {
if(!r) return -1;
if(ptr >= sizeof(data)) return 0;
return 1;
}
//! Always returns 0.
//! @seealso
//! @[Stdio.File()->query_address()]
string query_address(void|int(0..1) is_local) { return 0; }
//! @seealso
//! @[Stdio.File()->read()]
string read(void|int(0..) len, void|int(0..1) not_all) {
if(!r) return 0;
if (len < 0) error("Cannot read negative number of characters.\n");
int start=ptr;
ptr += len;
if(zero_type(len) || ptr>sizeof(data))
ptr = sizeof(data);
// FIXME: read callback
return data[start..ptr-1];
}
//! @seealso
//! @[Stdio.FILE()->gets()]
string gets() {
if(!r) return 0;
string ret;
sscanf(data,"%*"+(string)ptr+"s%[^\n]",ret);
if(ret)
{
ptr+=sizeof(ret)+1;
if(ptr>sizeof(data))
{
ptr=sizeof(data);
if(!sizeof(ret))
ret = 0;
}
}
// FIXME: read callback
return ret;
}
//! @seealso
//! @[Stdio.FILE()->getchar()]
int getchar() {
if(!r) return 0;
int c;
if(catch(c=data[ptr]))
c=-1;
else
ptr++;
// FIXME: read callback
return c;
}
//! @seealso
//! @[Stdio.FILE()->unread()]
void unread(string s) {
if(!r) return;
if(data[ptr-sizeof(s)..ptr-1]==s)
ptr-=sizeof(s);
else
{
data=s+data[ptr..];
ptr=0;
}
}
//! @seealso
//! @[Stdio.File()->seek()]
int seek(int pos, void|int mult, void|int add) {
if(mult)
pos = pos*mult+add;
if(pos<0)
{
pos = sizeof(data)+pos;
if( pos < 0 )
pos = 0;
}
ptr = pos;
if( ptr > strlen( data ) )
ptr = strlen(data);
return ptr;
}
//! Always returns 1.
//! @seealso
//! @[Stdio.File()->sync()]
int(1..1) sync() { return 1; }
//! @seealso
//! @[Stdio.File()->tell()]
int tell() { return ptr; }
//! @seealso
//! @[Stdio.File()->truncate()]
int(0..1) truncate(int length) {
data = data[..length-1];
return sizeof(data)==length;
}
//! @seealso
//! @[Stdio.File()->write()]
int(-1..) write(string|array(string) str, mixed ... extra) {
if(!w) return -1;
if(arrayp(str)) str=str*"";
if(sizeof(extra)) str=sprintf(str, @extra);
if(ptr==sizeof(data)) {
data += str;
ptr = sizeof(data);
}
else if(sizeof(str)==1)
data[ptr++] = str[0];
else {
data = data[..ptr-1] + str + data[ptr+sizeof(str)..];
ptr += sizeof(str);
}
// FIXME: write callback
return sizeof(str);
}
//! @seealso
//! @[Stdio.File()->set_blocking]
void set_blocking() {
close_cb = 0;
read_cb = 0;
read_oob_cb = 0;
write_cb = 0;
write_oob_cb = 0;
}
//! @seealso
//! @[Stdio.File()->set_blocking_keep_callbacks]
void set_blocking_keep_callbacks() { }
//! @seealso
//! @[Stdio.File()->set_blocking]
void set_nonblocking(function rcb, function wcb, function ccb,
function rocb, function wocb) {
read_cb = rcb;
write_cb = wcb;
close_cb = ccb;
read_oob_cb = rocb;
write_oob_cb = wocb;
}
//! @seealso
//! @[Stdio.File()->set_blocking_keep_callbacks]
void set_nonblocking_keep_callbacks() { }
//! @seealso
//! @[Stdio.File()->set_close_callback]
void set_close_callback(function cb) { close_cb = cb; }
//! @seealso
//! @[Stdio.File()->set_read_callback]
void set_read_callback(function cb) { read_cb = cb; }
//! @seealso
//! @[Stdio.File()->set_read_oob_callback]
void set_read_oob_callback(function cb) { read_oob_cb = cb; }
//! @seealso
//! @[Stdio.File()->set_write_callback]
void set_write_callback(function cb) { write_cb = cb; }
//! @seealso
//! @[Stdio.File()->set_write_oob_callback]
void set_write_oob_callback(function cb) { write_oob_cb = cb; }
//! @seealso
//! @[Stdio.File()->query_close_callback]
function query_close_callback() { return close_cb; }
//! @seealso
//! @[Stdio.File()->query_read_callback]
function query_read_callback() { return read_cb; }
//! @seealso
//! @[Stdio.File()->query_read_oob_callback]
function query_read_oob_callback() { return read_oob_cb; }
//! @seealso
//! @[Stdio.File()->query_write_callback]
function query_write_callback() { return write_cb; }
//! @seealso
//! @[Stdio.File()->query_write_oob_callback]
function query_write_oob_callback() { return write_oob_cb; }
string _sprintf(int t) {
return t=='O' && sprintf("%O(%d,%O)", this_program, sizeof(data),
make_type_str());
}
// FakeFile specials.
//! A FakeFile can be casted to a string.
mixed cast(string to) {
switch(to) {
case "string": return data;
case "object": return this;
}
error("Can not cast object to %O.\n", to);
}
//! Sizeof on a FakeFile returns the size of its contents.
int(0..) _sizeof() {
return sizeof(data);
}
//! @ignore
#define NOPE(X) mixed X (mixed ... args) { error("This is a FakeFile. %s is not available.\n", #X); }
NOPE(assign);
NOPE(async_connect);
NOPE(connect);
NOPE(connect_unix);
NOPE(open);
NOPE(open_socket);
NOPE(pipe);
NOPE(tcgetattr);
NOPE(tcsetattr);
// Stdio.Fd
NOPE(dup2);
NOPE(lock); // We could implement this
NOPE(mode); // We could implement this
NOPE(proxy); // We could implement this
NOPE(query_fd);
NOPE(read_oob);
NOPE(set_close_on_exec);
NOPE(set_keepalive);
NOPE(trylock); // We could implement this
NOPE(write_oob);
//! @endignore

View File

@@ -0,0 +1,260 @@
:- module(format_spec, [ format_error/2
, format_spec/2
, format_spec//1
, spec_arity/2
, spec_types/2
]).
:- use_module(library(dcg/basics), [eos//0, integer//1, string_without//2]).
:- use_module(library(error)).
:- use_module(library(when), [when/2]).
% TODO loading this module is optional
% TODO it's for my own convenience during development
%:- use_module(library(mavis)).
%% format_error(+Goal, -Error:string) is nondet.
%
% True if Goal exhibits an Error in its format string. The
% Error string describes what is wrong with Goal. Iterates each
% error on backtracking.
%
% Goal may be one of the following predicates:
%
% * format/2
% * format/3
% * debug/3
format_error(format(Format,Args), Error) :-
format_error_(Format, Args,Error).
format_error(format(_,Format,Args), Error) :-
format_error_(Format,Args,Error).
format_error(debug(_,Format,Args), Error) :-
format_error_(Format,Args,Error).
format_error_(Format,Args,Error) :-
format_spec(Format, Spec),
!,
is_list(Args),
spec_types(Spec, Types),
types_error(Args, Types, Error).
format_error_(Format,_,Error) :-
% \+ format_spec(Format, _),
format(string(Error), "Invalid format string: ~q", [Format]).
types_error(Args, Types, Error) :-
length(Types, TypesLen),
length(Args, ArgsLen),
TypesLen =\= ArgsLen,
!,
format( string(Error)
, "Wrong argument count. Expected ~d, got ~d"
, [TypesLen, ArgsLen]
).
types_error(Args, Types, Error) :-
types_error_(Args, Types, Error).
types_error_([Arg|_],[Type|_],Error) :-
ground(Arg),
\+ is_of_type(Type,Arg),
message_to_string(error(type_error(Type,Arg),_Location),Error).
types_error_([_|Args],[_|Types],Error) :-
types_error_(Args, Types, Error).
% check/0 augmentation
:- multifile check:checker/2.
:- dynamic check:checker/2.
check:checker(format_spec:checker, "format/2 strings and arguments").
:- dynamic format_fail/3.
checker :-
prolog_walk_code([ module_class([user])
, infer_meta_predicates(false)
, autoload(false) % format/{2,3} are always loaded
, undefined(ignore)
, trace_reference(_)
, on_trace(check_format)
]),
retract(format_fail(Goal,Location,Error)),
print_message(warning, format_error(Goal,Location,Error)),
fail. % iterate all errors
checker. % succeed even if no errors are found
check_format(Module:Goal, _Caller, Location) :-
predicate_property(Module:Goal, imported_from(Source)),
memberchk(Source, [system,prolog_debug]),
can_check(Goal),
format_error(Goal, Error),
assert(format_fail(Goal, Location, Error)),
fail.
check_format(_,_,_). % succeed to avoid printing goals
% true if format_error/2 can check this goal
can_check(Goal) :-
once(clause(format_error(Goal,_),_)).
prolog:message(format_error(Goal,Location,Error)) -->
prolog:message_location(Location),
['~n In goal: ~q~n ~s'-[Goal,Error]].
%% format_spec(-Spec)//
%
% DCG for parsing format strings. It doesn't yet generate format
% strings from a spec. See format_spec/2 for details.
format_spec([]) -->
eos.
format_spec([escape(Numeric,Modifier,Action)|Rest]) -->
"~",
numeric_argument(Numeric),
modifier_argument(Modifier),
action(Action),
format_spec(Rest).
format_spec([text(String)|Rest]) -->
{ when((ground(String);ground(Codes)),string_codes(String, Codes)) },
string_without("~", Codes),
{ Codes \= [] },
format_spec(Rest).
%% format_spec(+Format, -Spec:list) is semidet.
%
% Parse a format string. Each element of Spec is one of the following:
%
% * `text(Text)` - text sent to the output as is
% * `escape(Num,Colon,Action)` - a format escape
%
% `Num` represents the optional numeric portion of an esape. `Colon`
% represents the optional colon in an escape. `Action` is an atom
% representing the action to be take by this escape.
format_spec(Format, Spec) :-
when((ground(Format);ground(Codes)),text_codes(Format, Codes)),
once(phrase(format_spec(Spec), Codes, [])).
%% spec_arity(+FormatSpec, -Arity:positive_integer) is det.
%
% True if FormatSpec requires format/2 to have Arity arguments.
spec_arity(Spec, Arity) :-
spec_types(Spec, Types),
length(Types, Arity).
%% spec_types(+FormatSpec, -Types:list(type)) is det.
%
% True if FormatSpec requires format/2 to have arguments of Types. Each
% value of Types is a type as described by error:has_type/2. This
% notion of types is compatible with library(mavis).
spec_types(Spec, Types) :-
phrase(spec_types(Spec), Types).
spec_types([]) -->
[].
spec_types([Item|Items]) -->
item_types(Item),
spec_types(Items).
item_types(text(_)) -->
[].
item_types(escape(Numeric,_,Action)) -->
numeric_types(Numeric),
action_types(Action).
numeric_types(number(_)) -->
[].
numeric_types(character(_)) -->
[].
numeric_types(star) -->
[number].
numeric_types(nothing) -->
[].
action_types(Action) -->
{ atom_codes(Action, [Code]) },
{ action_types(Code, Types) },
phrase(Types).
%% text_codes(Text:text, Codes:codes).
text_codes(Var, Codes) :-
var(Var),
!,
string_codes(Var, Codes).
text_codes(Atom, Codes) :-
atom(Atom),
!,
atom_codes(Atom, Codes).
text_codes(String, Codes) :-
string(String),
!,
string_codes(String, Codes).
text_codes(Codes, Codes) :-
is_of_type(codes, Codes).
numeric_argument(number(N)) -->
integer(N).
numeric_argument(character(C)) -->
"`",
[C].
numeric_argument(star) -->
"*".
numeric_argument(nothing) -->
"".
modifier_argument(colon) -->
":".
modifier_argument(no_colon) -->
\+ ":".
action(Action) -->
[C],
{ is_action(C) },
{ atom_codes(Action, [C]) }.
%% is_action(+Action:integer) is semidet.
%% is_action(-Action:integer) is multi.
%
% True if Action is a valid format/2 action character. Iterates all
% acceptable action characters, if Action is unbound.
is_action(Action) :-
action_types(Action, _).
%% action_types(?Action:integer, ?Types:list(type))
%
% True if Action consumes arguments matching Types. An action (like
% `~`), which consumes no arguments, has `Types=[]`. For example,
%
% ?- action_types(0'~, Types).
% Types = [].
% ?- action_types(0'a, Types).
% Types = [atom].
action_types(0'~, []).
action_types(0'a, [atom]).
action_types(0'c, [integer]). % specifically, a code
action_types(0'd, [integer]).
action_types(0'D, [integer]).
action_types(0'e, [float]).
action_types(0'E, [float]).
action_types(0'f, [float]).
action_types(0'g, [float]).
action_types(0'G, [float]).
action_types(0'i, [any]).
action_types(0'I, [integer]).
action_types(0'k, [any]).
action_types(0'n, []).
action_types(0'N, []).
action_types(0'p, [any]).
action_types(0'q, [any]).
action_types(0'r, [integer]).
action_types(0'R, [integer]).
action_types(0's, [text]).
action_types(0'@, [callable]).
action_types(0't, []).
action_types(0'|, []).
action_types(0'+, []).
action_types(0'w, [any]).
action_types(0'W, [any, list]).

194
samples/Prolog/func.pl Normal file
View File

@@ -0,0 +1,194 @@
:- module(func, [ op(675, xfy, ($))
, op(650, xfy, (of))
, ($)/2
, (of)/2
]).
:- use_module(library(list_util), [xfy_list/3]).
:- use_module(library(function_expansion)).
:- use_module(library(arithmetic)).
:- use_module(library(error)).
% true if the module whose terms are being read has specifically
% imported library(func).
wants_func :-
prolog_load_context(module, Module),
Module \== func, % we don't want func sugar ourselves
predicate_property(Module:of(_,_),imported_from(func)).
%% compile_function(+Term, -In, -Out, -Goal) is semidet.
%
% True if Term represents a function from In to Out
% implemented by calling Goal. This multifile hook is
% called by $/2 and of/2 to convert a term into a goal.
% It's used at compile time for macro expansion.
% It's used at run time to handle functions which aren't
% known at compile time.
% When called as a hook, Term is guaranteed to be =nonvar=.
%
% For example, to treat library(assoc) terms as functions which
% map a key to a value, one might define:
%
% :- multifile compile_function/4.
% compile_function(Assoc, Key, Value, Goal) :-
% is_assoc(Assoc),
% Goal = get_assoc(Key, Assoc, Value).
%
% Then one could write:
%
% list_to_assoc([a-1, b-2, c-3], Assoc),
% Two = Assoc $ b,
:- multifile compile_function/4.
compile_function(Var, _, _, _) :-
% variables storing functions must be evaluated at run time
% and can't be compiled, a priori, into a goal
var(Var),
!,
fail.
compile_function(Expr, In, Out, Out is Expr) :-
% arithmetic expression of one variable are simply evaluated
\+ string(Expr), % evaluable/1 throws exception with strings
arithmetic:evaluable(Expr),
term_variables(Expr, [In]).
compile_function(F, In, Out, func:Goal) :-
% composed functions
function_composition_term(F),
user:function_expansion(F, func:Functor, true),
Goal =.. [Functor,In,Out].
compile_function(F, In, Out, Goal) :-
% string interpolation via format templates
format_template(F),
( atom(F) ->
Goal = format(atom(Out), F, In)
; string(F) ->
Goal = format(string(Out), F, In)
; error:has_type(codes, F) ->
Goal = format(codes(Out), F, In)
; fail % to be explicit
).
compile_function(Dict, In, Out, Goal) :-
is_dict(Dict),
Goal = get_dict(In, Dict, Out).
%% $(+Function, +Argument) is det.
%
% Apply Function to an Argument. A Function is any predicate
% whose final argument generates output and whose penultimate argument
% accepts input.
%
% This is realized by expanding function application to chained
% predicate calls at compile time. Function application itself can
% be chained.
%
% ==
% Reversed = reverse $ sort $ [c,d,b].
% ==
:- meta_predicate $(2,+).
$(_,_) :-
throw(error(permission_error(call, predicate, ($)/2),
context(_, '$/2 must be subject to goal expansion'))).
user:function_expansion($(F,X), Y, Goal) :-
wants_func,
( func:compile_function(F, X, Y, Goal) ->
true
; var(F) -> Goal = % defer until run time
( func:compile_function(F, X, Y, P) ->
call(P)
; call(F, X, Y)
)
; Goal = call(F, X, Y)
).
%% of(+F, +G) is det.
%
% Creates a new function by composing F and G. The functions are
% composed at compile time to create a new, compiled predicate which
% behaves like a function. Function composition can be chained.
% Composed functions can also be applied with $/2.
%
% ==
% Reversed = reverse of sort $ [c,d,b].
% ==
:- meta_predicate of(2,2).
of(_,_).
%% format_template(Format) is semidet.
%
% True if Format is a template string suitable for format/3.
% The current check is very naive and should be improved.
format_template(Format) :-
atom(Format), !,
atom_codes(Format, Codes),
format_template(Codes).
format_template(Format) :-
string(Format),
!,
string_codes(Format, Codes),
format_template(Codes).
format_template(Format) :-
error:has_type(codes, Format),
memberchk(0'~, Format). % ' fix syntax highlighting
% True if the argument is a function composition term
function_composition_term(of(_,_)).
% Converts a function composition term into a list of functions to compose
functions_to_compose(Term, Funcs) :-
functor(Term, Op, 2),
Op = (of),
xfy_list(Op, Term, Funcs).
% Thread a state variable through a list of functions. This is similar
% to a DCG expansion, but much simpler.
thread_state([], [], Out, Out).
thread_state([F|Funcs], [Goal|Goals], In, Out) :-
( compile_function(F, In, Tmp, Goal) ->
true
; var(F) ->
instantiation_error(F)
; F =.. [Functor|Args],
append(Args, [In, Tmp], NewArgs),
Goal =.. [Functor|NewArgs]
),
thread_state(Funcs, Goals, Tmp, Out).
user:function_expansion(Term, func:Functor, true) :-
wants_func,
functions_to_compose(Term, Funcs),
debug(func, 'building composed function for: ~w', [Term]),
variant_sha1(Funcs, Sha),
format(atom(Functor), 'composed_function_~w', [Sha]),
debug(func, ' name: ~s', [Functor]),
( func:current_predicate(Functor/2) ->
debug(func, ' composed predicate already exists', [])
; true ->
reverse(Funcs, RevFuncs),
thread_state(RevFuncs, Threaded, In, Out),
xfy_list(',', Body, Threaded),
Head =.. [Functor, In, Out],
func:assert(Head :- Body),
func:compile_predicates([Functor/2])
).
% support foo(x,~,y) evaluation
user:function_expansion(Term, Output, Goal) :-
wants_func,
compound(Term),
% has a single ~ argument
setof( X
, ( arg(X,Term,Arg), Arg == '~' )
, [N]
),
% replace ~ with a variable
Term =.. [Name|Args0],
nth1(N, Args0, ~, Rest),
nth1(N, Args, Output, Rest),
Goal =.. [Name|Args].

View File

@@ -0,0 +1,97 @@
{{
*****************************************
* 4x4 Keypad Reader v1.0 *
* Author: Beau Schwabe *
* Copyright (c) 2007 Parallax *
* See end of file for terms of use. *
*****************************************
}}
{
Operation:
This object uses a capacitive PIN approach to reading the keypad.
To do so, ALL pins are made LOW and an OUTPUT to "discharge" the
I/O pins. Then, ALL pins are set to an INPUT state. At this point,
only one pin is made HIGH and an OUTPUT at a time. If the "switch"
is closed, then a HIGH will be read on the input, otherwise a LOW
will be returned.
The keypad decoding routine only requires two subroutines and returns
the entire 4x4 keypad matrix into a single WORD variable indicating
which buttons are pressed. Multiple button presses are allowed with
the understanding that“BOX entries can be confused. An example of a
BOX entry... 1,2,4,5 or 1,4,3,6 or 4,6,*,# etc. where any 3 of the 4
buttons pressed will evaluate the non pressed button as being pressed,
even when they are not. There is no danger of any physical or
electrical damage, that s just the way this sensing method happens to
work.
Schematic:
No resistors, No capacitors. The connections are directly from the
keypad to the I/O's. I literally plugged mine right into the demo
board RevC.
Looking at the Back of the 4x4 keypad...
P7 P0
││││││││
┌─────── ││││││││ ───────┐
│ oo ││││││││ o │
│ │
│ O O O O O │
│ │
│ O O O O O │
│ {LABEL} │
│ O O O O O │
│ │
│ O O O O O │
│ │
│ O O O O O │
│ o o │
└────────────────────────┘
}
VAR
word keypad
PUB ReadKeyPad
keypad := 0 'Clear 4x4 'keypad' value
ReadRow(3) 'Call routine to read entire ROW 0
keypad <<= 4 'Shift 'keypad' value left by 4
ReadRow(2) 'Call routine to read entire ROW 1
keypad <<= 4 'Shift 'keypad' value left by 4
ReadRow(1) 'Call routine to read entire ROW 2
keypad <<= 4 'Shift 'keypad' value left by 4
ReadRow(0) 'Call routine to read entire ROW 3
Result := keypad
PRI ReadRow(n)
outa[0..7]~ 'preset P0 to P7 as LOWs
dira[0..7]~~ 'make P0 to P7 OUTPUTs ... discharge pins or "capacitors" to VSS
dira[0..7]~ 'make P0 to P7 INPUTSs ... now the pins act like tiny capacitors
outa[n]~~ 'preset Pin 'n' HIGH
dira[n]~~ 'make Pin 'n' an OUTPUT... Make only one pin HIGH ; will charge
' "capacitor" if switch is closed.
'
keypad += ina[4..7] 'read ROW value ... If a switch is open, the pin or "capacitor"
dira[n]~ 'make Pn an INPUT will remain discharged
DAT
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ TERMS OF USE: MIT License │
├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │
│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │
│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│
│is furnished to do so, subject to the following conditions: │
│ │
│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│
│ │
│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │
│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │
│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │
│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

View File

@@ -0,0 +1,181 @@
''****************************************
''* Debug_Lcd v1.2 *
''* Authors: Jon Williams, Jeff Martin *
''* Copyright (c) 2006 Parallax, Inc. *
''* See end of file for terms of use. *
''****************************************
''
'' Debugging wrapper for Serial_Lcd object
''
'' v1.2 - March 26, 2008 - Updated by Jeff Martin to conform to Propeller object initialization standards.
'' v1.1 - April 29, 2006 - Updated by Jon Williams for consistency.
''
OBJ
lcd : "serial_lcd" ' driver for Parallax Serial LCD
num : "simple_numbers" ' number to string conversion
PUB init(pin, baud, lines) : okay
'' Initializes serial LCD object
'' -- returns true if all parameters okay
okay := lcd.init(pin, baud, lines)
PUB finalize
'' Finalizes lcd object -- frees the pin (floats)
lcd.finalize
PUB putc(txbyte)
'' Send a byte to the terminal
lcd.putc(txbyte)
PUB str(strAddr)
'' Print a zero-terminated string
lcd.str(strAddr)
PUB dec(value)
'' Print a signed decimal number
lcd.str(num.dec(value))
PUB decf(value, width)
'' Prints signed decimal value in space-padded, fixed-width field
lcd.str(num.decf(value, width))
PUB decx(value, digits)
'' Prints zero-padded, signed-decimal string
'' -- if value is negative, field width is digits+1
lcd.str(num.decx(value, digits))
PUB hex(value, digits)
'' Print a hexadecimal number
lcd.str(num.hex(value, digits))
PUB ihex(value, digits)
'' Print an indicated hexadecimal number
lcd.str(num.ihex(value, digits))
PUB bin(value, digits)
'' Print a binary number
lcd.str(num.bin(value, digits))
PUB ibin(value, digits)
'' Print an indicated (%) binary number
lcd.str(num.ibin(value, digits))
PUB cls
'' Clears LCD and moves cursor to home (0, 0) position
lcd.cls
PUB home
'' Moves cursor to 0, 0
lcd.home
PUB gotoxy(col, line)
'' Moves cursor to col/line
lcd.gotoxy(col, line)
PUB clrln(line)
'' Clears line
lcd.clrln(line)
PUB cursor(type)
'' Selects cursor type
'' 0 : cursor off, blink off
'' 1 : cursor off, blink on
'' 2 : cursor on, blink off
'' 3 : cursor on, blink on
lcd.cursor(type)
PUB display(status)
'' Controls display visibility; use display(false) to hide contents without clearing
if status
lcd.displayOn
else
lcd.displayOff
PUB custom(char, chrDataAddr)
'' Installs custom character map
'' -- chrDataAddr is address of 8-byte character definition array
lcd.custom(char, chrDataAddr)
PUB backLight(status)
'' Enable (true) or disable (false) LCD backlight
'' -- affects only backlit models
lcd.backLight(status)
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ TERMS OF USE: MIT License │
├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │
│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │
│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│
│is furnished to do so, subject to the following conditions: │
│ │
│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│
│ │
│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │
│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │
│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │
│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,221 @@
{{
*****************************************
* Inductive Sensor Demo v1.0 *
* Author: Beau Schwabe *
* Copyright (c) 2007 Parallax *
* See end of file for terms of use. *
*****************************************
Test Circuit:
10pF 100K 1M
FPin ───┳──┳── SDF(sigma-delta feedback)
│ ┣──── SDI(sigma-delta input)
L  100K
 
GND GND
Test Coils:
Wire used was the "Radio Shack Special" GREEN (about 27 gauge)
25T (Coke Can form) = 2.1MHz
15T (Coke Can form) = 3.9MHz
5T (Coke Can form) = 5.3MHz
50T (BIC pen form) = 3.2MHz
How does it work?
Note: The reported resonate frequency is NOT the actual resonate LC frequency. Instead it is where the voltage produced from
the LC circuit was clipped.
In the example circuit below:
C L
A ────┳──── GND
B
When you apply a small voltage at a specific frequency to an LC circuit (at point "A") that is at or near the resonate
frequency of LC, it is not uncommon to measure 10's or 100's of times the amount of voltage (at point "B") that you are
applying to the LC circuit. (at point "A")
In the "Test Circuit" above, point "B" passes through a diode which then basically feeds a divide by 2 voltage divider:
100K 100K
B ───┳── GND
C
...So in order see the sigma-delta ADC "clip" the frequency sweep result, the output from the LC circuit only needs
to generate about 6.6 Volts above ground. (0.6V drop across the diode, and since the ADC is only sensitive to about
3V, it works out to be about 6.6V after the voltage divider.)
A typical magnitude plot of a frequency sweep applied to an LC circuit might look something like this:
*
*
*
*
* *
* *
* *
* *
* *
***** *****
...With 'clipping' the pattern looks more like this:
X****
* *
* *
* *
***** *****
...The 'X' denotes the location of the reported resonate frequency. The reason this is slightly off is for
two reasons really. 1) lazy - I didn't want to fiddle with the voltage divider combo... adjusting so that the
"peak" was also where the ADC happened to "clip". 2) some benefit - When you apply a frequency to a tuned LC
circuit that's resonate frequency is the same as the applied frequency, the LC acts like a dead short. A
situation not exactly great for Propeller I/O's
Now that we have that out of the way, what happens next? How can we use this so called "coil" as a sensor?
If a frequency sweep is initially preformed to determine the resonate frequency clip point, then it just so
happens that adding additional "metal" (<- Does not need to be ferrous) causes the resonate frequency to shift
to a HIGHER frequency.
Once you determine the "clip" frequency and you use one of the available counters to constantly feed that
particular frequency back to the LC circuit, the resulting ADC output is proportional and somewhat linear when
metal objects are introduced to the coil.
Assume frequency increases from Left to Right. With a slight resonate shift to the right, the ADC reports a
lower "de-tuned" value because the voltage magnitude no longer "clips" at the reported resonate frequency.
Typical ranges are full scale between 65535 (no metal) and 0 (metal saturation)
X *****
* *
ADC reports value here --> * *
* *
***** *****
Slight shift to the right
I also made mention that the response is somewhat linear. As the LC resonance shifts and the ADC value begins
to lower, the slope is steepest near the "clip" point. Therefore, the slightest shift results in larger value
changes. Since the coil is actually the least sensitive to metal the further away it is (Law of squares) and
most sensitive to metal the closer it is, the resulting combination acts to linearize the output. I need to
point out that some LC combinations will exhibit plateaus and other anomalies caused by varying parasitic circuit
conditions that will affect the overall output, so a little bit of trial and error is necessary to get things
the way you want them.
}}
OBJ
Freq : "Synth"
ADC : "ADC"
gr : "graphics"
Num : "Numbers"
CON
FPin = 0
UpperFrequency = 6_000_000
LowerFrequency = 2_000_000
bitmap_base = $2000
display_base = $5000
VAR
long FMax, FTemp, FValue, Frequency
PUB demo
'start and setup graphics
gr.start
gr.setup(16, 12, 128, 96, bitmap_base)
FindResonateFrequency
DisplayInductorValue
PUB DisplayInductorValue | X
Freq.Synth("A", FPin, FValue)
repeat
ADC.SigmaDelta(@FTemp)
'**************************************** Graphics Option Start *********************************************
'clear bitmap
gr.clear
'draw text
gr.textmode(1,1,7,5)
gr.colorwidth(1,0)
gr.text(0,90,string("Inductive Propeller Sensor"))
gr.colorwidth(1,5)
X := (65535 - FTemp )*200/65535
gr.plot(-100+X,15)
gr.textmode(1,1,7,%0000)
gr.colorwidth(1,0)
gr.text(-100,-20,string("Resonate Frequency ="))
gr.text(35,-20,Num.ToStr(FValue,10))
gr.text(-100,-36,string("ADC Frequency Response ="))
gr.text(65,-36,Num.ToStr(FTemp,10))
'copy bitmap to display
gr.copy(display_base)
'**************************************** Graphics Option Finish *********************************************
PUB FindResonateFrequency | P
dira[FPin] := 1
FMax := 0
repeat Frequency from LowerFrequency to UpperFrequency step 1000
Freq.Synth("A", FPin, Frequency)
ADC.SigmaDelta(@FTemp)
if FTemp > FMax
FMax := FTemp
FValue := Frequency
'**************************************** Graphics Option Start *********************************************
P := (Frequency - LowerFrequency)*100/(UpperFrequency - LowerFrequency)
gr.colorwidth(1,5)
gr.plot(0,0)
gr.line(P,0)
gr.colorwidth(3,5)
gr.line(100,0)
gr.colorwidth(2,0)
gr.plot(P,(FTemp/1024)+10)
gr.colorwidth(0,1)
gr.plot(P+1,5)
gr.line(P+1,50)
gr.copy(display_base)
'**************************************** Graphics Option Finish *********************************************
DAT
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ TERMS OF USE: MIT License │
├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │
│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │
│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│
│is furnished to do so, subject to the following conditions: │
│ │
│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│
│ │
│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │
│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │
│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │
│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

View File

@@ -0,0 +1,736 @@
''***************************************
''* PS/2 Keyboard Driver v1.0.1 *
''* Author: Chip Gracey *
''* Copyright (c) 2004 Parallax, Inc. *
''* See end of file for terms of use. *
''***************************************
{-----------------REVISION HISTORY-----------------
v1.0.1 - Updated 6/15/2006 to work with Propeller Tool 0.96}
VAR
long cog
long par_tail 'key buffer tail read/write (19 contiguous longs)
long par_head 'key buffer head read-only
long par_present 'keyboard present read-only
long par_states[8] 'key states (256 bits) read-only
long par_keys[8] 'key buffer (16 words) read-only (also used to pass initial parameters)
PUB start(dpin, cpin) : okay
'' Start keyboard driver - starts a cog
'' returns false if no cog available
''
'' dpin = data signal on PS/2 jack
'' cpin = clock signal on PS/2 jack
''
'' use 100-ohm resistors between pins and jack
'' use 10K-ohm resistors to pull jack-side signals to VDD
'' connect jack-power to 5V, jack-gnd to VSS
''
'' all lock-keys will be enabled, NumLock will be initially 'on',
'' and auto-repeat will be set to 15cps with a delay of .5s
okay := startx(dpin, cpin, %0_000_100, %01_01000)
PUB startx(dpin, cpin, locks, auto) : okay
'' Like start, but allows you to specify lock settings and auto-repeat
''
'' locks = lock setup
'' bit 6 disallows shift-alphas (case set soley by CapsLock)
'' bits 5..3 disallow toggle of NumLock/CapsLock/ScrollLock state
'' bits 2..0 specify initial state of NumLock/CapsLock/ScrollLock
'' (eg. %0_001_100 = disallow ScrollLock, NumLock initially 'on')
''
'' auto = auto-repeat setup
'' bits 6..5 specify delay (0=.25s, 1=.5s, 2=.75s, 3=1s)
'' bits 4..0 specify repeat rate (0=30cps..31=2cps)
'' (eg %01_00000 = .5s delay, 30cps repeat)
stop
longmove(@par_keys, @dpin, 4)
okay := cog := cognew(@entry, @par_tail) + 1
PUB stop
'' Stop keyboard driver - frees a cog
if cog
cogstop(cog~ - 1)
longfill(@par_tail, 0, 19)
PUB present : truefalse
'' Check if keyboard present - valid ~2s after start
'' returns t|f
truefalse := -par_present
PUB key : keycode
'' Get key (never waits)
'' returns key (0 if buffer empty)
if par_tail <> par_head
keycode := par_keys.word[par_tail]
par_tail := ++par_tail & $F
PUB getkey : keycode
'' Get next key (may wait for keypress)
'' returns key
repeat until (keycode := key)
PUB newkey : keycode
'' Clear buffer and get new key (always waits for keypress)
'' returns key
par_tail := par_head
keycode := getkey
PUB gotkey : truefalse
'' Check if any key in buffer
'' returns t|f
truefalse := par_tail <> par_head
PUB clearkeys
'' Clear key buffer
par_tail := par_head
PUB keystate(k) : state
'' Get the state of a particular key
'' returns t|f
state := -(par_states[k >> 5] >> k & 1)
DAT
'******************************************
'* Assembly language PS/2 keyboard driver *
'******************************************
org
'
'
' Entry
'
entry movd :par,#_dpin 'load input parameters _dpin/_cpin/_locks/_auto
mov x,par
add x,#11*4
mov y,#4
:par rdlong 0,x
add :par,dlsb
add x,#4
djnz y,#:par
mov dmask,#1 'set pin masks
shl dmask,_dpin
mov cmask,#1
shl cmask,_cpin
test _dpin,#$20 wc 'modify port registers within code
muxc _d1,dlsb
muxc _d2,dlsb
muxc _d3,#1
muxc _d4,#1
test _cpin,#$20 wc
muxc _c1,dlsb
muxc _c2,dlsb
muxc _c3,#1
mov _head,#0 'reset output parameter _head
'
'
' Reset keyboard
'
reset mov dira,#0 'reset directions
mov dirb,#0
movd :par,#_present 'reset output parameters _present/_states[8]
mov x,#1+8
:par mov 0,#0
add :par,dlsb
djnz x,#:par
mov stat,#8 'set reset flag
'
'
' Update parameters
'
update movd :par,#_head 'update output parameters _head/_present/_states[8]
mov x,par
add x,#1*4
mov y,#1+1+8
:par wrlong 0,x
add :par,dlsb
add x,#4
djnz y,#:par
test stat,#8 wc 'if reset flag, transmit reset command
if_c mov data,#$FF
if_c call #transmit
'
'
' Get scancode
'
newcode mov stat,#0 'reset state
:same call #receive 'receive byte from keyboard
cmp data,#$83+1 wc 'scancode?
if_nc cmp data,#$AA wz 'powerup/reset?
if_nc_and_z jmp #configure
if_nc cmp data,#$E0 wz 'extended?
if_nc_and_z or stat,#1
if_nc_and_z jmp #:same
if_nc cmp data,#$F0 wz 'released?
if_nc_and_z or stat,#2
if_nc_and_z jmp #:same
if_nc jmp #newcode 'unknown, ignore
'
'
' Translate scancode and enter into buffer
'
test stat,#1 wc 'lookup code with extended flag
rcl data,#1
call #look
cmp data,#0 wz 'if unknown, ignore
if_z jmp #newcode
mov t,_states+6 'remember lock keys in _states
mov x,data 'set/clear key bit in _states
shr x,#5
add x,#_states
movd :reg,x
mov y,#1
shl y,data
test stat,#2 wc
:reg muxnc 0,y
if_nc cmpsub data,#$F0 wc 'if released or shift/ctrl/alt/win, done
if_c jmp #update
mov y,_states+7 'get shift/ctrl/alt/win bit pairs
shr y,#16
cmpsub data,#$E0 wc 'translate keypad, considering numlock
if_c test _locks,#%100 wz
if_c_and_z add data,#@keypad1-@table
if_c_and_nz add data,#@keypad2-@table
if_c call #look
if_c jmp #:flags
cmpsub data,#$DD wc 'handle scrlock/capslock/numlock
if_c mov x,#%001_000
if_c shl x,data
if_c andn x,_locks
if_c shr x,#3
if_c shr t,#29 'ignore auto-repeat
if_c andn x,t wz
if_c xor _locks,x
if_c add data,#$DD
if_c_and_nz or stat,#4 'if change, set configure flag to update leds
test y,#%11 wz 'get shift into nz
if_nz cmp data,#$60+1 wc 'check shift1
if_nz_and_c cmpsub data,#$5B wc
if_nz_and_c add data,#@shift1-@table
if_nz_and_c call #look
if_nz_and_c andn y,#%11
if_nz cmp data,#$3D+1 wc 'check shift2
if_nz_and_c cmpsub data,#$27 wc
if_nz_and_c add data,#@shift2-@table
if_nz_and_c call #look
if_nz_and_c andn y,#%11
test _locks,#%010 wc 'check shift-alpha, considering capslock
muxnc :shift,#$20
test _locks,#$40 wc
if_nz_and_nc xor :shift,#$20
cmp data,#"z"+1 wc
if_c cmpsub data,#"a" wc
:shift if_c add data,#"A"
if_c andn y,#%11
:flags ror data,#8 'add shift/ctrl/alt/win flags
mov x,#4 '+$100 if shift
:loop test y,#%11 wz '+$200 if ctrl
shr y,#2 '+$400 if alt
if_nz or data,#1 '+$800 if win
ror data,#1
djnz x,#:loop
rol data,#12
rdlong x,par 'if room in buffer and key valid, enter
sub x,#1
and x,#$F
cmp x,_head wz
if_nz test data,#$FF wz
if_nz mov x,par
if_nz add x,#11*4
if_nz add x,_head
if_nz add x,_head
if_nz wrword data,x
if_nz add _head,#1
if_nz and _head,#$F
test stat,#4 wc 'if not configure flag, done
if_nc jmp #update 'else configure to update leds
'
'
' Configure keyboard
'
configure mov data,#$F3 'set keyboard auto-repeat
call #transmit
mov data,_auto
and data,#%11_11111
call #transmit
mov data,#$ED 'set keyboard lock-leds
call #transmit
mov data,_locks
rev data,#-3 & $1F
test data,#%100 wc
rcl data,#1
and data,#%111
call #transmit
mov x,_locks 'insert locks into _states
and x,#%111
shl _states+7,#3
or _states+7,x
ror _states+7,#3
mov _present,#1 'set _present
jmp #update 'done
'
'
' Lookup byte in table
'
look ror data,#2 'perform lookup
movs :reg,data
add :reg,#table
shr data,#27
mov x,data
:reg mov data,0
shr data,x
jmp #rand 'isolate byte
'
'
' Transmit byte to keyboard
'
transmit
_c1 or dira,cmask 'pull clock low
movs napshr,#13 'hold clock for ~128us (must be >100us)
call #nap
_d1 or dira,dmask 'pull data low
movs napshr,#18 'hold data for ~4us
call #nap
_c2 xor dira,cmask 'release clock
test data,#$0FF wc 'append parity and stop bits to byte
muxnc data,#$100
or data,dlsb
mov x,#10 'ready 10 bits
transmit_bit call #wait_c0 'wait until clock low
shr data,#1 wc 'output data bit
_d2 muxnc dira,dmask
mov wcond,c1 'wait until clock high
call #wait
djnz x,#transmit_bit 'another bit?
mov wcond,c0d0 'wait until clock and data low
call #wait
mov wcond,c1d1 'wait until clock and data high
call #wait
call #receive_ack 'receive ack byte with timed wait
cmp data,#$FA wz 'if ack error, reset keyboard
if_nz jmp #reset
transmit_ret ret
'
'
' Receive byte from keyboard
'
receive test _cpin,#$20 wc 'wait indefinitely for initial clock low
waitpne cmask,cmask
receive_ack
mov x,#11 'ready 11 bits
receive_bit call #wait_c0 'wait until clock low
movs napshr,#16 'pause ~16us
call #nap
_d3 test dmask,ina wc 'input data bit
rcr data,#1
mov wcond,c1 'wait until clock high
call #wait
djnz x,#receive_bit 'another bit?
shr data,#22 'align byte
test data,#$1FF wc 'if parity error, reset keyboard
if_nc jmp #reset
rand and data,#$FF 'isolate byte
look_ret
receive_ack_ret
receive_ret ret
'
'
' Wait for clock/data to be in required state(s)
'
wait_c0 mov wcond,c0 '(wait until clock low)
wait mov y,tenms 'set timeout to 10ms
wloop movs napshr,#18 'nap ~4us
call #nap
_c3 test cmask,ina wc 'check required state(s)
_d4 test dmask,ina wz 'loop until got state(s) or timeout
wcond if_never djnz y,#wloop '(replaced with c0/c1/c0d0/c1d1)
tjz y,#reset 'if timeout, reset keyboard
wait_ret
wait_c0_ret ret
c0 if_c djnz y,#wloop '(if_never replacements)
c1 if_nc djnz y,#wloop
c0d0 if_c_or_nz djnz y,#wloop
c1d1 if_nc_or_z djnz y,#wloop
'
'
' Nap
'
nap rdlong t,#0 'get clkfreq
napshr shr t,#18/16/13 'shr scales time
min t,#3 'ensure waitcnt won't snag
add t,cnt 'add cnt to time
waitcnt t,#0 'wait until time elapses (nap)
nap_ret ret
'
'
' Initialized data
'
'
dlsb long 1 << 9
tenms long 10_000 / 4
'
'
' Lookup table
' ascii scan extkey regkey ()=keypad
'
table word $0000 '00
word $00D8 '01 F9
word $0000 '02
word $00D4 '03 F5
word $00D2 '04 F3
word $00D0 '05 F1
word $00D1 '06 F2
word $00DB '07 F12
word $0000 '08
word $00D9 '09 F10
word $00D7 '0A F8
word $00D5 '0B F6
word $00D3 '0C F4
word $0009 '0D Tab
word $0060 '0E `
word $0000 '0F
word $0000 '10
word $F5F4 '11 Alt-R Alt-L
word $00F0 '12 Shift-L
word $0000 '13
word $F3F2 '14 Ctrl-R Ctrl-L
word $0071 '15 q
word $0031 '16 1
word $0000 '17
word $0000 '18
word $0000 '19
word $007A '1A z
word $0073 '1B s
word $0061 '1C a
word $0077 '1D w
word $0032 '1E 2
word $F600 '1F Win-L
word $0000 '20
word $0063 '21 c
word $0078 '22 x
word $0064 '23 d
word $0065 '24 e
word $0034 '25 4
word $0033 '26 3
word $F700 '27 Win-R
word $0000 '28
word $0020 '29 Space
word $0076 '2A v
word $0066 '2B f
word $0074 '2C t
word $0072 '2D r
word $0035 '2E 5
word $CC00 '2F Apps
word $0000 '30
word $006E '31 n
word $0062 '32 b
word $0068 '33 h
word $0067 '34 g
word $0079 '35 y
word $0036 '36 6
word $CD00 '37 Power
word $0000 '38
word $0000 '39
word $006D '3A m
word $006A '3B j
word $0075 '3C u
word $0037 '3D 7
word $0038 '3E 8
word $CE00 '3F Sleep
word $0000 '40
word $002C '41 ,
word $006B '42 k
word $0069 '43 i
word $006F '44 o
word $0030 '45 0
word $0039 '46 9
word $0000 '47
word $0000 '48
word $002E '49 .
word $EF2F '4A (/) /
word $006C '4B l
word $003B '4C ;
word $0070 '4D p
word $002D '4E -
word $0000 '4F
word $0000 '50
word $0000 '51
word $0027 '52 '
word $0000 '53
word $005B '54 [
word $003D '55 =
word $0000 '56
word $0000 '57
word $00DE '58 CapsLock
word $00F1 '59 Shift-R
word $EB0D '5A (Enter) Enter
word $005D '5B ]
word $0000 '5C
word $005C '5D \
word $CF00 '5E WakeUp
word $0000 '5F
word $0000 '60
word $0000 '61
word $0000 '62
word $0000 '63
word $0000 '64
word $0000 '65
word $00C8 '66 BackSpace
word $0000 '67
word $0000 '68
word $C5E1 '69 End (1)
word $0000 '6A
word $C0E4 '6B Left (4)
word $C4E7 '6C Home (7)
word $0000 '6D
word $0000 '6E
word $0000 '6F
word $CAE0 '70 Insert (0)
word $C9EA '71 Delete (.)
word $C3E2 '72 Down (2)
word $00E5 '73 (5)
word $C1E6 '74 Right (6)
word $C2E8 '75 Up (8)
word $00CB '76 Esc
word $00DF '77 NumLock
word $00DA '78 F11
word $00EC '79 (+)
word $C7E3 '7A PageDn (3)
word $00ED '7B (-)
word $DCEE '7C PrScr (*)
word $C6E9 '7D PageUp (9)
word $00DD '7E ScrLock
word $0000 '7F
word $0000 '80
word $0000 '81
word $0000 '82
word $00D6 '83 F7
keypad1 byte $CA, $C5, $C3, $C7, $C0, 0, $C1, $C4, $C2, $C6, $C9, $0D, "+-*/"
keypad2 byte "0123456789.", $0D, "+-*/"
shift1 byte "{|}", 0, 0, "~"
shift2 byte $22, 0, 0, 0, 0, "<_>?)!@#$%^&*(", 0, ":", 0, "+"
'
'
' Uninitialized data
'
dmask res 1
cmask res 1
stat res 1
data res 1
x res 1
y res 1
t res 1
_head res 1 'write-only
_present res 1 'write-only
_states res 8 'write-only
_dpin res 1 'read-only at start
_cpin res 1 'read-only at start
_locks res 1 'read-only at start
_auto res 1 'read-only at start
''
''
'' _________
'' Key Codes
''
'' 00..DF = keypress and keystate
'' E0..FF = keystate only
''
''
'' 09 Tab
'' 0D Enter
'' 20 Space
'' 21 !
'' 22 "
'' 23 #
'' 24 $
'' 25 %
'' 26 &
'' 27 '
'' 28 (
'' 29 )
'' 2A *
'' 2B +
'' 2C ,
'' 2D -
'' 2E .
'' 2F /
'' 30 0..9
'' 3A :
'' 3B ;
'' 3C <
'' 3D =
'' 3E >
'' 3F ?
'' 40 @
'' 41..5A A..Z
'' 5B [
'' 5C \
'' 5D ]
'' 5E ^
'' 5F _
'' 60 `
'' 61..7A a..z
'' 7B {
'' 7C |
'' 7D }
'' 7E ~
''
'' 80-BF (future international character support)
''
'' C0 Left Arrow
'' C1 Right Arrow
'' C2 Up Arrow
'' C3 Down Arrow
'' C4 Home
'' C5 End
'' C6 Page Up
'' C7 Page Down
'' C8 Backspace
'' C9 Delete
'' CA Insert
'' CB Esc
'' CC Apps
'' CD Power
'' CE Sleep
'' CF Wakeup
''
'' D0..DB F1..F12
'' DC Print Screen
'' DD Scroll Lock
'' DE Caps Lock
'' DF Num Lock
''
'' E0..E9 Keypad 0..9
'' EA Keypad .
'' EB Keypad Enter
'' EC Keypad +
'' ED Keypad -
'' EE Keypad *
'' EF Keypad /
''
'' F0 Left Shift
'' F1 Right Shift
'' F2 Left Ctrl
'' F3 Right Ctrl
'' F4 Left Alt
'' F5 Right Alt
'' F6 Left Win
'' F7 Right Win
''
'' FD Scroll Lock State
'' FE Caps Lock State
'' FF Num Lock State
''
'' +100 if Shift
'' +200 if Ctrl
'' +400 if Alt
'' +800 if Win
''
'' eg. Ctrl-Alt-Delete = $6C9
''
''
'' Note: Driver will buffer up to 15 keystrokes, then ignore overflow.
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ TERMS OF USE: MIT License │
├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │
│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │
│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│
│is furnished to do so, subject to the following conditions: │
│ │
│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│
│ │
│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │
│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │
│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │
│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

View File

@@ -0,0 +1,711 @@
''***************************************
''* TV Driver v1.1 *
''* Author: Chip Gracey *
''* Copyright (c) 2004 Parallax, Inc. *
''* See end of file for terms of use. *
''***************************************
' v1.0 - 01 May 2006 - original version
' v1.1 - 17 May 2006 - pixel tile size can now be 16 x 32 to enable more efficient
' character displays utilizing the internal font - see 'tv_mode'
CON
fntsc = 3_579_545 'NTSC color frequency
lntsc = 3640 'NTSC color cycles per line * 16
sntsc = 624 'NTSC color cycles per sync * 16
fpal = 4_433_618 'PAL color frequency
lpal = 4540 'PAL color cycles per line * 16
spal = 848 'PAL color cycles per sync * 16
paramcount = 14
colortable = $180 'start of colortable inside cog
VAR
long cog
PUB start(tvptr) : okay
'' Start TV driver - starts a cog
'' returns false if no cog available
''
'' tvptr = pointer to TV parameters
stop
okay := cog := cognew(@entry, tvptr) + 1
PUB stop
'' Stop TV driver - frees a cog
if cog
cogstop(cog~ - 1)
DAT
'*******************************
'* Assembly language TV driver *
'*******************************
org
'
'
' Entry
'
entry mov taskptr,#tasks 'reset tasks
mov x,#10 'perform task sections initially
:init jmpret taskret,taskptr
djnz x,#:init
'
'
' Superfield
'
superfield mov taskptr,#tasks 'reset tasks
test _mode,#%0001 wc 'if ntsc, set phaseflip
if_nc mov phaseflip,phasemask
test _mode,#%0010 wz 'get interlace into nz
'
'
' Field
'
field mov x,vinv 'do invisible back porch lines
:black call #hsync 'do hsync
waitvid burst,sync_high2 'do black
jmpret taskret,taskptr 'call task section (z undisturbed)
djnz x,#:black 'another black line?
wrlong visible,par 'set status to visible
mov x,vb 'do visible back porch lines
call #blank_lines
mov screen,_screen 'point to first tile (upper-leftmost)
mov y,_vt 'set vertical tiles
:line mov vx,_vx 'set vertical expand
:vert if_z xor interlace,#1 'interlace skip?
if_z tjz interlace,#:skip
call #hsync 'do hsync
mov vscl,hb 'do visible back porch pixels
xor tile,colortable
waitvid tile,#0
mov x,_ht 'set horizontal tiles
mov vscl,hx 'set horizontal expand
:tile rdword tile,screen 'read tile
or tile,line 'set pointer bits into tile
rol tile,#6 'read tile pixels
rdlong pixels,tile '(2 instructions between reads)
shr tile,#10+6 'set tile colors
movs :color,tile
add screen,#2 'point to next tile
mov tile,phaseflip
:color xor tile,colortable
waitvid tile,pixels 'pass colors and pixels to video
djnz x,#:tile 'another tile?
sub screen,hc2x 'repoint to first tile in same line
mov vscl,hf 'do visible front porch pixels
mov tile,phaseflip
xor tile,colortable
waitvid tile,#0
:skip djnz vx,#:vert 'vertical expand?
ror line,linerot 'set next line
add line,lineadd wc
rol line,linerot
if_nc jmp #:line
add screen,hc2x 'point to first tile in next line
djnz y,#:line 'another tile line?
if_z xor interlace,#1 wz 'get interlace and field1 into z
test _mode,#%0001 wc 'do visible front porch lines
mov x,vf
if_nz_and_c add x,#1
call #blank_lines
if_nz wrlong invisible,par 'unless interlace and field1, set status to invisible
if_z_eq_c call #hsync 'if required, do short line
if_z_eq_c mov vscl,hrest
if_z_eq_c waitvid burst,sync_high2
if_z_eq_c xor phaseflip,phasemask
call #vsync_high 'do high vsync pulses
movs vsync1,#sync_low1 'do low vsync pulses
movs vsync2,#sync_low2
call #vsync_low
call #vsync_high 'do high vsync pulses
if_nz mov vscl,hhalf 'if odd frame, do half line
if_nz waitvid burst,sync_high2
if_z jmp #field 'if interlace and field1, display field2
jmp #superfield 'else, new superfield
'
'
' Blank lines
'
blank_lines call #hsync 'do hsync
xor tile,colortable 'do background
waitvid tile,#0
djnz x,#blank_lines
blank_lines_ret ret
'
'
' Horizontal sync
'
hsync test _mode,#%0001 wc 'if pal, toggle phaseflip
if_c xor phaseflip,phasemask
mov vscl,sync_scale1 'do hsync
mov tile,phaseflip
xor tile,burst
waitvid tile,sync_normal
mov vscl,hvis 'setup in case blank line
mov tile,phaseflip
hsync_ret ret
'
'
' Vertical sync
'
vsync_high movs vsync1,#sync_high1 'vertical sync
movs vsync2,#sync_high2
vsync_low mov x,vrep
vsyncx mov vscl,sync_scale1
vsync1 waitvid burst,sync_high1
mov vscl,sync_scale2
vsync2 waitvid burst,sync_high2
djnz x,#vsyncx
vsync_low_ret
vsync_high_ret ret
'
'
' Tasks - performed in sections during invisible back porch lines
'
tasks mov t1,par 'load parameters
movd :par,#_enable '(skip _status)
mov t2,#paramcount - 1
:load add t1,#4
:par rdlong 0,t1
add :par,d0
djnz t2,#:load '+119
mov t1,_pins 'set video pins and directions
test t1,#$08 wc
if_nc mov t2,pins0
if_c mov t2,pins1
test t1,#$40 wc
shr t1,#1
shl t1,#3
shr t2,t1
movs vcfg,t2
shr t1,#6
movd vcfg,t1
shl t1,#3
and t2,#$FF
shl t2,t1
if_nc mov dira,t2
if_nc mov dirb,#0
if_c mov dira,#0
if_c mov dirb,t2 '+18
tjz _enable,#disabled '+2, disabled?
jmpret taskptr,taskret '+1=140, break and return later
movs :rd,#wtab 'load ntsc/pal metrics from word table
movd :wr,#hvis
mov t1,#wtabx - wtab
test _mode,#%0001 wc
:rd mov t2,0
add :rd,#1
if_nc shl t2,#16
shr t2,#16
:wr mov 0,t2
add :wr,d0
djnz t1,#:rd '+54
if_nc movs :ltab,#ltab 'load ntsc/pal metrics from long table
if_c movs :ltab,#ltab+1
movd :ltab,#fcolor
mov t1,#(ltabx - ltab) >> 1
:ltab mov 0,0
add :ltab,d0s1
djnz t1,#:ltab '+17
rdlong t1,#0 'get CLKFREQ
shr t1,#1 'if CLKFREQ < 16MHz, cancel _broadcast
cmp t1,m8 wc
if_c mov _broadcast,#0
shr t1,#1 'if CLKFREQ < color frequency * 4, disable
cmp t1,fcolor wc
if_c jmp #disabled '+11
jmpret taskptr,taskret '+1=83, break and return later
mov t1,fcolor 'set ctra pll to fcolor * 16
call #divide 'if ntsc, set vco to fcolor * 32 (114.5454 MHz)
test _mode,#%0001 wc 'if pal, set vco to fcolor * 16 (70.9379 MHz)
if_c movi ctra,#%00001_111 'select fcolor * 16 output (ntsc=/2, pal=/1)
if_nc movi ctra,#%00001_110
if_nc shl t2,#1
mov frqa,t2 '+147
jmpret taskptr,taskret '+1=148, break and return later
mov t1,_broadcast 'set ctrb pll to _broadcast
mov t2,#0 'if 0, turn off ctrb
tjz t1,#:off
min t1,m8 'limit from 8MHz to 128MHz
max t1,m128
mov t2,#%00001_100 'adjust _broadcast to be within 4MHz-8MHz
:scale shr t1,#1 '(vco will be within 64MHz-128MHz)
cmp m8,t1 wc
if_c add t2,#%00000_001
if_c jmp #:scale
:off movi ctrb,t2
call #divide
mov frqb,t2 '+165
jmpret taskptr,taskret '+1=166, break and return later
mov t1,#%10100_000 'set video configuration
test _pins,#$01 wc '(swap broadcast/baseband output bits?)
if_c or t1,#%01000_000
test _mode,#%1000 wc '(strip chroma from broadcast?)
if_nc or t1,#%00010_000
test _mode,#%0100 wc '(strip chroma from baseband?)
if_nc or t1,#%00001_000
and _auralcog,#%111 '(set aural cog)
or t1,_auralcog
movi vcfg,t1 '+10
mov hx,_hx 'compute horizontal metrics
shl hx,#8
or hx,_hx
shl hx,#4
mov hc2x,_ht
shl hc2x,#1
mov t1,_ht
mov t2,_hx
call #multiply
mov hf,hvis
sub hf,t1
shr hf,#1 wc
mov hb,_ho
addx hb,hf
sub hf,_ho '+52
mov t1,_vt 'compute vertical metrics
mov t2,_vx
call #multiply
test _mode,#%10000 wc 'consider tile size
muxc linerot,#1
mov lineadd,lineinc
if_c shr lineadd,#1
if_c shl t1,#1
test _mode,#%0010 wc 'consider interlace
if_c shr t1,#1
mov vf,vvis
sub vf,t1
shr vf,#1 wc
neg vb,_vo
addx vb,vf
add vf,_vo '+53
xor _mode,#%0010 '+1, flip interlace bit for display
:colors jmpret taskptr,taskret '+1=117/160, break and return later
mov t1,#13 'load next 13 colors into colortable
:colorloop mov t2,:colorreg '5 times = 65 (all 64 colors loaded)
shr t2,#9-2
and t2,#$FC
add t2,_colors
:colorreg rdlong colortable,t2
add :colorreg,d0
andn :colorreg,d6
djnz t1,#:colorloop '+158
jmp #:colors '+1, keep loading colors
'
'
' Divide t1/CLKFREQ to get frqa or frqb value into t2
'
divide rdlong m1,#0 'get CLKFREQ
mov m2,#32+1
:loop cmpsub t1,m1 wc
rcl t2,#1
shl t1,#1
djnz m2,#:loop
divide_ret ret '+140
'
'
' Multiply t1 * t2 * 16 (t1, t2 = bytes)
'
multiply shl t2,#8+4-1
mov m1,#8
:loop shr t1,#1 wc
if_c add t1,t2
djnz m1,#:loop
multiply_ret ret '+37
'
'
' Disabled - reset status, nap ~4ms, try again
'
disabled mov ctra,#0 'reset ctra
mov ctrb,#0 'reset ctrb
mov vcfg,#0 'reset video
wrlong outa,par 'set status to disabled
rdlong t1,#0 'get CLKFREQ
shr t1,#8 'nap for ~4ms
min t1,#3
add t1,cnt
waitcnt t1,#0
jmp #entry 'reload parameters
'
'
' Initialized data
'
m8 long 8_000_000
m128 long 128_000_000
d0 long 1 << 9 << 0
d6 long 1 << 9 << 6
d0s1 long 1 << 9 << 0 + 1 << 1
interlace long 0
invisible long 1
visible long 2
phaseflip long $00000000
phasemask long $F0F0F0F0
line long $00060000
lineinc long $10000000
linerot long 0
pins0 long %11110000_01110000_00001111_00000111
pins1 long %11111111_11110111_01111111_01110111
sync_high1 long %0101010101010101010101_101010_0101
sync_high2 long %01010101010101010101010101010101 'used for black
sync_low1 long %1010101010101010101010101010_0101
sync_low2 long %01_101010101010101010101010101010
'
'
' NTSC/PAL metrics tables
' ntsc pal
' ----------------------------------------------
wtab word lntsc - sntsc, lpal - spal 'hvis
word lntsc / 2 - sntsc, lpal / 2 - spal 'hrest
word lntsc / 2, lpal / 2 'hhalf
word 243, 286 'vvis
word 10, 18 'vinv
word 6, 5 'vrep
word $02_8A, $02_AA 'burst
wtabx
ltab long fntsc 'fcolor
long fpal
long sntsc >> 4 << 12 + sntsc 'sync_scale1
long spal >> 4 << 12 + spal
long 67 << 12 + lntsc / 2 - sntsc 'sync_scale2
long 79 << 12 + lpal / 2 - spal
long %0101_00000000_01_10101010101010_0101 'sync_normal
long %010101_00000000_01_101010101010_0101
ltabx
'
'
' Uninitialized data
'
taskptr res 1 'tasks
taskret res 1
t1 res 1
t2 res 1
m1 res 1
m2 res 1
x res 1 'display
y res 1
hf res 1
hb res 1
vf res 1
vb res 1
hx res 1
vx res 1
hc2x res 1
screen res 1
tile res 1
pixels res 1
lineadd res 1
hvis res 1 'loaded from word table
hrest res 1
hhalf res 1
vvis res 1
vinv res 1
vrep res 1
burst res 1
fcolor res 1 'loaded from long table
sync_scale1 res 1
sync_scale2 res 1
sync_normal res 1
'
'
' Parameter buffer
'
_enable res 1 '0/non-0 read-only
_pins res 1 '%pppmmmm read-only
_mode res 1 '%tccip read-only
_screen res 1 '@word read-only
_colors res 1 '@long read-only
_ht res 1 '1+ read-only
_vt res 1 '1+ read-only
_hx res 1 '4+ read-only
_vx res 1 '1+ read-only
_ho res 1 '0+- read-only
_vo res 1 '0+- read-only
_broadcast res 1 '0+ read-only
_auralcog res 1 '0-7 read-only
fit colortable 'fit underneath colortable ($180-$1BF)
''
''___
''VAR 'TV parameters - 14 contiguous longs
''
'' long tv_status '0/1/2 = off/invisible/visible read-only
'' long tv_enable '0/non-0 = off/on write-only
'' long tv_pins '%pppmmmm = pin group, pin group mode write-only
'' long tv_mode '%tccip = tile,chroma,interlace,ntsc/pal write-only
'' long tv_screen 'pointer to screen (words) write-only
'' long tv_colors 'pointer to colors (longs) write-only
'' long tv_ht 'horizontal tiles write-only
'' long tv_vt 'vertical tiles write-only
'' long tv_hx 'horizontal tile expansion write-only
'' long tv_vx 'vertical tile expansion write-only
'' long tv_ho 'horizontal offset write-only
'' long tv_vo 'vertical offset write-only
'' long tv_broadcast 'broadcast frequency (Hz) write-only
'' long tv_auralcog 'aural fm cog write-only
''
''The preceding VAR section may be copied into your code.
''After setting variables, do start(@tv_status) to start driver.
''
''All parameters are reloaded each superframe, allowing you to make live
''changes. To minimize flicker, correlate changes with tv_status.
''
''Experimentation may be required to optimize some parameters.
''
''Parameter descriptions:
'' _________
'' tv_status
''
'' driver sets this to indicate status:
'' 0: driver disabled (tv_enable = 0 or CLKFREQ < requirement)
'' 1: currently outputting invisible sync data
'' 2: currently outputting visible screen data
'' _________
'' tv_enable
''
'' 0: disable (pins will be driven low, reduces power)
'' non-0: enable
'' _______
'' tv_pins
''
'' bits 6..4 select pin group:
'' %000: pins 7..0
'' %001: pins 15..8
'' %010: pins 23..16
'' %011: pins 31..24
'' %100: pins 39..32
'' %101: pins 47..40
'' %110: pins 55..48
'' %111: pins 63..56
''
'' bits 3..0 select pin group mode:
'' %0000: %0000_0111 - baseband
'' %0001: %0000_0111 - broadcast
'' %0010: %0000_1111 - baseband + chroma
'' %0011: %0000_1111 - broadcast + aural
'' %0100: %0111_0000 broadcast -
'' %0101: %0111_0000 baseband -
'' %0110: %1111_0000 broadcast + aural -
'' %0111: %1111_0000 baseband + chroma -
'' %1000: %0111_0111 broadcast baseband
'' %1001: %0111_0111 baseband broadcast
'' %1010: %0111_1111 broadcast baseband + chroma
'' %1011: %0111_1111 baseband broadcast + aural
'' %1100: %1111_0111 broadcast + aural baseband
'' %1101: %1111_0111 baseband + chroma broadcast
'' %1110: %1111_1111 broadcast + aural baseband + chroma
'' %1111: %1111_1111 baseband + chroma broadcast + aural
'' -----------------------------------------------------------
'' active pins top nibble bottom nibble
''
'' the baseband signal nibble is arranged as:
'' bit 3: chroma signal for s-video (attach via 560-ohm resistor)
'' bits 2..0: baseband video (sum 270/560/1100-ohm resistors to form 75-ohm 1V signal)
''
'' the broadcast signal nibble is arranged as:
'' bit 3: aural subcarrier (sum 560-ohm resistor into network below)
'' bits 2..0: visual carrier (sum 270/560/1100-ohm resistors to form 75-ohm 1V signal)
'' _______
'' tv_mode
''
'' bit 4 selects between 16x16 and 16x32 pixel tiles:
'' 0: 16x16 pixel tiles (tileheight = 16)
'' 1: 16x32 pixel tiles (tileheight = 32)
''
'' bit 3 controls chroma mixing into broadcast:
'' 0: mix chroma into broadcast (color)
'' 1: strip chroma from broadcast (black/white)
''
'' bit 2 controls chroma mixing into baseband:
'' 0: mix chroma into baseband (composite color)
'' 1: strip chroma from baseband (black/white or s-video)
''
'' bit 1 controls interlace:
'' 0: progressive scan (243 display lines for NTSC, 286 for PAL)
'' less flicker, good for motion
'' 1: interlaced scan (486 display lines for NTSC, 572 for PAL)
'' doubles the vertical display lines, good for text
''
'' bit 0 selects NTSC or PAL format
'' 0: NTSC
'' 3016 horizontal display ticks
'' 243 or 486 (interlaced) vertical display lines
'' CLKFREQ must be at least 14_318_180 (4 * 3_579_545 Hz)*
'' 1: PAL
'' 3692 horizontal display ticks
'' 286 or 572 (interlaced) vertical display lines
'' CLKFREQ must be at least 17_734_472 (4 * 4_433_618 Hz)*
''
'' * driver will disable itself while CLKFREQ is below requirement
'' _________
'' tv_screen
''
'' pointer to words which define screen contents (left-to-right, top-to-bottom)
'' number of words must be tv_ht * tv_vt
'' each word has two bitfields: a 6-bit colorset ptr and a 10-bit pixelgroup ptr
'' bits 15..10: select the colorset* for the associated pixel tile
'' bits 9..0: select the pixelgroup** address %ppppppppppcccc00 (p=address, c=0..15)
''
'' * colorsets are longs which each define four 8-bit colors
''
'' ** pixelgroups are <tileheight> longs which define (left-to-right, top-to-bottom) the 2-bit
'' (four color) pixels that make up a 16x16 or a 32x32 pixel tile
'' _________
'' tv_colors
''
'' pointer to longs which define colorsets
'' number of longs must be 1..64
'' each long has four 8-bit fields which define colors for 2-bit (four color) pixels
'' first long's bottom color is also used as the screen background color
'' 8-bit color fields are as follows:
'' bits 7..4: chroma data (0..15 = blue..green..red..)*
'' bit 3: controls chroma modulation (0=off, 1=on)
'' bits 2..0: 3-bit luminance level:
'' values 0..1: reserved for sync - don't use
'' values 2..7: valid luminance range, modulation adds/subtracts 1 (beware of 7)
'' value 0 may be modulated to produce a saturated color toggling between levels 1 and 7
''
'' * because of TV's limitations, it doesn't look good when chroma changes abruptly -
'' rather, use luminance - change chroma only against a black or white background for
'' best appearance
'' _____
'' tv_ht
''
'' horizontal number pixel tiles - must be at least 1
'' practical limit is 40 for NTSC, 50 for PAL
'' _____
'' tv_vt
''
'' vertical number of pixel tiles - must be at least 1
'' practical limit is 13 for NTSC, 15 for PAL (26/30 max for interlaced NTSC/PAL)
'' _____
'' tv_hx
''
'' horizontal tile expansion factor - must be at least 3 for NTSC, 4 for PAL
''
'' make sure 16 * tv_ht * tv_hx + ||tv_ho + 32 is less than the horizontal display ticks
'' _____
'' tv_vx
''
'' vertical tile expansion factor - must be at least 1
''
'' make sure <tileheight> * tv_vt * tv_vx + ||tv_vo + 1 is less than the display lines
'' _____
'' tv_ho
''
'' horizontal offset in ticks - pos/neg value (0 for centered image)
'' shifts the display right/left
'' _____
'' tv_vo
''
'' vertical offset in lines - pos/neg value (0 for centered image)
'' shifts the display up/down
'' ____________
'' tv_broadcast
''
'' broadcast frequency expressed in Hz (ie channel 2 is 55_250_000)
'' if 0, modulator is turned off - saves power
''
'' broadcasting requires CLKFREQ to be at least 16_000_000
'' while CLKFREQ is below 16_000_000, modulator will be turned off
'' ___________
'' tv_auralcog
''
'' selects cog to supply aural fm signal - 0..7
'' uses ctra pll output from selected cog
''
'' in NTSC, the offset frequency must be 4.5MHz and the max bandwidth +-25KHz
'' in PAL, the offset frequency and max bandwidth vary by PAL type
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ TERMS OF USE: MIT License │
├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │
│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │
│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│
│is furnished to do so, subject to the following conditions: │
│ │
│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│
│ │
│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │
│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │
│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │
│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

View File

@@ -0,0 +1,244 @@
''***************************************
''* TV Terminal v1.1 *
''* Author: Chip Gracey *
''* Copyright (c) 2005 Parallax, Inc. *
''* See end of file for terms of use. *
''***************************************
{-----------------REVISION HISTORY-----------------
v1.1 - Updated 5/15/2006 to use actual pin number, instead of pin group, for Start method's basepin parameter.}
CON
x_tiles = 16
y_tiles = 13
x_screen = x_tiles << 4
y_screen = y_tiles << 4
width = 0 '0 = minimum
x_scale = 1 '1 = minimum
y_scale = 1 '1 = minimum
x_spacing = 6 '6 = normal
y_spacing = 13 '13 = normal
x_chr = x_scale * x_spacing
y_chr = y_scale * y_spacing
y_offset = y_spacing / 6 + y_chr - 1
x_limit = x_screen / (x_scale * x_spacing)
y_limit = y_screen / (y_scale * y_spacing)
y_max = y_limit - 1
y_screen_bytes = y_screen << 2
y_scroll = y_chr << 2
y_scroll_longs = y_chr * y_max
y_clear = y_scroll_longs << 2
y_clear_longs = y_screen - y_scroll_longs
paramcount = 14
VAR
long x, y, bitmap_base
long tv_status '0/1/2 = off/visible/invisible read-only
long tv_enable '0/? = off/on write-only
long tv_pins '%ppmmm = pins write-only
long tv_mode '%ccinp = chroma,interlace,ntsc/pal,swap write-only
long tv_screen 'pointer to screen (words) write-only
long tv_colors 'pointer to colors (longs) write-only
long tv_hc 'horizontal cells write-only
long tv_vc 'vertical cells write-only
long tv_hx 'horizontal cell expansion write-only
long tv_vx 'vertical cell expansion write-only
long tv_ho 'horizontal offset write-only
long tv_vo 'vertical offset write-only
long tv_broadcast 'broadcast frequency (Hz) write-only
long tv_auralcog 'aural fm cog write-only
long bitmap[x_tiles * y_tiles << 4 + 16] 'add 16 longs to allow for 64-byte alignment
word screen[x_tiles * y_tiles]
OBJ
tv : "tv"
gr : "graphics"
PUB start(basepin)
'' Start terminal
''
'' basepin = first of three pins on a 4-pin boundary (0, 4, 8...) to have
'' 1.1k, 560, and 270 ohm resistors connected and summed to form the 1V,
'' 75 ohm DAC for baseband video
'init bitmap and tile screen
bitmap_base := (@bitmap + $3F) & $7FC0
repeat x from 0 to x_tiles - 1
repeat y from 0 to y_tiles - 1
screen[y * x_tiles + x] := bitmap_base >> 6 + y + x * y_tiles
'start tv
tvparams_pins := (basepin & $38) << 1 | (basepin & 4 == 4) & %0101
longmove(@tv_status, @tvparams, paramcount)
tv_screen := @screen
tv_colors := @color_schemes
tv.start(@tv_status)
'start graphics
gr.start
gr.setup(x_tiles, y_tiles, 0, y_screen, bitmap_base)
gr.textmode(x_scale, y_scale, x_spacing, 0)
gr.width(width)
out(0)
PUB stop
'' Stop terminal
tv.stop
gr.stop
PUB out(c)
'' Print a character
''
'' $00 = home
'' $01..$03 = color
'' $04..$07 = color schemes
'' $09 = tab
'' $0D = return
'' $20..$7E = character
case c
$00: 'home?
gr.clear
x := y := 0
$01..$03: 'color?
gr.color(c)
$04..$07: 'color scheme?
tv_colors := @color_schemes[c & 3]
$09: 'tab?
repeat
out($20)
while x & 7
$0D: 'return?
newline
$20..$7E: 'character?
gr.text(x * x_chr, -y * y_chr - y_offset, @c)
gr.finish
if ++x == x_limit
newline
PUB str(string_ptr)
'' Print a zero-terminated string
repeat strsize(string_ptr)
out(byte[string_ptr++])
PUB dec(value) | i
'' Print a decimal number
if value < 0
-value
out("-")
i := 1_000_000_000
repeat 10
if value => i
out(value / i + "0")
value //= i
result~~
elseif result or i == 1
out("0")
i /= 10
PUB hex(value, digits)
'' Print a hexadecimal number
value <<= (8 - digits) << 2
repeat digits
out(lookupz((value <-= 4) & $F : "0".."9", "A".."F"))
PUB bin(value, digits)
'' Print a binary number
value <<= 32 - digits
repeat digits
out((value <-= 1) & 1 + "0")
PRI newline
if ++y == y_limit
gr.finish
repeat x from 0 to x_tiles - 1
y := bitmap_base + x * y_screen_bytes
longmove(y, y + y_scroll, y_scroll_longs)
longfill(y + y_clear, 0, y_clear_longs)
y := y_max
x := 0
DAT
tvparams long 0 'status
long 1 'enable
tvparams_pins long %001_0101 'pins
long %0000 'mode
long 0 'screen
long 0 'colors
long x_tiles 'hc
long y_tiles 'vc
long 10 'hx
long 1 'vx
long 0 'ho
long 0 'vo
long 55_250_000 'broadcast
long 0 'auralcog
color_schemes long $BC_6C_05_02
long $0E_0D_0C_0A
long $6E_6D_6C_6A
long $BE_BD_BC_BA
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ TERMS OF USE: MIT License │
├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │
│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │
│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│
│is furnished to do so, subject to the following conditions: │
│ │
│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│
│ │
│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │
│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │
│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │
│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

View File

@@ -0,0 +1,232 @@
''***************************************
''* TV Text 40x13 v1.0 *
''* Author: Chip Gracey *
''* Copyright (c) 2006 Parallax, Inc. *
''* See end of file for terms of use. *
''***************************************
CON
cols = 40
rows = 13
screensize = cols * rows
lastrow = screensize - cols
tv_count = 14
VAR
long col, row, color, flag
word screen[screensize]
long colors[8 * 2]
long tv_status '0/1/2 = off/invisible/visible read-only (14 longs)
long tv_enable '0/non-0 = off/on write-only
long tv_pins '%pppmmmm = pin group, pin group mode write-only
long tv_mode '%tccip = tile,chroma,interlace,ntsc/pal write-only
long tv_screen 'pointer to screen (words) write-only
long tv_colors 'pointer to colors (longs) write-only
long tv_ht 'horizontal tiles write-only
long tv_vt 'vertical tiles write-only
long tv_hx 'horizontal tile expansion write-only
long tv_vx 'vertical tile expansion write-only
long tv_ho 'horizontal offset write-only
long tv_vo 'vertical offset write-only
long tv_broadcast 'broadcast frequency (Hz) write-only
long tv_auralcog 'aural fm cog write-only
OBJ
tv : "tv"
PUB start(basepin) : okay
'' Start terminal - starts a cog
'' returns false if no cog available
setcolors(@palette)
out(0)
longmove(@tv_status, @tv_params, tv_count)
tv_pins := (basepin & $38) << 1 | (basepin & 4 == 4) & %0101
tv_screen := @screen
tv_colors := @colors
okay := tv.start(@tv_status)
PUB stop
'' Stop terminal - frees a cog
tv.stop
PUB str(stringptr)
'' Print a zero-terminated string
repeat strsize(stringptr)
out(byte[stringptr++])
PUB dec(value) | i
'' Print a decimal number
if value < 0
-value
out("-")
i := 1_000_000_000
repeat 10
if value => i
out(value / i + "0")
value //= i
result~~
elseif result or i == 1
out("0")
i /= 10
PUB hex(value, digits)
'' Print a hexadecimal number
value <<= (8 - digits) << 2
repeat digits
out(lookupz((value <-= 4) & $F : "0".."9", "A".."F"))
PUB bin(value, digits)
'' Print a binary number
value <<= 32 - digits
repeat digits
out((value <-= 1) & 1 + "0")
PUB out(c) | i, k
'' Output a character
''
'' $00 = clear screen
'' $01 = home
'' $08 = backspace
'' $09 = tab (8 spaces per)
'' $0A = set X position (X follows)
'' $0B = set Y position (Y follows)
'' $0C = set color (color follows)
'' $0D = return
'' others = printable characters
case flag
$00: case c
$00: wordfill(@screen, $220, screensize)
col := row := 0
$01: col := row := 0
$08: if col
col--
$09: repeat
print(" ")
while col & 7
$0A..$0C: flag := c
return
$0D: newline
other: print(c)
$0A: col := c // cols
$0B: row := c // rows
$0C: color := c & 7
flag := 0
PUB setcolors(colorptr) | i, fore, back
'' Override default color palette
'' colorptr must point to a list of up to 8 colors
'' arranged as follows:
''
'' fore back
'' ------------
'' palette byte color, color 'color 0
'' byte color, color 'color 1
'' byte color, color 'color 2
'' ...
repeat i from 0 to 7
fore := byte[colorptr][i << 1]
back := byte[colorptr][i << 1 + 1]
colors[i << 1] := fore << 24 + back << 16 + fore << 8 + back
colors[i << 1 + 1] := fore << 24 + fore << 16 + back << 8 + back
PRI print(c)
screen[row * cols + col] := (color << 1 + c & 1) << 10 + $200 + c & $FE
if ++col == cols
newline
PRI newline | i
col := 0
if ++row == rows
row--
wordmove(@screen, @screen[cols], lastrow) 'scroll lines
wordfill(@screen[lastrow], $220, cols) 'clear new line
DAT
tv_params long 0 'status
long 1 'enable
long 0 'pins
long %10010 'mode
long 0 'screen
long 0 'colors
long cols 'hc
long rows 'vc
long 4 'hx
long 1 'vx
long 0 'ho
long 0 'vo
long 0 'broadcast
long 0 'auralcog
' fore back
' color color
palette byte $07, $0A '0 white / dark blue
byte $07, $BB '1 white / red
byte $9E, $9B '2 yellow / brown
byte $04, $07 '3 grey / white
byte $3D, $3B '4 cyan / dark cyan
byte $6B, $6E '5 green / gray-green
byte $BB, $CE '6 red / pink
byte $3C, $0A '7 cyan / blue
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ TERMS OF USE: MIT License │
├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │
│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │
│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│
│is furnished to do so, subject to the following conditions: │
│ │
│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│
│ │
│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │
│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │
│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │
│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

View File

@@ -0,0 +1,596 @@
''***************************************
''* VGA Driver v1.1 *
''* Author: Chip Gracey *
''* Copyright (c) 2006 Parallax, Inc. *
''* See end of file for terms of use. *
''***************************************
' v1.0 - 01 May 2006 - original version
' v1.1 - 15 May 2006 - pixel tile size can now be 16 x 32 to enable more efficient
' character displays utilizing the internal font - see 'vga_mode'
CON
paramcount = 21
colortable = $180 'start of colortable inside cog
VAR
long cog
PUB start(vgaptr) : okay
'' Start VGA driver - starts a cog
'' returns false if no cog available
''
'' vgaptr = pointer to VGA parameters
stop
okay := cog := cognew(@entry, vgaptr) + 1
PUB stop
'' Stop VGA driver - frees a cog
if cog
cogstop(cog~ - 1)
DAT
'********************************
'* Assembly language VGA driver *
'********************************
org
'
'
' Entry
'
entry mov taskptr,#tasks 'reset tasks
mov x,#8 'perform task sections initially
:init jmpret taskret,taskptr
djnz x,#:init
'
'
' Superfield
'
superfield mov hv,hvbase 'set hv
mov interlace,#0 'reset interlace
test _mode,#%0100 wz 'get interlace into nz
'
'
' Field
'
field wrlong visible,par 'set status to visible
tjz vb,#:nobl 'do any visible back porch lines
mov x,vb
movd bcolor,#colortable
call #blank_line
:nobl
mov screen,_screen 'point to first tile (upper-leftmost)
mov y,_vt 'set vertical tiles
:line mov vx,_vx 'set vertical expand
:vert if_nz xor interlace,#1 'interlace skip?
if_nz tjz interlace,#:skip
tjz hb,#:nobp 'do any visible back porch pixels
mov vscl,hb
waitvid colortable,#0
:nobp
mov x,_ht 'set horizontal tiles
mov vscl,hx 'set horizontal expand
:tile rdword tile,screen 'read tile
add tile,line 'set pointer bits into tile
rol tile,#6 'read tile pixels
rdlong pixels,tile '(8 clocks between reads)
shr tile,#10+6 'set tile colors
movd :color,tile
add screen,#2 'point to next tile
:color waitvid colortable,pixels 'pass colors and pixels to video
djnz x,#:tile 'another tile?
sub screen,hc2x 'repoint to first tile in same line
tjz hf,#:nofp 'do any visible front porch pixels
mov vscl,hf
waitvid colortable,#0
:nofp
mov x,#1 'do hsync
call #blank_hsync '(x=0)
:skip djnz vx,#:vert 'vertical expand?
ror line,linerot 'set next line
add line,lineadd wc
rol line,linerot
if_nc jmp #:line
add screen,hc2x 'point to first tile in next line
djnz y,#:line wc 'another tile line? (c=0)
tjz vf,#:nofl 'do any visible front porch lines
mov x,vf
movd bcolor,#colortable
call #blank_line
:nofl
if_nz xor interlace,#1 wc,wz 'get interlace and field1 into nz (c=0/?)
if_z wrlong invisible,par 'unless interlace and field1, set status to invisible
mov taskptr,#tasks 'reset tasks
addx x,_vf wc 'do invisible front porch lines (x=0 before, c=0 after)
call #blank_line
mov x,_vs 'do vsync lines
call #blank_vsync
mov x,_vb 'do invisible back porch lines, except last
call #blank_vsync
if_nz jmp #field 'if interlace and field1, display field2
jmp #superfield 'else, new superfield
'
'
' Blank line(s)
'
blank_vsync cmp interlace,#2 wc 'vsync (c=1)
blank_line mov vscl,h1 'blank line or vsync-interlace?
if_nc add vscl,h2
if_c_and_nz xor hv,#%01
if_c waitvid hv,#0
if_c mov vscl,h2 'blank line or vsync-normal?
if_c_and_z xor hv,#%01
bcolor waitvid hv,#0
if_nc jmpret taskret,taskptr 'call task section (z undisturbed)
blank_hsync mov vscl,_hf 'hsync, do invisible front porch pixels
waitvid hv,#0
mov vscl,_hs 'do invisble sync pixels
xor hv,#%10
waitvid hv,#0
mov vscl,_hb 'do invisible back porch pixels
xor hv,#%10
waitvid hv,#0
djnz x,#blank_line wc '(c=0)
movd bcolor,#hv
blank_hsync_ret
blank_line_ret
blank_vsync_ret ret
'
'
' Tasks - performed in sections during invisible back porch lines
'
tasks mov t1,par 'load parameters
movd :par,#_enable '(skip _status)
mov t2,#paramcount - 1
:load add t1,#4
:par rdlong 0,t1
add :par,d0
djnz t2,#:load '+164
mov t1,#2 'set video pins and directions
shl t1,_pins '(if video disabled, pins will drive low)
sub t1,#1
test _pins,#$20 wc
and _pins,#$38
shr t1,_pins
movs vcfg,t1
shl t1,_pins
shr _pins,#3
movd vcfg,_pins
if_nc mov dira,t1
if_nc mov dirb,#0
if_c mov dira,#0
if_c mov dirb,t1 '+14
tjz _enable,#disabled '+2, disabled?
jmpret taskptr,taskret '+1=181, break and return later
rdlong t1,#0 'make sure CLKFREQ => 16MHz
shr t1,#1
cmp t1,m8 wc
if_c jmp #disabled '+8
min _rate,pllmin 'limit _rate to pll range
max _rate,pllmax '+2
mov t1,#%00001_011 'set ctra configuration
:max cmp m8,_rate wc 'adjust rate to be within 4MHz-8MHz
if_c shr _rate,#1 '(vco will be within 64MHz-128MHz)
if_c add t1,#%00000_001
if_c jmp #:max
:min cmp _rate,m4 wc
if_c shl _rate,#1
if_c sub x,#%00000_001
if_c jmp #:min
movi ctra,t1 '+22
rdlong t1,#0 'divide _rate/CLKFREQ and set frqa
mov hvbase,#32+1
:div cmpsub _rate,t1 wc
rcl t2,#1
shl _rate,#1
djnz hvbase,#:div '(hvbase=0)
mov frqa,t2 '+136
test _mode,#%0001 wc 'make hvbase
muxnc hvbase,vmask
test _mode,#%0010 wc
muxnc hvbase,hmask '+4
jmpret taskptr,taskret '+1=173, break and return later
mov hx,_hx 'compute horizontal metrics
shl hx,#8
or hx,_hx
shl hx,#4
mov hc2x,_ht
shl hc2x,#1
mov h1,_hd
neg h2,_hf
sub h2,_hs
sub h2,_hb
sub h1,h2
shr h1,#1 wc
addx h2,h1
mov t1,_ht
mov t2,_hx
call #multiply
mov hf,_hd
sub hf,t1
shr hf,#1 wc
mov hb,_ho
addx hb,hf
sub hf,_ho '+59
mov t1,_vt 'compute vertical metrics
mov t2,_vx
call #multiply
test _mode,#%1000 wc 'consider tile size
muxc linerot,#1
mov lineadd,lineinc
if_c shr lineadd,#1
if_c shl t1,#1
test _mode,#%0100 wc 'consider interlace
if_c shr t1,#1
mov vf,_vd
sub vf,t1
shr vf,#1 wc
neg vb,_vo
addx vb,vf
add vf,_vo '+53
movi vcfg,#%01100_000 '+1, set video configuration
:colors jmpret taskptr,taskret '+1=114/160, break and return later
mov t1,#13 'load next 13 colors into colortable
:loop mov t2,:color '5 times = 65 (all 64 colors loaded)
shr t2,#9-2
and t2,#$FC
add t2,_colors
rdlong t2,t2
and t2,colormask
or t2,hvbase
:color mov colortable,t2
add :color,d0
andn :color,d6
djnz t1,#:loop '+158
jmp #:colors '+1, keep loading colors
'
'
' Multiply t1 * t2 * 16 (t1, t2 = bytes)
'
multiply shl t2,#8+4-1
mov tile,#8
:loop shr t1,#1 wc
if_c add t1,t2
djnz tile,#:loop
multiply_ret ret '+37
'
'
' Disabled - reset status, nap ~4ms, try again
'
disabled mov ctra,#0 'reset ctra
mov vcfg,#0 'reset video
wrlong outa,par 'set status to disabled
rdlong t1,#0 'get CLKFREQ
shr t1,#8 'nap for ~4ms
min t1,#3
add t1,cnt
waitcnt t1,#0
jmp #entry 'reload parameters
'
'
' Initialized data
'
pllmin long 500_000 'pll lowest output frequency
pllmax long 128_000_000 'pll highest output frequency
m8 long 8_000_000 '*16 = 128MHz (pll vco max)
m4 long 4_000_000 '*16 = 64MHz (pll vco min)
d0 long 1 << 9 << 0
d6 long 1 << 9 << 6
invisible long 1
visible long 2
line long $00060000
lineinc long $10000000
linerot long 0
vmask long $01010101
hmask long $02020202
colormask long $FCFCFCFC
'
'
' Uninitialized data
'
taskptr res 1 'tasks
taskret res 1
t1 res 1
t2 res 1
x res 1 'display
y res 1
hf res 1
hb res 1
vf res 1
vb res 1
hx res 1
vx res 1
hc2x res 1
screen res 1
tile res 1
pixels res 1
lineadd res 1
interlace res 1
hv res 1
hvbase res 1
h1 res 1
h2 res 1
'
'
' Parameter buffer
'
_enable res 1 '0/non-0 read-only
_pins res 1 '%pppttt read-only
_mode res 1 '%tihv read-only
_screen res 1 '@word read-only
_colors res 1 '@long read-only
_ht res 1 '1+ read-only
_vt res 1 '1+ read-only
_hx res 1 '1+ read-only
_vx res 1 '1+ read-only
_ho res 1 '0+- read-only
_vo res 1 '0+- read-only
_hd res 1 '1+ read-only
_hf res 1 '1+ read-only
_hs res 1 '1+ read-only
_hb res 1 '1+ read-only
_vd res 1 '1+ read-only
_vf res 1 '1+ read-only
_vs res 1 '1+ read-only
_vb res 1 '2+ read-only
_rate res 1 '500_000+ read-only
fit colortable 'fit underneath colortable ($180-$1BF)
''
''___
''VAR 'VGA parameters - 21 contiguous longs
''
'' long vga_status '0/1/2 = off/visible/invisible read-only
'' long vga_enable '0/non-0 = off/on write-only
'' long vga_pins '%pppttt = pins write-only
'' long vga_mode '%tihv = tile,interlace,hpol,vpol write-only
'' long vga_screen 'pointer to screen (words) write-only
'' long vga_colors 'pointer to colors (longs) write-only
'' long vga_ht 'horizontal tiles write-only
'' long vga_vt 'vertical tiles write-only
'' long vga_hx 'horizontal tile expansion write-only
'' long vga_vx 'vertical tile expansion write-only
'' long vga_ho 'horizontal offset write-only
'' long vga_vo 'vertical offset write-only
'' long vga_hd 'horizontal display ticks write-only
'' long vga_hf 'horizontal front porch ticks write-only
'' long vga_hs 'horizontal sync ticks write-only
'' long vga_hb 'horizontal back porch ticks write-only
'' long vga_vd 'vertical display lines write-only
'' long vga_vf 'vertical front porch lines write-only
'' long vga_vs 'vertical sync lines write-only
'' long vga_vb 'vertical back porch lines write-only
'' long vga_rate 'tick rate (Hz) write-only
''
''The preceding VAR section may be copied into your code.
''After setting variables, do start(@vga_status) to start driver.
''
''All parameters are reloaded each superframe, allowing you to make live
''changes. To minimize flicker, correlate changes with vga_status.
''
''Experimentation may be required to optimize some parameters.
''
''Parameter descriptions:
'' __________
'' vga_status
''
'' driver sets this to indicate status:
'' 0: driver disabled (vga_enable = 0 or CLKFREQ < 16MHz)
'' 1: currently outputting invisible sync data
'' 2: currently outputting visible screen data
'' __________
'' vga_enable
''
'' 0: disable (pins will be driven low, reduces power)
'' non-0: enable
'' ________
'' vga_pins
''
'' bits 5..3 select pin group:
'' %000: pins 7..0
'' %001: pins 15..8
'' %010: pins 23..16
'' %011: pins 31..24
'' %100: pins 39..32
'' %101: pins 47..40
'' %110: pins 55..48
'' %111: pins 63..56
''
'' bits 2..0 select top pin within group
'' for example: %01111 (15) will use pins %01000-%01111 (8-15)
'' ________
'' vga_mode
''
'' bit 3 selects between 16x16 and 16x32 pixel tiles:
'' 0: 16x16 pixel tiles (tileheight = 16)
'' 1: 16x32 pixel tiles (tileheight = 32)
''
'' bit 2 controls interlace:
'' 0: progressive scan (less flicker, good for motion, required for LCD monitors)
'' 1: interlaced scan (allows you to double vga_vt, good for text)
''
'' bits 1 and 0 select horizontal and vertical sync polarity, respectively
'' 0: active low
'' 1: active high
'' __________
'' vga_screen
''
'' pointer to words which define screen contents (left-to-right, top-to-bottom)
'' number of words must be vga_ht * vga_vt
'' each word has two bitfields: a 6-bit colorset ptr and a 10-bit pixelgroup ptr
'' bits 15..10: select the colorset* for the associated pixel tile
'' bits 9..0: select the pixelgroup** address %ppppppppppcccc00 (p=address, c=0..15)
''
'' * colorsets are longs which each define four 8-bit colors
''
'' ** pixelgroups are <tileheight> longs which define (left-to-right, top-to-bottom) the 2-bit
'' (four color) pixels that make up a 16x16 or a 16x32 pixel tile
'' __________
'' vga_colors
''
'' pointer to longs which define colorsets
'' number of longs must be 1..64
'' each long has four 8-bit fields which define colors for 2-bit (four color) pixels
'' first long's bottom color is also used as the screen background color
'' 8-bit color fields are as follows:
'' bits 7..2: actual state of pins 7..2 within pin group*
'' bits 1..0: don't care (used within driver for hsync and vsync)
''
'' * it is suggested that:
'' bits/pins 7..6 are used for red
'' bits/pins 5..4 are used for green
'' bits/pins 3..2 are used for blue
'' for each bit/pin set, sum 240 and 470-ohm resistors to form 75-ohm 1V signals
'' connect signal sets to RED, GREEN, and BLUE on VGA connector
'' always connect group pin 1 to HSYNC on VGA connector via 240-ohm resistor
'' always connect group pin 0 to VSYNC on VGA connector via 240-ohm resistor
'' ______
'' vga_ht
''
'' horizontal number of pixel tiles - must be at least 1
'' ______
'' vga_vt
''
'' vertical number of pixel tiles - must be at least 1
'' ______
'' vga_hx
''
'' horizontal tile expansion factor - must be at least 1
''
'' make sure 16 * vga_ht * vga_hx + ||vga_ho is equal to or at least 16 less than vga_hd
'' ______
'' vga_vx
''
'' vertical tile expansion factor - must be at least 1
''
'' make sure <tileheight> * vga_vt * vga_vx + ||vga_vo does not exceed vga_vd
'' (for interlace, use <tileheight> / 2 * vga_vt * vga_vx + ||vga_vo)
'' ______
'' vga_ho
''
'' horizontal offset in ticks - pos/neg value (0 recommended)
'' shifts the display right/left
'' ______
'' vga_vo
''
'' vertical offset in lines - pos/neg value (0 recommended)
'' shifts the display up/down
'' ______
'' vga_hd
''
'' horizontal display ticks
'' ______
'' vga_hf
''
'' horizontal front porch ticks
'' ______
'' vga_hs
''
'' horizontal sync ticks
'' ______
'' vga_hb
''
'' horizontal back porch ticks
'' ______
'' vga_vd
''
'' vertical display lines
'' ______
'' vga_vf
''
'' vertical front porch lines
'' ______
'' vga_vs
''
'' vertical sync lines
'' ______
'' vga_vb
''
'' vertical back porch lines
'' ________
'' vga_rate
''
'' tick rate in Hz
''
'' driver will limit value to be within 500KHz and 128MHz
'' pixel rate (vga_rate / vga_hx) should be no more than CLKFREQ / 4
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ TERMS OF USE: MIT License │
├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │
│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │
│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│
│is furnished to do so, subject to the following conditions: │
│ │
│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│
│ │
│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │
│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │
│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │
│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

View File

@@ -0,0 +1,737 @@
{{
┌───────────────────────────────────────────┬────────────────┬───────────────────────────────────┬─────────────────┐
│ Vocal Tract v1.1 │ by Chip Gracey │ Copyright (c) 2006 Parallax, Inc. │ 28 October 2006 │
├───────────────────────────────────────────┴────────────────┴───────────────────────────────────┴─────────────────┤
│ │
│ This object synthesizes a human vocal tract in real-time. It requires one cog and at least 80 MHz. │
│ │
│ The vocal tract is controlled via 13 single-byte parameters which must reside in the parent object: │
│ │
│ VAR byte aa,ga,gp,vp,vr,f1,f2,f3,f4,na,nf,fa,ff 'vocal tract parameters │
│ │
│ │
│ aa │
│ ┌────────────┐ │
│ │ ASPIRATION ├──┐ │
│ └────────────┘ │ f1 f2 f3 f4 na nf │
│  ┌────┐ ┌────┐ ┌────┐ ┌────┐ ┌───────┐ │
│ +┣──┤ F1 ├──┤ F2 ├──┤ F3 ├──┤ F4 ├──┤ NASAL ├──┐ │
│ ga gp  └────┘ └────┘ └────┘ └────┘ └───────┘ │ │
│ ┌─────────┐ │  │
│ │ GLOTTAL ├──┘ +┣── OUTPUT │
│ └────┬────┘ fa ff  │
│  ┌───────────┐ │ │
│ vp │ vr │ FRICATION ├──┘ │
│ ┌────┴────┐ └───────────┘ │
│ │ VIBRATO │ │
│ └─────────┘ │
│ │
│ │
│ ┌───────────┬──────────────────────┬─────────────┬────────────────────────────────────────────────┐ │
│ │ parameter │ description │ unit │ notes │ │
│ ├───────────┼──────────────────────┼─────────────┼────────────────────────────────────────────────┤ │
│ │ aa │ aspiration amplitude │ 0..255 │ breath volume: silent..loud, linear │ │
│ │ ga │ glottal amplitude │ 0..255 │ voice volume: silent..loud, linear │ │
│ │ gp │ glottal pitch │ 1/48 octave │ voice pitch: 100 ─ 110.00Hz (musical note A2) │ │
│ │ vp │ vibrato pitch │ 1/48 octave │ voice vibrato pitch: 48 ─ ± 1/2 octave swing │ │
│ │ vr │ vibrato rate │ 0.0763 Hz │ voice vibrato rate: 52 ─ 4 Hz │ │
│ │ f1 │ formant1 frequency │ 19.53 Hz │ 1st resonator frequency: 40 ─ 781 Hz │ │
│ │ f2 │ formant2 frequency │ 19.53 Hz │ 2nd resonator frequency: 56 ─ 1094 Hz │ │
│ │ f3 │ formant3 frequency │ 19.53 Hz │ 3rd resonator frequency: 128 ─ 2500 Hz │ │
│ │ f4 │ formant4 frequency │ 19.53 Hz │ 4th resonator frequency: 179 ─ 3496 Hz │ │
│ │ na │ nasal amplitude │ 0..255 │ anti-resonator level: off..on, linear │ │
│ │ nf │ nasal frequency │ 19.53 Hz │ anti-resonator frequency: 102 ─ 1992 Hz │ │
│ │ fa │ frication amplitude │ 0..255 │ white noise volume: silent..loud, linear │ │
│ │ ff │ frication frequency │ 39.06 Hz │ white noise frequency: 60 ─ 2344 Hz ("Sh") │ │
│ └───────────┴──────────────────────┴─────────────┴────────────────────────────────────────────────┘ │
│ │
│ The parent object alternately modifies one or more of these parameters and then calls the go(time) method to │
│ queue the entire 13-parameter frame for feeding to the vocal tract. The vocal tract will load one queued frame │
│ after another and smoothly interpolate between them over specified amounts of time without interruption. Up to │
│ eight frames will be queued in order to relax the frame-generation timing requirement of the parent object. If │
│ eight frames are queued, the parent must then wait to queue another frame. If the vocal tract runs out of │
│ frames, it will continue generating samples based on the last frame. When a new frame is queued, it will │
│ immediately load it and begin inter-polating towards it. │
│ │
│ The vocal tract generates audio samples at a continuous rate of 20KHz. These samples can be output to pins via │
│ delta-modulation for RC filtering or direct transducer driving. An FM aural subcarrier can also be generated for │
│ inclusion into a TV broadcast controlled by another cog. Regardless of any output mode, samples are always │
│ streamed into a special variable so that other objects can access them in real-time. │
│ │
│ In order to achieve optimal sound quality, it is worthwhile to maximize amplitudes such as 'ga' to the point │
│ just shy of numerical overflow. Numerical overflow results in high-amplitude noise bursts which are quite │
│ disruptive. The closeness of 'f1'-'f4' and their relationship to 'gp' can greatly influence the amount of 'ga' │
│ that can be applied before overflow occurs. You must determine through experimentation what the limits are. By │
│ pushing 'ga' close to the overflow point, you will maximize the signal-to-noise ratio of the vocal tract, │
│ resulting in the highest quality sound. Once your vocal tract programming is complete, the attenuation level │
│ can then be used to reduce the overall output in 3dB steps while preserving the signal-to-noise ratio. │
│ │
├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Revision History v1.0 released 26 October 2006 │
│ │
│ v1.1 If the vocal tract runs out of frames, its internal parameters will now be brought all the way to the │
│ last frame's values. Before, they were left one interpolation point shy, and then set to the last frame's │
│ values at the start of the next frame. For continuous frames this was trivial, but it posed a problem │
│ during frame gaps because the internal parameters would get stalled at transition points just shy of the │
│ last frame's values. This change makes the vocal tract behave more sensibly during frame gaps. │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}
CON
frame_buffers = 8 'frame buffers (2n)
frame_bytes = 3 {for stepsize} + 13 {for aa..ff} '16 bytes per frame
frame_longs = frame_bytes / 4 '4 longs per frame
frame_buffer_bytes = frame_bytes * frame_buffers
frame_buffer_longs = frame_longs * frame_buffers
VAR
long cog, tract, pace
long index, attenuation, sample '3 longs ...must
long dira_, dirb_, ctra_, ctrb_, frqa_, cnt_ '6 longs ...be
long frames[frame_buffer_longs] 'many longs ...contiguous
PUB start(tract_ptr, pos_pin, neg_pin, fm_offset) : okay
'' Start vocal tract driver - starts a cog
'' returns false if no cog available
''
'' tract_ptr = pointer to vocal tract parameters (13 bytes)
'' pos_pin = positive delta-modulation pin (-1 to disable)
'' neg_pin = negative delta-modulation pin (pos_pin must also be enabled, -1 to disable)
'' fm_offset = offset frequency for fm aural subcarrier generation (-1 to disable, 4_500_000 for NTSC)
'Reset driver
stop
'Remember vocal tract parameters pointer
tract := tract_ptr
'Initialize pace to 100%
pace := 100
'If delta-modulation pin(s) enabled, ready output(s) and ready ctrb for duty mode
if pos_pin > -1
dira_[pos_pin >> 5 & 1] |= |< pos_pin
ctrb_ := $18000000 + pos_pin & $3F
if neg_pin > -1
dira_[neg_pin >> 5 & 1] |= |< neg_pin
ctrb_ += $04000000 + (neg_pin & $3F) << 9
'If fm offset is valid, ready ctra for pll mode with divide-by-16 (else disabled)
if fm_offset > -1
ctra_ := $05800000
'Ready frqa value for fm offset
repeat 33
frqa_ <<= 1
if fm_offset => clkfreq
fm_offset -= clkfreq
frqa_++
fm_offset <<= 1
'Ready 20KHz sample period
cnt_ := clkfreq / 20_000
'Launch vocal tract cog
return cog := cognew(@entry, @attenuation) + 1
PUB stop
'' Stop vocal tract driver - frees a cog
'If already running, stop vocal tract cog
if cog
cogstop(cog~ - 1)
'Reset variables and buffers
longfill(@index, 0, constant(3 + 6 + frame_buffer_longs))
PUB set_attenuation(level)
'' Set master attenuation level (0..7, initially 0)
attenuation := level
PUB set_pace(percentage)
'' Set pace to some percentage (initially 100)
pace := percentage
PUB go(time)
'' Queue current parameters to transition over time
''
'' actual time = integer(time * 100 / pace) #> 2 * 700µs (at least 1400µs, see set_pace)
'Wait until frame available (first long will be zeroed)
repeat while frames[index]
'Load parameters into frame
bytemove(@frames[index] + 3, tract, 13)
'Write stepsize into frame (non-0 alerts vocal tract that frame is ready)
frames[index] |= $01000000 / (time * 100 / pace #> 2)
'Increment frame index
index := (index + frame_longs) & constant(frame_buffer_longs - 1)
PUB full : status
'' Returns true if the parameter queue is full
'' (useful for checking if "go" would have to wait)
return frames[index]
PUB empty : status | i
'' Returns true if the parameter queue is empty
'' (useful for detecting when the vocal tract is finished)
repeat i from 0 to constant(frame_buffers - 1)
if frames[i * frame_longs]
return {false}
return true
PUB sample_ptr : ptr
'' Returns the address of the long which receives the audio samples in real-time
'' (signed 32-bit values updated at 20KHz)
return @sample
PUB aural_id : id
'' Returns the id of the cog executing the vocal tract algorithm
'' (for connecting a broadcast tv driver with the aural subcarrier)
return cog - 1
DAT
' ┌──────────────────┐
' │ Initialization │
' └──────────────────┘
entry org
:zero mov reserves,#0 'zero all reserved data
add :zero,d0
djnz clear_cnt,#:zero
mov t1,#2*15 'assemble 15 multiply steps into reserves
:minst mov mult_steps,mult_step '(saves hub memory)
add :minst,d0s0
test t1,#1 wc
if_c sub :minst,#2
djnz t1,#:minst
mov mult_ret,antilog_ret 'write 'ret' after last instruction
mov t1,#13 'assemble 13 cordic steps into reserves
:cstep mov t2,#8 '(saves hub memory)
:cinst mov cordic_steps,cordic_step
add :cinst,d0s0
djnz t2,#:cinst
sub :cinst,#8
add cordic_dx,#1
add cordic_dy,#1
add cordic_a,#1
djnz t1,#:cstep
mov cordic_ret,antilog_ret 'write 'ret' over last instruction
mov t1,par 'get dira/dirb/ctra/ctrb
add t1,#2*4
mov t2,#4
:regs rdlong dira,t1
add t1,#4
add :regs,d0
djnz t2,#:regs
rdlong frqa_center,t1 'get frqa center
add t1,#4 'get cnt ticks
rdlong cnt_ticks,t1
mov cnt_value,cnt 'prepare for initial waitcnt
add cnt_value,cnt_ticks
' ┌────────────────────┐
' │ Vocal Tract Loop │
' └────────────────────┘
' Wait for next sample period, then output sample
loop waitcnt cnt_value,cnt_ticks 'wait for sample period
rdlong t1,par 'perform master attenuation
sar x,t1
mov t1,x 'update fm aural subcarrier for tv broadcast
sar t1,#10
add t1,frqa_center
mov frqa,t1
mov t1,x 'update duty cycle output for pin driving
add t1,h80000000
mov frqb,t1
mov t1,par 'update sample receiver in main memory
add t1,#1*4
wrlong x,t1
' White noise source
test lfsr,lfsr_taps wc 'iterate lfsr three times
rcl lfsr,#1
test lfsr,lfsr_taps wc
rcl lfsr,#1
test lfsr,lfsr_taps wc
rcl lfsr,#1
' Aspiration
mov t1,aa 'aspiration amplitude
mov t2,lfsr
call #mult
sar t1,#8 'set x
mov x,t1
' Vibrato
mov t1,vr 'vibrato rate
shr t1,#10
add vphase,t1
mov t1,vp 'vibrato pitch
mov t2,vphase
call #sine
add t1,gp 'sum glottal pitch (+) into vibrato pitch (+/-)
' Glottal pulse
shr t1,#2 'divide final pitch by 3 to mesh with
mov t2,t1 '...12 notes/octave musical scale
shr t2,#2 '(multiply by %0.0101010101010101)
add t1,t2
mov t2,t1
shr t2,#4
add t1,t2
mov t2,t1
shr t2,#8
add t1,t2
add t1,tune 'tune scale so that gp=100 produces 110.00Hz (A2)
call #antilog 'convert pitch (log frequency) to phase delta
add gphase,t2
mov t1,gphase 'convert phase to glottal pulse sample
call #antilog
sub t2,h40000000
mov t1,ga
call #sine
sar t1,#6 'add to x
add x,t1
' Vocal tract formants
mov y,#0 'reset y
mov a,f1 'formant1, sum and rotate (x,y)
add x,f1x
add y,f1y
call #cordic
mov f1x,x
mov f1y,y
mov a,f2 'formant2, sum and rotate (x,y)
add x,f2x
add y,f2y
call #cordic
mov f2x,x
mov f2y,y
mov a,f3 'formant3, sum and rotate (x,y)
add x,f3x
add y,f3y
call #cordic
mov f3x,x
mov f3y,y
mov a,f4 'formant4, sum and rotate (x,y)
add x,f4x
add y,f4y
call #cordic
mov f4x,x
mov f4y,y
' Nasal anti-formant
add nx,x 'subtract from x (nx negated)
mov a,nf 'nasal frequency
call #cordic
mov t1,na 'nasal amplitude
mov t2,x
call #mult
mov x,nx 'restore x
neg nx,t1 'negate nx
' Frication
mov t1,lfsr 'phase noise
sar t1,#3
add fphase,t1
sar t1,#1
add fphase,t1
mov t1,ff 'frication frequency
shr t1,#1
add fphase,t1
mov t1,fa 'frication amplitude
mov t2,fphase
call #sine
add x,t1 'add to x
' Handle frame
jmp :ret 'run segment of frame handler, return to loop
' ┌─────────────────┐
' │ Frame Handler │
' └─────────────────┘
:ret long :wait 'pointer to next frame handler routine
:wait jmpret :ret,#loop '(6 or 17.5 cycles)
mov frame_ptr,par 'check for next frame
add frame_ptr,#8*4 'point past miscellaneous data
add frame_ptr,frame_index 'point to start of frame
rdlong step_size,frame_ptr 'get stepsize
and step_size,h00FFFFFF wz 'isolate stepsize and check if not 0
if_nz jmp #:next 'if not 0, next frame ready
mov :final1,:finali 'no frame ready, ready to finalize parameters
mov frame_cnt,#13 'iterate aa..ff
:final jmpret :ret,#loop '(13.5 or 4 cycles)
:final1 mov par_curr,par_next 'current parameter = next parameter
add :final1,d0s0 'update pointers
djnz frame_cnt,#:final 'another parameter?
jmp #:wait 'check for next frame
:next add step_size,#1 'next frame ready, insure accurate accumulation
mov step_acc,step_size 'initialize step accumulator
movs :set1,#par_next 'ready to get parameters and steps for aa..ff
movd :set2,#par_curr
movd :set3,#par_next
movd :set4,#par_step
add frame_ptr,#3 'point to first parameter
mov frame_cnt,#13 'iterate aa..ff
:set jmpret :ret,#loop '(19.5 or 46.5 cycles)
rdbyte t1,frame_ptr 'get new parameter
shl t1,#24 'msb justify
:set1 mov t2,par_next 'get next parameter
:set2 mov par_curr,t2 'current parameter = next parameter
:set3 mov par_next,t1 'next parameter = new parameter
sub t1,t2 wc 'get next-current delta with sign in c
negc t1,t1 'make delta absolute (by c, not msb)
rcl vscl,#1 wz, nr 'save sign into nz (vscl unaffected)
mov t2,#8 'multiply delta by step size
:mult shl t1,#1 wc
if_c add t1,step_size
djnz t2,#:mult
:set4 negnz par_step,t1 'set signed step
add :set1,#1 'update pointers for next parameter+step
add :set2,d0
add :set3,d0
add :set4,d0
add frame_ptr,#1
djnz frame_cnt,#:set 'another parameter?
:stepframe jmpret :ret,#loop '(47.5 or 8 cycles)
mov :step1,:stepi 'ready to step parameters
mov frame_cnt,#13 'iterate aa..ff
:step jmpret :ret,#loop '(3 or 4 cycles)
:step1 add par_curr,par_step 'step parameter
add :step1,d0s0 'update pointers for next parameter+step
djnz frame_cnt,#:step 'another parameter?
add step_acc,step_size 'accumulate frame steps
test step_acc,h01000000 wc 'check for frame steps done
if_nc jmp #:stepframe 'another frame step?
sub frame_ptr,#frame_bytes 'zero stepsize in frame to signal frame done
wrlong vscl,frame_ptr
add frame_index,#frame_bytes'point to next frame
and frame_index,#frame_buffer_bytes - 1
jmp #:wait 'check for next frame
:finali mov par_curr,par_next 'instruction used to finalize parameters
:stepi add par_curr,par_step 'instruction used to step parameters
' ┌────────────────────┐
' │ Math Subroutines │
' └────────────────────┘
' Antilog
'
' in: t1 = log (top 4 bits = whole number, next 11 bits = fraction)
'
' out: t2 = antilog ($00010000..$FFEA0000)
antilog mov t2,t1
shr t2,#16 'position 11-bit fraction
shr t1,#16+12 'position 4-bit whole number
and t2,h00000FFE 'get table offset
or t2,h0000D000 'get table base
rdword t2,t2 'lookup fractional antilog
or t2,h00010000 'insert leading bit
shl t2,t1 'shift up by whole number
antilog_ret ret
' Scaled sine
'
' in: t1 = unsigned scale (15 top bits used)
' t2 = angle (13 top bits used)
'
' out: t1 = 17-bit * 15-bit scaled sine ($80014000..$7FFEC000)
sine shr t2,#32-13 'get 13-bit angle
test t2,h00001000 wz 'get sine quadrant 3|4 into nz
test t2,h00000800 wc 'get sine quadrant 2|4 into c
negc t2,t2 'if sine quadrant 2|4, negate table offset
or t2,h00007000 'insert sine table base address >> 1
shl t2,#1 'shift left to get final word address
rdword t2,t2 'read sine word from table
negnz t2,t2 'if quadrant 3|4, negate word
shl t2,#15 'msb-justify result
'multiply follows...
' Multiply
'
' in: t1 = unsigned multiplier (15 top bits used)
' t2 = signed multiplicand (17 top bits used)
'
' out: t1 = 32-bit signed product
mult shr t1,#32-15 'position unsigned multiplier
sar t2,#15 'position signed multiplicand
shl t2,#15-1
jmp #mult_steps 'do multiply steps
mult_step sar t1,#1 wc 'multiply step that gets assembled into reserves (x15)
if_c add t1,t2
' Cordic rotation
'
' in: a = 0 to <90 degree angle (~13 top bits used)
' x,y = signed coordinates
'
' out: x,y = scaled and rotated signed coordinates
cordic sar x,#1 'multiply (x,y) by %0.10011001 (0.60725 * 0.984)
mov t1,x '...for cordic pre-scaling and slight damping
sar t1,#3
add x,t1
mov t1,x
sar t1,#4
add x,t1
sar y,#1
mov t1,y
sar t1,#3
add y,t1
mov t1,y
sar t1,#4
add y,t1
mov t1,x 'do first cordic step
sub x,y
add y,t1
sub a,h80000000 wc
jmp #cordic_steps+1 'do subsequent cordic steps (skip first instruction)
cordic_step mov a,a wc 'cordic step that gets assembled into reserves (x13)
mov t1,y
cordic_dx sar t1,#1 '(source incremented for each step)
mov t2,x
cordic_dy sar t2,#1 '(source incremented for each step)
sumnc x,t1
sumc y,t2
cordic_a sumnc a,cordic_delta '(source incremented for each step)
' ┌────────────────┐
' │ Defined Data │
' └────────────────┘
tune long $66920000 'scale tuned to 110.00Hz at gp=100 (manually calibrated)
lfsr long 1 'linear feedback shift register for noise generation
lfsr_taps long $80061000
cordic_delta long $4B901476 'cordic angle deltas (first is h80000000)
long $27ECE16D
long $14444750
long $0A2C350C
long $05175F85
long $028BD879
long $0145F154
long $00A2F94D
long $00517CBB
long $0028BE60
long $00145F30
long $000A2F98
h80000000 long $80000000 'miscellaneous constants greater than 9 bits
h40000000 long $40000000
h01000000 long $01000000
h00FFFFFF long $00FFFFFF
h00010000 long $00010000
h0000D000 long $0000D000
h00007000 long $00007000
h00001000 long $00001000
h00000FFE long $00000FFE
h00000800 long $00000800
d0 long $00000200 'destination/source field increments
d0s0 long $00000201
clear_cnt long $1F0 - reserves 'number of reserved registers to clear on startup
' ┌──────────────────────────────────────────────────┐
' │ Undefined Data (zeroed by initialization code) │
' └──────────────────────────────────────────────────┘
reserves
frqa_center res 1 'reserved registers that get cleared on startup
cnt_ticks res 1
cnt_value res 1
frame_index res 1
frame_ptr res 1
frame_cnt res 1
step_size res 1
step_acc res 1
vphase res 1
gphase res 1
fphase res 1
f1x res 1
f1y res 1
f2x res 1
f2y res 1
f3x res 1
f3y res 1
f4x res 1
f4y res 1
nx res 1
a res 1
x res 1
y res 1
t1 res 1
t2 res 1
par_curr '*** current parameters
aa res 1 'aspiration amplitude
ga res 1 'glottal amplitude
gp res 1 'glottal pitch
vp res 1 'vibrato pitch
vr res 1 'vibrato rate
f1 res 1 'formant1 frequency
f2 res 1 'formant2 frequency
f3 res 1 'formant3 frequency
f4 res 1 'formant4 frequency
na res 1 'nasal amplitude
nf res 1 'nasal frequency
fa res 1 'frication amplitude
ff res 1 'frication frequency
par_next res 13 '*** next parameters
par_step res 13 '*** parameter steps
mult_steps res 2 * 15 'assembly area for multiply steps w/ret
mult_ret
sine_ret res 1
cordic_steps res 8 * 13 - 1 'assembly area for cordic steps w/ret
cordic_ret res 1
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ TERMS OF USE: MIT License │
├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │
│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │
│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│
│is furnished to do so, subject to the following conditions: │
│ │
│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│
│ │
│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │
│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │
│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │
│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

View File

@@ -0,0 +1,63 @@
"""
Additive Wave
by Daniel Shiffman.
Create a more complex wave by adding two waves together.
"""
xspacing = 8 # How far apart should each horizontal location be spaced
maxwaves = 4 # total # of waves to add together
theta = 0.0
amplitude = [] # Height of wave
# Value for incrementing X, to be calculated as a function of period and
# xspacing
dx = []
yvalues = []
def setup():
size(640, 360)
frameRate(30)
colorMode(RGB, 255, 255, 255, 100)
w = width + 16
for i in range(maxwaves):
amplitude.append(random(10, 30))
period = random(100, 300) # How many pixels before the wave repeats
dx.append((TWO_PI / period) * xspacing)
for _ in range(w / xspacing + 1):
yvalues.append(0.0)
def draw():
background(0)
calcWave()
renderWave()
def calcWave():
# Increment theta (try different values for 'angular velocity' here
theta += 0.02
# Set all height values to zero
for i in range(len(yvalues)):
yvalues[i] = 0
# Accumulate wave height values
for j in range(maxwaves):
x = theta
for i in range(len(yvalues)):
# Every other wave is cosine instead of sine
if j % 2 == 0:
yvalues[i] += sin(x) * amplitude[j]
else:
yvalues[i] += cos(x) * amplitude[j]
x += dx[j]
def renderWave():
# A simple way to draw the wave with an ellipse at each location
noStroke()
fill(255, 50)
ellipseMode(CENTER)
for x, v in enumerate(yvalues):
ellipse(x * xspacing, height / 2 + v, 16, 16)

View File

@@ -0,0 +1,241 @@
#
# Cinema 4D Python Plugin Source file
# https://github.com/nr-plugins/nr-xpresso-alignment-tools
#
# coding: utf-8
#
# Copyright (C) 2012, Niklas Rosenstein
# Licensed under the GNU General Public License
#
# XPAT - XPresso Alignment Tools
# ==============================
#
# The XPAT plugin provides tools for aligning nodes in the Cinema 4D
# XPresso Editor, improving readability of complex XPresso set-ups
# immensively.
#
# Requirements:
# - MAXON Cinema 4D R13+
# - Python `c4dtools` library. Get it from
# http://github.com/NiklasRosenstein/c4dtools
#
# Author: Niklas Rosenstein <rosensteinniklas@gmail.com>
# Version: 1.1 (01/06/2012)
import os
import sys
import json
import c4d
import c4dtools
import itertools
from c4d.modules import graphview as gv
from c4dtools.misc import graphnode
res, importer = c4dtools.prepare(__file__, __res__)
settings = c4dtools.helpers.Attributor({
'options_filename': res.file('config.json'),
})
def align_nodes(nodes, mode, spacing):
r"""
Aligns the passed nodes horizontally and apply the minimum spacing
between them.
"""
modes = ['horizontal', 'vertical']
if not nodes:
return
if mode not in modes:
raise ValueError('invalid mode, choices are: ' + ', '.join(modes))
get_0 = lambda x: x.x
get_1 = lambda x: x.y
set_0 = lambda x, v: setattr(x, 'x', v)
set_1 = lambda x, v: setattr(x, 'y', v)
if mode == 'vertical':
get_0, get_1 = get_1, get_0
set_0, set_1 = set_1, set_0
nodes = [graphnode.GraphNode(n) for n in nodes]
nodes.sort(key=lambda n: get_0(n.position))
midpoint = graphnode.find_nodes_mid(nodes)
# Apply the spacing between the nodes relative to the coordinate-systems
# origin. We can offset them later because we now the nodes' midpoint
# already.
first_position = nodes[0].position
new_positions = []
prev_offset = 0
for node in nodes:
# Compute the relative position of the node.
position = node.position
set_0(position, get_0(position) - get_0(first_position))
# Obtain it's size and check if the node needs to be re-placed.
size = node.size
if get_0(position) < prev_offset:
set_0(position, prev_offset)
prev_offset += spacing + get_0(size)
else:
prev_offset = get_0(position) + get_0(size) + spacing
set_1(position, get_1(midpoint))
new_positions.append(position)
# Center the nodes again.
bbox_size = prev_offset - spacing
bbox_size_2 = bbox_size * 0.5
for node, position in itertools.izip(nodes, new_positions):
# TODO: Here is some issue with offsetting the nodes. Some value
# dependent on the spacing must be added here to not make the nodes
# move horizontally/vertically although they have already been
# aligned.
set_0(position, get_0(midpoint) + get_0(position) - bbox_size_2 + spacing)
node.position = position
def align_nodes_shortcut(mode, spacing):
master = gv.GetMaster(0)
if not master:
return
root = master.GetRoot()
if not root:
return
nodes = graphnode.find_selected_nodes(root)
if nodes:
master.AddUndo()
align_nodes(nodes, mode, spacing)
c4d.EventAdd()
return True
class XPAT_Options(c4dtools.helpers.Attributor):
r"""
This class organizes the options for the XPAT plugin, i.e.
validating, loading and saving.
"""
defaults = {
'hspace': 50,
'vspace': 20,
}
def __init__(self, filename=None):
super(XPAT_Options, self).__init__()
self.load(filename)
def load(self, filename=None):
r"""
Load the options from file pointed to by filename. If filename
is None, it defaults to the filename defined in options in the
global scope.
"""
if filename is None:
filename = settings.options_filename
if os.path.isfile(filename):
self.dict_ = self.defaults.copy()
with open(filename, 'rb') as fp:
self.dict_.update(json.load(fp))
else:
self.dict_ = self.defaults.copy()
self.save()
def save(self, filename=None):
r"""
Save the options defined in XPAT_Options instance to HD.
"""
if filename is None:
filename = settings.options_filename
values = dict((k, v) for k, v in self.dict_.iteritems()
if k in self.defaults)
with open(filename, 'wb') as fp:
json.dump(values, fp)
class XPAT_OptionsDialog(c4d.gui.GeDialog):
r"""
This class implements the behavior of the XPAT options dialog,
taking care of storing the options on the HD and loading them
again on startup.
"""
# c4d.gui.GeDialog
def CreateLayout(self):
return self.LoadDialogResource(res.DLG_OPTIONS)
def InitValues(self):
self.SetLong(res.EDT_HSPACE, options.hspace)
self.SetLong(res.EDT_VSPACE, options.vspace)
return True
def Command(self, id, msg):
if id == res.BTN_SAVE:
options.hspace = self.GetLong(res.EDT_HSPACE)
options.vspace = self.GetLong(res.EDT_VSPACE)
options.save()
self.Close()
return True
class XPAT_Command_OpenOptionsDialog(c4dtools.plugins.Command):
r"""
This Cinema 4D CommandData plugin opens the XPAT options dialog
when being executed.
"""
def __init__(self):
super(XPAT_Command_OpenOptionsDialog, self).__init__()
self._dialog = None
@property
def dialog(self):
if not self._dialog:
self._dialog = XPAT_OptionsDialog()
return self._dialog
# c4dtools.plugins.Command
PLUGIN_ID = 1029621
PLUGIN_NAME = res.string.XPAT_COMMAND_OPENOPTIONSDIALOG()
PLUGIN_HELP = res.string.XPAT_COMMAND_OPENOPTIONSDIALOG_HELP()
# c4d.gui.CommandData
def Execute(self, doc):
return self.dialog.Open(c4d.DLG_TYPE_MODAL)
class XPAT_Command_AlignHorizontal(c4dtools.plugins.Command):
PLUGIN_ID = 1029538
PLUGIN_NAME = res.string.XPAT_COMMAND_ALIGNHORIZONTAL()
PLUGIN_ICON = res.file('xpresso-align-h.png')
PLUGIN_HELP = res.string.XPAT_COMMAND_ALIGNHORIZONTAL_HELP()
def Execute(self, doc):
align_nodes_shortcut('horizontal', options.hspace)
return True
class XPAT_Command_AlignVertical(c4dtools.plugins.Command):
PLUGIN_ID = 1029539
PLUGIN_NAME = res.string.XPAT_COMMAND_ALIGNVERTICAL()
PLUGIN_ICON = res.file('xpresso-align-v.png')
PLUGIN_HELP = res.string.XPAT_COMMAND_ALIGNVERTICAL_HELP()
def Execute(self, doc):
align_nodes_shortcut('vertical', options.vspace)
return True
options = XPAT_Options()
if __name__ == '__main__':
c4dtools.plugins.main()

View File

@@ -0,0 +1,29 @@
"""
* Move Eye.
* by Simon Greenwold.
*
* The camera lifts up (controlled by mouseY) while looking at the same point.
"""
def setup():
size(640, 360, P3D)
fill(204)
def draw():
lights()
background(0)
# Change height of the camera with mouseY
camera(30.0, mouseY, 220.0, # eyeX, eyeY, eyeZ
0.0, 0.0, 0.0, # centerX, centerY, centerZ
0.0, 1.0, 0.0) # upX, upY, upZ
noStroke()
box(90)
stroke(255)
line(-100, 0, 0, 100, 0, 0)
line(0, -100, 0, 0, 100, 0)
line(0, 0, -100, 0, 0, 100)

30
samples/QMake/complex.pro Normal file
View File

@@ -0,0 +1,30 @@
# This QMake file is complex, as it usese
# boolean operators and function calls
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
# We could use some OpenGL right now
contains(QT_CONFIG, opengl) | contains(QT_CONFIG, opengles2) {
QT += opengl
} else {
DEFINES += QT_NO_OPENGL
}
TEMPLATE = app
win32 {
TARGET = BlahApp
RC_FILE = Resources/winres.rc
}
!win32 { TARGET = blahapp }
# Let's add a PRI file!
include(functions.pri)
SOURCES += file.cpp
HEADERS += file.h
FORMS += file.ui
RESOURCES += res.qrc

View File

@@ -0,0 +1,8 @@
# QMake include file that calls some functions
# and does nothing else...
exists(.git/HEAD) {
system(git rev-parse HEAD >rev.txt)
} else {
system(echo ThisIsNotAGitRepo >rev.txt)
}

View File

@@ -0,0 +1,2 @@
#!/usr/bin/qmake
message(This is QMake.)

17
samples/QMake/simple.pro Normal file
View File

@@ -0,0 +1,17 @@
# Simple QMake file
CONFIG += qt
QT += core gui
TEMPLATE = app
TARGET = simpleapp
SOURCES += file.cpp \
file2.c \
This/Is/Folder/file3.cpp
HEADERS += file.h \
file2.h \
This/Is/Folder/file3.h
FORMS += This/Is/Folder/file3.ui \
Test.ui

29
samples/R/df.residual.r Normal file
View File

@@ -0,0 +1,29 @@
df.residual.mira <- function(object, ...) {
fit <- object$analyses[[1]]
return(df.residual(fit))
}
df.residual.lme <- function(object, ...) {
return(object$fixDF[["X"]][1])
}
df.residual.mer <- function(object, ...) {
return(sum(object@dims[2:4] * c(1, -1, -1)) + 1)
}
df.residual.default <- function(object, q = 1.3, ...) {
df <- object$df.residual
if (!is.null(df))
return(df)
mk <- try(c <- coef(object), silent = TRUE)
mn <- try(f <- fitted(object), silent = TRUE)
if (inherits(mk, "try-error") | inherits(mn, "try-error"))
return(NULL)
n <- ifelse(is.data.frame(f) | is.matrix(f), nrow(f), length(f))
k <- length(c)
if (k == 0 | n == 0)
return(NULL)
return(max(1, n - q * k))
}

101
samples/R/filenames/expr-dist Executable file
View File

@@ -0,0 +1,101 @@
#!/usr/bin/env Rscript
# Copyright (c) 2013 Daniel S. Standage, released under MIT license
#
# expr-dist: plot distributions of expression values before and after
# normalization; visually confirm that normalization worked
# as expected
#
# Program input is a matrix of expression values, each row corresponding to a
# molecule (gene, transcript, etc) and each row corresponding to that molecule's
# expression level or abundance. The program expects the rows and columns to be
# named, and was tested primarily on output produced by the
# 'rsem-generate-data-matrix' script distributed with the RSEM package.
#
# The program plots the distributions of the logged expression values by sample
# as provided, then normalizes the values, and finally plots the distribution of
# the logged normalized expression values by sample. The expectation is that all
# samples' distributions will have a similar shape but different medians prior
# to normalization, and that post normalization they will all have an identical
# median to facilitate cross-sample comparison.
# MedianNorm function borrowed from the EBSeq library version 1.1.6
# See http://www.bioconductor.org/packages/devel/bioc/html/EBSeq.html
MedianNorm <- function(data)
{
geomeans <- exp( rowMeans(log(data)) )
apply(data, 2, function(cnts) median((cnts/geomeans)[geomeans > 0]))
}
library("getopt")
print_usage <- function(file=stderr())
{
cat("
expr-dist: see source code for full description
Usage: expr-dist [options] < expr-matrix.txt
Options:
-h|--help: print this help message and exit
-o|--out: STRING prefix for output files; default is 'expr-dist'
-r|--res: INT resolution (dpi) of generated graphics; default is 150
-t|--height: INT height (pixels) of generated graphics; default is 1200
-w|--width: INT width (pixels) of generated graphics; default is 1200
-y|--ylim: REAL the visible range of the Y axis depends on the first
distribution plotted; if other distributions are getting
cut off, use this setting to override the default\n\n")
}
spec <- matrix( c("help", 'h', 0, "logical",
"out", 'o', 1, "character",
"res", 'r', 1, "integer",
"height", 't', 1, "integer",
"width", 'w', 1, "integer",
"ylim", 'y', 1, "double"),
byrow=TRUE, ncol=4)
opt <- getopt(spec)
if(!is.null(opt$help))
{
print_usage(file=stdout())
q(status=1)
}
if(is.null(opt$height)) { opt$height <- 1200 }
if(is.null(opt$out)) { opt$out <- "expr-dist" }
if(is.null(opt$res)) { opt$res <- 150 }
if(is.null(opt$width)) { opt$width <- 1200 }
if(!is.null(opt$ylim)) { opt$ylim <- c(0, opt$ylim) }
# Load data, determine number of samples
data <- read.table(file("stdin"), header=TRUE, sep="\t", quote="")
nsamp <- dim(data)[2] - 1
data <- data[,1:nsamp+1]
# Plot distribution of expression values before normalization
outfile <- sprintf("%s-median.png", opt$out)
png(outfile, height=opt$height, width=opt$width, res=opt$res)
h <- hist(log(data[,1]), plot=FALSE)
plot(h$mids, h$density, type="l", col=rainbow(nsamp)[1], main="",
xlab="Log expression value", ylab="Proportion of molecules", ylim=opt$ylim)
for(i in 2:nsamp)
{
h <- hist(log(data[,i]), plot=FALSE)
lines(h$mids, h$density, col=rainbow(nsamp)[i])
}
devnum <- dev.off()
# Normalize by median
size.factors <- MedianNorm(data.matrix(data))
data.norm <- t(apply(data, 1, function(x){ x / size.factors }))
# Plot distribution of normalized expression values
outfile <- sprintf("%s-median-norm.png", opt$out)
png(outfile, height=opt$height, width=opt$width, res=opt$res)
h <- hist(log(data.norm[,1]), plot=FALSE)
plot(h$mids, h$density, type="l", col=rainbow(nsamp)[1], main="",
xlab="Log normalized expression value", ylab="Proportion of molecules",
ylim=opt$ylim)
for(i in 2:nsamp)
{
h <- hist(log(data.norm[,i]), plot=FALSE)
lines(h$mids, h$density, col=rainbow(nsamp)[i])
}
devnum <- dev.off()

201
samples/R/import.r Normal file
View File

@@ -0,0 +1,201 @@
#' Import a module into the current scope
#'
#' \code{module = import('module')} imports a specified module and makes its
#' code available via the environment-like object it returns.
#'
#' @param module an identifier specifying the full module path
#' @param attach if \code{TRUE}, attach the newly loaded module to the object
#' search path (see \code{Details})
#' @param attach_operators if \code{TRUE}, attach operators of module to the
#' object search path, even if \code{attach} is \code{FALSE}
#' @return the loaded module environment (invisible)
#'
#' @details Modules are loaded in an isolated environment which is returned, and
#' optionally attached to the object search path of the current scope (if
#' argument \code{attach} is \code{TRUE}).
#' \code{attach} defaults to \code{FALSE}. However, in interactive code it is
#' often helpful to attach packages by default. Therefore, in interactive code
#' invoked directly from the terminal only (i.e. not within modules),
#' \code{attach} defaults to the value of \code{options('import.attach')}, which
#' can be set to \code{TRUE} or \code{FALSE} depending on the users preference.
#'
#' \code{attach_operators} causes \emph{operators} to be attached by default,
#' because operators can only be invoked in R if they re found in the search
#' path. Not attaching them therefore drastically limits a modules usefulness.
#'
#' Modules are searched in the module search path \code{options('import.path')}.
#' This is a vector of paths to consider, from the highest to the lowest
#' priority. The current directory is \emph{always} considered first. That is,
#' if a file \code{a.r} exists both in the current directory and in a module
#' search path, the local file \code{./a.r} will be loaded.
#'
#' Module names can be fully qualified to refer to nested paths. See
#' \code{Examples}.
#'
#' @note Unlike for packages, attaching happens \emph{locally}: if
#' \code{import} is executed in the global environment, the effect is the same.
#' Otherwise, the imported module is inserted as the parent of the current
#' \code{environment()}. When used (globally) \emph{inside} a module, the newly
#' imported module is only available inside the modules search path, not
#' outside it (nor in other modules which might be loaded).
#'
#' @examples
#' # `a.r` is a file in the local directory containing a function `f`.
#' a = import('a')
#' a$f()
#'
#' # b/c.r is a file in path `b`, containing a function `g`.
#' import('b/c', attach = TRUE)
#' g() # No module name qualification necessary
#'
#' @seealso \code{unload}
#' @seealso \code{reload}
#' @seealso \code{module_name}
#' @export
import = function (module, attach, attach_operators = TRUE) {
module = substitute(module)
stopifnot(inherits(module, 'name'))
if (missing(attach)) {
attach = if (interactive() && is.null(module_name()))
getOption('import.attach', FALSE)
else
FALSE
}
stopifnot(class(attach) == 'logical' && length(attach) == 1)
module_path = try(find_module(module), silent = TRUE)
if (inherits(module_path, 'try-error'))
stop(attr(module_path, 'condition')$message)
containing_modules = module_init_files(module, module_path)
mapply(do_import, names(containing_modules), containing_modules)
mod_ns = do_import(as.character(module), module_path)
module_parent = parent.frame()
mod_env = exhibit_namespace(mod_ns, as.character(module), module_parent)
if (attach) {
if (identical(module_parent, .GlobalEnv))
attach(mod_env, name = environmentName(mod_env))
else
parent.env(module_parent) = mod_env
}
else if (attach_operators)
export_operators(mod_ns, module_parent)
invisible(mod_env)
}
do_import = function (module_name, module_path) {
if (is_module_loaded(module_path))
return(get_loaded_module(module_path))
# The namespace contains a modules content. This schema is very much like
# R package organisation.
# A good resource for this is:
# <http://obeautifulcode.com/R/How-R-Searches-And-Finds-Stuff/>
namespace = structure(new.env(parent = .BaseNamespaceEnv),
name = paste('namespace', module_name, sep = ':'),
path = module_path,
class = c('namespace', 'environment'))
local(source(attr(environment(), 'path'), chdir = TRUE, local = TRUE),
envir = namespace)
cache_module(namespace)
namespace
}
exhibit_namespace = function (namespace, name, parent) {
exported_functions = lsf.str(namespace)
# Skip one parent environment because this module is hooked into the chain
# between the calling environment and its ancestor, thus sitting in its
# local object search path.
structure(list2env(sapply(exported_functions, get, envir = namespace),
parent = parent.env(parent)),
name = paste('module', name, sep = ':'),
path = module_path(namespace),
class = c('module', 'environment'))
}
export_operators = function (namespace, parent) {
# `$` cannot be overwritten, but it is generic so S3 variants of it can be
# defined. We therefore test it as well.
ops = c('+', '-', '*', '/', '^', '**', '&', '|', ':', '::', ':::', '$', '=',
'<-', '<<-', '==', '<', '<=', '>', '>=', '!=', '~', '&&', '||')
is_predefined = function (f) f %in% ops
is_op = function (f) {
prefix = strsplit(f, '\\.')[[1]][1]
is_predefined(prefix) || grepl('^%.*%$', prefix)
}
operators = Filter(is_op, lsf.str(namespace))
name = module_name(namespace)
# Skip one parent environment because this module is hooked into the chain
# between the calling environment and its ancestor, thus sitting in its
# local object search path.
op_env = structure(list2env(sapply(operators, get, envir = namespace),
parent = parent.env(parent)),
name = paste('operators', name, sep = ':'),
path = module_path(namespace),
class = c('module', 'environment'))
if (identical(parent, .GlobalEnv))
attach(op_env, name = environmentName(op_env))
else
parent.env(parent) = op_env
}
#' Unload a given module
#'
#' Unset the module variable that is being passed as a parameter, and remove the
#' loaded module from cache.
#' @param module reference to the module which should be unloaded
#' @note Any other references to the loaded modules remain unchanged, and will
#' still work. However, subsequently importing the module again will reload its
#' source files, which would not have happened without \code{unload}.
#' Unloading modules is primarily useful for testing during development, and
#' should not be used in production code.
#'
#' \code{unload} does not currently detach environments.
#' @seealso \code{import}
#' @seealso \code{reload}
#' @export
unload = function (module) {
stopifnot(inherits(module, 'module'))
module_ref = as.character(substitute(module))
rm(list = module_path(module), envir = .loaded_modules)
# unset the module reference in its scope, i.e. the callers environment or
# some parent thereof.
rm(list = module_ref, envir = parent.frame(), inherits = TRUE)
}
#' Reload a given module
#'
#' Remove the loaded module from the cache, forcing a reload. The newly reloaded
#' module is assigned to the module reference in the calling scope.
#' @param module reference to the module which should be unloaded
#' @note Any other references to the loaded modules remain unchanged, and will
#' still work. Reloading modules is primarily useful for testing during
#' development, and should not be used in production code.
#'
#' \code{reload} does not work correctly with attached environments.
#' @seealso \code{import}
#' @seealso \code{unload}
#' @export
reload = function (module) {
stopifnot(inherits(module, 'module'))
module_ref = as.character(substitute(module))
module_path = module_path(module)
module_name = module_name(module)
rm(list = module_path, envir = .loaded_modules)
#' @TODO Once we have `attach`, need also to take care of the search path
#' and whatnot.
mod_ns = do_import(module_name, module_path)
module_parent = parent.frame()
mod_env = exhibit_namespace(mod_ns, module_ref, module_parent)
assign(module_ref, mod_env, envir = module_parent, inherits = TRUE)
}

25
samples/R/scholar.Rd Normal file
View File

@@ -0,0 +1,25 @@
\docType{package}
\name{scholar}
\alias{scholar}
\alias{scholar-package}
\title{scholar}
\source{
The package reads data from
\url{http://scholar.google.com}. Dates and citation
counts are estimated and are determined automatically by
a computer program. Use at your own risk.
}
\description{
The \code{scholar} package provides functions to extract
citation data from Google Scholar. There are also
convenience functions for comparing multiple scholars and
predicting h-index scores based on past publication
records.
}
\note{
A complementary set of Google Scholar functions can be
found at
\url{http://biostat.jhsph.edu/~jleek/code/googleCite.r}.
The \code{scholar} package was developed independently.
}

257
samples/Red/example.red Normal file
View File

@@ -0,0 +1,257 @@
Red [
Title: "Red console"
Author: ["Nenad Rakocevic" "Kaj de Vos"]
File: %console.red
Tabs: 4
Rights: "Copyright (C) 2012-2013 Nenad Rakocevic. All rights reserved."
License: {
Distributed under the Boost Software License, Version 1.0.
See https://github.com/dockimbel/Red/blob/master/BSL-License.txt
}
Purpose: "Just some code for testing Pygments colorizer"
Language: http://www.red-lang.org/
]
#system-global [
#either OS = 'Windows [
#import [
"kernel32.dll" stdcall [
AttachConsole: "AttachConsole" [
processID [integer!]
return: [integer!]
]
SetConsoleTitle: "SetConsoleTitleA" [
title [c-string!]
return: [integer!]
]
ReadConsole: "ReadConsoleA" [
consoleInput [integer!]
buffer [byte-ptr!]
charsToRead [integer!]
numberOfChars [int-ptr!]
inputControl [int-ptr!]
return: [integer!]
]
]
]
line-buffer-size: 16 * 1024
line-buffer: allocate line-buffer-size
][
#switch OS [
MacOSX [
#define ReadLine-library "libreadline.dylib"
]
#default [
#define ReadLine-library "libreadline.so.6"
#define History-library "libhistory.so.6"
]
]
#import [
ReadLine-library cdecl [
read-line: "readline" [ ; Read a line from the console.
prompt [c-string!]
return: [c-string!]
]
rl-bind-key: "rl_bind_key" [
key [integer!]
command [integer!]
return: [integer!]
]
rl-insert: "rl_insert" [
count [integer!]
key [integer!]
return: [integer!]
]
]
#if OS <> 'MacOSX [
History-library cdecl [
add-history: "add_history" [ ; Add line to the history.
line [c-string!]
]
]
]
]
rl-insert-wrapper: func [
[cdecl]
count [integer!]
key [integer!]
return: [integer!]
][
rl-insert count key
]
]
]
Windows?: system/platform = 'Windows
read-argument: routine [
/local
args [str-array!]
str [red-string!]
][
if system/args-count <> 2 [
SET_RETURN(none-value)
exit
]
args: system/args-list + 1 ;-- skip binary filename
str: simple-io/read-txt args/item
SET_RETURN(str)
]
init-console: routine [
str [string!]
/local
ret
][
#either OS = 'Windows [
;ret: AttachConsole -1
;if zero? ret [print-line "ReadConsole failed!" halt]
ret: SetConsoleTitle as c-string! string/rs-head str
if zero? ret [print-line "SetConsoleTitle failed!" halt]
][
rl-bind-key as-integer tab as-integer :rl-insert-wrapper
]
]
input: routine [
prompt [string!]
/local
len ret str buffer line
][
#either OS = 'Windows [
len: 0
print as c-string! string/rs-head prompt
ret: ReadConsole stdin line-buffer line-buffer-size :len null
if zero? ret [print-line "ReadConsole failed!" halt]
len: len + 1
line-buffer/len: null-byte
str: string/load as c-string! line-buffer len
][
line: read-line as c-string! string/rs-head prompt
if line = null [halt] ; EOF
#if OS <> 'MacOSX [add-history line]
str: string/load line 1 + length? line
; free as byte-ptr! line
]
SET_RETURN(str)
]
count-delimiters: function [
buffer [string!]
return: [block!]
][
list: copy [0 0]
c: none
foreach c buffer [
case [
escaped? [
escaped?: no
]
in-comment? [
switch c [
#"^/" [in-comment?: no]
]
]
'else [
switch c [
#"^^" [escaped?: yes]
#";" [if zero? list/2 [in-comment?: yes]]
#"[" [list/1: list/1 + 1]
#"]" [list/1: list/1 - 1]
#"{" [list/2: list/2 + 1]
#"}" [list/2: list/2 - 1]
]
]
]
]
list
]
do-console: function [][
buffer: make string! 10000
prompt: red-prompt: "red>> "
mode: 'mono
switch-mode: [
mode: case [
cnt/1 > 0 ['block]
cnt/2 > 0 ['string]
'else [
prompt: red-prompt
do eval
'mono
]
]
prompt: switch mode [
block ["[^-"]
string ["{^-"]
mono [red-prompt]
]
]
eval: [
code: load/all buffer
unless tail? code [
set/any 'result do code
unless unset? :result [
if 67 = length? result: mold/part :result 67 [ ;-- optimized for width = 72
clear back tail result
append result "..."
]
print ["==" result]
]
]
clear buffer
]
while [true][
unless tail? line: input prompt [
append buffer line
cnt: count-delimiters buffer
either Windows? [
remove skip tail buffer -2 ;-- clear extra CR (Windows)
][
append buffer lf ;-- Unix
]
switch mode [
block [if cnt/1 <= 0 [do switch-mode]]
string [if cnt/2 <= 0 [do switch-mode]]
mono [do either any [cnt/1 > 0 cnt/2 > 0][switch-mode][eval]]
]
]
]
]
q: :quit
if script: read-argument [
script: load script
either any [
script/1 <> 'Red
not block? script/2
][
print "*** Error: not a Red program!"
][
do skip script 2
]
quit
]
init-console "Red Console"
print {
-=== Red Console alpha version ===-
(only ASCII input supported)
}
do-console

124
samples/Red/example.reds Normal file
View File

@@ -0,0 +1,124 @@
Red/System [
Title: "Red/System example file"
Purpose: "Just some code for testing Pygments colorizer"
Language: http://www.red-lang.org/
]
#include %../common/FPU-configuration.reds
; C types
#define time! long!
#define clock! long!
date!: alias struct! [
second [integer!] ; 0-61 (60?)
minute [integer!] ; 0-59
hour [integer!] ; 0-23
day [integer!] ; 1-31
month [integer!] ; 0-11
year [integer!] ; Since 1900
weekday [integer!] ; 0-6 since Sunday
yearday [integer!] ; 0-365
daylight-saving-time? [integer!] ; Negative: unknown
]
#either OS = 'Windows [
#define clocks-per-second 1000
][
; CLOCKS_PER_SEC value for Syllable, Linux (XSI-conformant systems)
; TODO: check for other systems
#define clocks-per-second 1000'000
]
#import [LIBC-file cdecl [
; Error handling
form-error: "strerror" [ ; Return error description.
code [integer!]
return: [c-string!]
]
print-error: "perror" [ ; Print error to standard error output.
string [c-string!]
]
; Memory management
make: "calloc" [ ; Allocate zero-filled memory.
chunks [size!]
size [size!]
return: [binary!]
]
resize: "realloc" [ ; Resize memory allocation.
memory [binary!]
size [size!]
return: [binary!]
]
]
JVM!: alias struct! [
reserved0 [int-ptr!]
reserved1 [int-ptr!]
reserved2 [int-ptr!]
DestroyJavaVM [function! [[JNICALL] vm [JVM-ptr!] return: [jint!]]]
AttachCurrentThread [function! [[JNICALL] vm [JVM-ptr!] penv [struct! [p [int-ptr!]]] args [byte-ptr!] return: [jint!]]]
DetachCurrentThread [function! [[JNICALL] vm [JVM-ptr!] return: [jint!]]]
GetEnv [function! [[JNICALL] vm [JVM-ptr!] penv [struct! [p [int-ptr!]]] version [integer!] return: [jint!]]]
AttachCurrentThreadAsDaemon [function! [[JNICALL] vm [JVM-ptr!] penv [struct! [p [int-ptr!]]] args [byte-ptr!] return: [jint!]]]
]
;just some datatypes for testing:
#some-hash
10-1-2013
quit
;binary:
#{00FF0000}
#{00FF0000 FF000000}
#{00FF0000 FF000000} ;with tab instead of space
2#{00001111}
64#{/wAAAA==}
64#{/wAAA A==} ;with space inside
64#{/wAAA A==} ;with tab inside
;string with char
{bla ^(ff) foo}
{bla ^(( foo}
;some numbers:
12
1'000
1.2
FF00FF00h
;some tests of hexa number notation with not common ending
[ff00h ff00h] ff00h{} FFh"foo" 00h(1 + 2) (AEh)
;normal words:
foo char
;get-word
:foo
;lit-word:
'foo 'foo
to-integer foo
foo/(a + 1)/b
call/output reform ['which interpreter] path: copy ""
version-1.1: 00010001h
#if type = 'exe [
push system/stack/frame ;-- save previous frame pointer
system/stack/frame: system/stack/top ;-- @@ reposition frame pointer just after the catch flag
]
push CATCH_ALL ;-- exceptions root barrier
push 0 ;-- keep stack aligned on 64-bit

View File

@@ -0,0 +1,19 @@
Pry.config.commands.import Pry::ExtendedCommands::Experimental
Pry.config.pager = false
Pry.config.color = false
Pry.config.commands.alias_command "lM", "ls -M"
Pry.config.commands.command "add", "Add a list of numbers together" do |*args|
output.puts "Result is: #{args.map(&:to_i).inject(&:+)}"
end
Pry.config.history.should_save = false
Pry.config.prompt = [proc { "input> " },
proc { " | " }]
# Disable pry-buggy-plug:
Pry.plugins["buggy-plug"].disable!

17
samples/SAS/data.sas Normal file
View File

@@ -0,0 +1,17 @@
/* Example DATA step code for linguist */
libname source 'C:\path\to\file'
data work.working_copy;
set source.original_file.sas7bdat;
run;
data work.working_copy;
set work.working_copy;
if Purge = 1 then delete;
run;
data work.working_copy;
set work.working_copy;
if ImportantVariable = . then MissingFlag = 1;
run;

15
samples/SAS/proc.sas Normal file
View File

@@ -0,0 +1,15 @@
/* PROC examples for Linguist */
proc surveyselect data=work.data out=work.boot method=urs reps=20000 seed=2156 sampsize=28 outhits;
samplingunit Site;
run;
PROC MI data=work.boot out=work.bootmi nimpute=30 seed=5686 round = 1;
By Replicate;
VAR Variable1 Variable2;
run;
proc logistic data=work.bootmi descending;
By Replicate _Imputation_;
model Outcome = Variable1 Variable2 / risklimits;
run;

View File

@@ -0,0 +1,19 @@
IF EXISTS (SELECT * FROM DBO.SYSOBJECTS WHERE ID = OBJECT_ID(N'dbo.AvailableInSearchSel') AND OBJECTPROPERTY(id, N'IsProcedure') = 1)
DROP PROCEDURE dbo.AvailableInSearchSel
GO
CREATE Procedure AvailableInSearchSel
AS
SELECT '-1',
'Select...'
UNION ALL
SELECT '1',
'Yes'
UNION ALL
SELECT '0',
'No'
GO
IF DB_NAME() = 'Diebold' BEGIN
GRANT EXECUTE ON dbo.AvailableInSearchSel TO [rv]
END
GO

225
samples/SQL/db.sql Normal file
View File

@@ -0,0 +1,225 @@
SHOW WARNINGS;
--
-- Table structure for table `articles`
--
CREATE TABLE IF NOT EXISTS `articles` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) DEFAULT NULL,
`content` longtext,
`date_posted` datetime NOT NULL,
`created_by` varchar(255) NOT NULL,
`last_modified` datetime DEFAULT NULL,
`last_modified_by` varchar(255) DEFAULT NULL,
`ordering` int(10) DEFAULT '0',
`is_published` int(1) DEFAULT '1',
PRIMARY KEY (`id`)
);
--
-- Dumping data for table `articles`
--
INSERT INTO `articles` (`title`, `content`, `date_posted`, `created_by`, `last_modified`, `last_modified_by`, `ordering`, `is_published`) VALUES
('Welcome', '<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed interdum, felis ac pellentesque feugiat, massa enim sagittis elit, sed dignissim sem ligula non nisl. Sed pulvinar nunc nec eros aliquet non tempus diam vehicula. Nunc tincidunt, leo ut interdum tristique, quam ligula porttitor tellus, at tincidunt magna enim nec arcu. Nunc tempor egestas libero. Vivamus nulla ligula, vehicula vitae mattis quis, laoreet eget urna. Proin eget est quis urna venenatis dictum nec vel lectus. Nullam sit amet vehicula leo. Sed commodo, orci vitae facilisis accumsan, arcu justo sagittis risus, quis aliquet purus neque eu odio. Mauris lectus orci, tincidunt in varius quis, dictum sed nibh. Quisque dapibus mollis blandit. Donec vel tellus nisl, sed scelerisque felis. Praesent ut eros tortor, sed molestie nunc. Duis eu massa at justo iaculis gravida.</p>\r\n<p>In adipiscing dictum risus a tincidunt. Sed nisi ipsum, rutrum sed ornare in, bibendum at augue. Integer ornare semper varius. Integer luctus vehicula elementum. Donec cursus elit quis erat laoreet elementum. Praesent eget justo purus, vitae accumsan massa. Ut tristique, mauris non dignissim luctus, velit justo sollicitudin odio, vel rutrum purus enim eu felis. In adipiscing elementum sagittis. Nam sed dui ante. Nunc laoreet hendrerit nisl vitae porta. Praesent sit amet ligula et nisi vulputate volutpat. Maecenas venenatis iaculis sapien sit amet auctor. Curabitur euismod venenatis velit non tempor. Cras vel sapien purus, mollis fermentum nulla. Mauris sed elementum enim. Donec ultrices urna at justo adipiscing rutrum.</p>', '2012-08-09 01:19:59', 'admin',NULL, NULL, 0, 1);
-- --------------------------------------------------------
--
-- Table structure for table `challenges`
--
CREATE TABLE IF NOT EXISTS `challenges` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) DEFAULT NULL,
`pkg_name` varchar(255) NOT NULL,
`description` text,
`author` varchar(255) NOT NULL,
`category` varchar(255) NOT NULL,
`date_posted` datetime NOT NULL,
`visibility` varchar(255) DEFAULT 'private',
`publish` int(10) DEFAULT '0',
`abstract` varchar(255) DEFAULT NULL,
`level` varchar(255) DEFAULT NULL,
`duration` int(11) DEFAULT NULL,
`goal` varchar(255) DEFAULT NULL,
`solution` varchar(255) DEFAULT NULL,
`availability` varchar(255) DEFAULT 'private',
`default_points` int(11) DEFAULT NULL,
`default_duration` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
);
--
-- Dumping data for table `challenges`
--
INSERT INTO `challenges` (`title`, `pkg_name`, `description`, `author`, `category`, `date_posted`, `visibility`, `publish`, `abstract`, `level`, `duration`, `goal`, `solution`, `availability`, `default_points`, `default_duration`) VALUES
('Challenge 1', 'ch001', 'Our agents (hackers) informed us that there reasonable suspicion \r\nthat the site of this <a href="ch001/" target="_blank">Logistics Company</a> is a blind \r\nfor a human organs'' smuggling organisation.<br /> <br /> This organisation attracts its \r\nvictims through advertisments for jobs with very high salaries. They choose those ones who \r\ndo not have many relatives, they assasinate them and then sell their organs to very rich \r\nclients, at very high prices.<br /> <br /> These employees are registered in the secret \r\nfiles of the company as "special clients"!<br /> <br /> One of our agents has been hired \r\nas by the particular company. Unfortunately, since 01/01/2007 he has gone missing.<br /> \r\n<br /> We know that our agent is alive, but we cannot contact him. Last time he \r\ncommunicated with us, he mentioned that we could contact him at the e-mail address the \r\ncompany has supplied him with, should there a problem arise.<br /> <br /> The problem is \r\nthat when we last talked to him, he had not a company e-mail address yet, but he told us \r\nthat his e-mail can be found through the company''s site. <br /> <br /> The only thing we \r\nremember is that he was hired on Friday the 13th! <br /> <br /> You have to find his e-mail \r\naddress and send it to us by using the central communication panel of the company''s \r\nsite.<br /> <br /> Good luck!!!', 'Andreas Venieris,\n Konstantinos Papapanagiotou,\n \n Anastasios Stasinopoulos,\n Vasilios Vlachos,\n Alexandros \nPapanikolaou', 'web', '2012-08-09 00:23:14', 'public', 1, NULL, '1', 60, NULL, NULL, 'public', 1, 60),
('Challenge 2', 'ch002', 'Your Country needs your help for finding the password of an enemy \r\n\r\nsite that contains useful information, which if is not acquired on time, peace in our \r\n\r\narea will be at stake.<br /> <br />\n You must therefore succeed in finding the \r\n\r\npassword of this military <a href="ch002/index.php" target="_blank">SITE</a>.<br /> <br \r\n\r\n/> Good luck!', 'Andreas Venieris,\n Konstantinos Papapanagiotou,\n Anastasios \r\n\r\nStasinopoulos,\n Vasilios Vlachos,\n Alexandros Papanikolaou', 'web', '0000-00-00 00:00:00', 'public', 1, NULL, '1', 60, NULL, NULL, 'public', 1, 60),
('Challenge 3', 'ch003', 'XSS permits a malevolent user to inject his own code in vulnerable \r\n\r\nweb pages. According to the OWASP 2010 Top 10 Application Security Risks, XSS attacks \r\n\r\nrank 2nd in the "most dangerous" list.<br /> <br /> Your objective is to make an alert \r\n\r\nbox appear <a href="ch003/index.php" target="_blank">HERE</a> bearing the message: \r\n\r\n"<strong>XSS!</strong>".', 'Andreas Venieris,\n Konstantinos Papapanagiotou,\n \r\n\r\n Anastasios Stasinopoulos,\n Vasilios Vlachos,\n Alexandros \r\n\r\nPapanikolaou', 'web', '2012-08-09 00:24:46', 'public', 1, NULL, '1', 60, NULL, NULL, 'public', 1, 60),
('Challenge 4', 'ch004', 'A hacker informed us that <a href="ch004/index.php" target=\r\n\r\n"_blank">this</a> site suffers from an XSS-like type of vulnerability. Unfortunately, he \r\n\r\nlost the notes he had written regarding how exactly did he exploit the aforementioned \r\n\r\nvulnerability.<br /> Your objective is to make an alert box appear, bearing the message \r\n\r\n"<strong>XSS!</strong>". It should be noted, however, that this site has some protection \r\n\r\nagainst such attacks.', 'Andreas Venieris,\n Konstantinos Papapanagiotou,\n \r\n\r\nAnastasios Stasinopoulos,\n Vasilios Vlachos,\n Alexandros \r\n\r\nPapanikolaou', 'web', '2012-08-09 00:25:25', 'public', 1, NULL, '1', 60, NULL, NULL, 'public', 1, 60),
('Challenge 5', 'ch005', 'You need to get access to the contents of this <a href=\r\n\r\n"ch005/index.php" target="_blank">SITE</a>. In order to achieve this, however, you \r\n\r\nmust buy the "p0wnBrowser" web browser. Since it is too expensive, you will have to \r\n\r\n"fool" the system in some way, so that it let you read the site''s contents.', 'Andreas \r\n\r\nVenieris,\n Konstantinos Papapanagiotou,\n Anastasios Stasinopoulos,\n \r\n\r\nVasilios Vlachos,\n Alexandros Papanikolaou', 'web', '2012-08-09 00:26:09', 'public', 1, NULL, '1', 60, NULL, NULL, 'public', 1, 60),
('Challenge 6', 'ch006', 'In this assignment you must prove your... knightly skills! Real \r\n\r\nknights have not disappeared.They still exist, keeping their secrets well hidden.<br /> \r\n\r\nYour mission is to infiltrate their <a href="ch006/index.php" target="_blank">SITE</a>. \r\n\r\nThere is a small problem, however... We don''t know the password!<br /> Perhaps you could \r\n\r\nfind it?<br /> Let''s see!<br /> g00d luck dudes!', 'Andreas Venieris,\n Konstantinos \r\n\r\nPapapanagiotou,\n Anastasios Stasinopoulos,\n Vasilios Vlachos,\n \r\n\r\nAlexandros Papanikolaou', 'web', '2012-08-09 00:26:52', 'public', 1, NULL, '1', 60, NULL, NULL, 'public', 1, 60),
('Challenge 7', 'ch007', 'A good friend of mine studies at Acme University, in the <a href=\r\n\r\n"ch007/index.php" target="_blank">Computer Science and Telecomms Department</a>. \r\n\r\nUnfortunately, her grades are not that good. You are now thinking "This is big news!"... \r\n\r\nHmmm, maybe not. What is big news, however, is this: The network administrator asked for \r\n\r\n3,000 euros to change her marks into A''s. This is obviously a case of administrative \r\n\r\nauthority abuse. Hence... a good chance for D-phase and public exposure...<br /> I need to \r\n\r\nget into the site as admin and upload an index.htm file in the web-root directory, that \r\n\r\nwill present all required evidence for the University''s latest "re-marking" practices!\r\n\r\n<br /> I only need you to find the admin password for me...<br /> <br /> Good \r\n\r\nLuck!', 'Andreas Venieris,\n Konstantinos Papapanagiotou,\n Anastasios \r\n\r\nStasinopoulos,\n Vasilios Vlachos,\n Alexandros Papanikolaou', 'web', '0000-00-00 00:00:00', 'public', 1, NULL, '1', 60, NULL, NULL, 'public', 1, 60),
('Challenge 8', 'ch008', 'You have managed, after several tries, to install a backdoor shell \r\n\r\n(Locus7Shell) to <a href="ch008/" target="_blank">trytohack.gr<br /></a> <br /> The \r\n\r\nproblem is that, in order to execute the majority of the commands (on the machine running \r\n\r\nthe backdoor) you must have super-user rights (root).<br /> <br /> Your aim is to obtain \r\n\r\nroot rights.', 'Andreas Venieris,\n Konstantinos Papapanagiotou,\n Anastasios \r\n\r\nStasinopoulos,\n Vasilios Vlachos,\n Alexandros Papanikolaou', 'web', '0000-00-00 00:00:00', 'public', 1, NULL, '1', 60, NULL, NULL, 'public', 1, 60),
('Challenge 9', 'ch009', 'A friend of yours has set up a news blog at <a href=\r\n\r\n"ch009/index.php" target="_blank">slagoff.com</a>. However, he is kind of worried \r\n\r\nregarding the security of the news that gets posted on the blog and has asked you to check \r\n\r\nhow secure it is.<br /> <br /> Your objective is to determine whether any vulnerabilities \r\n\r\nexist that, if exploited, can grant access to the blog''s server.<br /> <br /> Hint: A \r\n\r\nspecially-tailored backdoor shell can be found at "<a href=\r\n\r\n"http://www.really_nasty_hacker.com/shell.txt" target="_blank\r\n\r\n">http://www.really_nasty_hacker.com/shell.txt</a>".', 'Andreas Venieris,\n \r\n\r\nKonstantinos Papapanagiotou,\n Anastasios Stasinopoulos,\n Vasilios Vlachos,\r\n\r\n\n Alexandros Papanikolaou', 'web', '2012-08-09 00:31:31', 'public', 1, NULL, '1', 60, NULL, NULL, 'public', 1, 60),
('Challenge 10', 'ch010', 'Would you like to become an active hacker ?<br /> How about \r\n\r\nbecoming a member of the world''s largest hacker group:<br /> The n1nJ4.n4x0rZ.CreW!<br /> \r\n\r\n<br /> Before you can join though, you ''ll have to prove yourself worthy by passing the \r\n\r\ntest that can be found at: <a href="ch010/" target="_blank\r\n\r\n">http://n1nj4h4x0rzcr3w.com</a><br /> <br /> If you succeed in completing the challenge, \r\n\r\nyou will get a serial number, which you will use for obtaining the password that will \r\n\r\nenable you to join the group.<br /> <br /> Your objective is to bypass the authentication \r\n\r\nmechanism, find the serial number and be supplied with your own username and password from \r\n\r\n the admin team of the site.', 'Andreas Venieris,\n Konstantinos Papapanagiotou,\n \r\n\r\n Anastasios Stasinopoulos,\n Vasilios Vlachos,\n Alexandros \r\n\r\nPapanikolaou', 'web', '2012-08-09 00:32:07', 'public', 1, NULL, '1', 60, NULL, NULL, 'public', 1, 60),
('Example Template For Challenge xml Files creation', 'example', '<p>Insert some text describing the scenario of the challenge(what the users are supposed to do and if there is any fictional story)</p>', 'Name or email or both', 'In what category does your challenge belong?(web? crypto? networks?)', '2012-10-16 22:35:01', 'private', 0, NULL, '1', 60, NULL, NULL, 'private', 1, 0),
('cookiEng', 'cookiEng', '<p>Hello, we have heard that you are one of the best hackers in our country. We need your services.<br>You must visit an underground site and find<br> the right password. With this password we will cancel 100k+ illegal gun and drug deals!\n The good news are that we have the directory where the password is stored. Its here \\\"/t0psec.php\\\".\n The bad news are that we have no access there. Only the administrator does. Go and find the password for us!<br><br><br>Good luck!</p>', 'Nikos Danopoulos', 'web', '2012-08-09 00:32:07', 'public', 1, NULL, '1', 60, NULL, NULL, 'public', 1, 60),
('Izon Challenge', 'izon', '<p>After the mysterious disappearance of your best friend, you are contacted by an unknown individual who claims to have information about your friend. This individual identifies himself as \"Mister Jax\" and claims that is a former colleague of your friend.</p><p>Your friend was working at Izon Corporation, a weapons manufactured and government contractor as a systems engineer. Mister Jax didn\'t tell you his role in Izon, but wants you to pass through a series of tests to infiltrate Izon\'s web security to find the truth about your friend</p><p>After much consideration you agree with Mister Jax and he, remotely, sets up your computer to look like as if it is a part of Izon\'s Virtual Private Network in order to access their site. He also said that he\'ll guide you while you work your way to uncover the truth about your lost friend</p><p>Here is a copy of Mister Jax\'s last email:</p><p><pre>The task is simple: You get in, get your information and get out.\r\nYour friend was either a dumb programmer or a brilliant one, he left\r\nmany holes to be exploited in order to gain higher access to the site.\r\nI\'ll be guiding you with tips while you try to hack through Izon\'s site.\r\nThere are four tasks, some related to each other, some not.\r\nYou need to use your skills to overcome the obstacles, knowledge will come along.\r\nSixty minutes will suffice. When they\'re over, I won\'t be able to offer any\r\ncover to you, and you\'ll be compromised, with unknown consequences, I\'m afraid.\r\nI\'ll be seeing you there.\r\n\r\ - Jax</pre></p> <p>Once you get in, you\'ll have sixty minutes to complete this challenge. Use common sense, remember that the most obvious place hides the most important stuff and try to behave as if you were hacking a real system.</p><p>Good Luck!</p>', 'Vasileios Mplanas', 'web', '2014-03-27 00:00:00', 'public', 1, NULL, '1', 60, NULL, NULL, 'public', 10, 60);
-- --------------------------------------------------------
--
-- Table structure for table `challenge_attempts`
--
CREATE TABLE IF NOT EXISTS `challenge_attempts` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`challenge_id` int(11) NOT NULL,
`time` datetime NOT NULL,
`status` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
);
-- --------------------------------------------------------
--
-- Table structure for table `challenge_attempt_count`
--
CREATE TABLE IF NOT EXISTS `challenge_attempt_count` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`challenge_id` int(11) NOT NULL,
`tries` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `user_id` (`user_id`),
UNIQUE KEY `challenge_id` (`challenge_id`)
);
-- --------------------------------------------------------
--
-- Table structure for table `classes`
--
CREATE TABLE IF NOT EXISTS `classes` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`date_created` datetime NOT NULL,
`archive` int(1) DEFAULT '0',
PRIMARY KEY (`id`)
);
--
-- Dumping data for table `classes`
--
INSERT INTO `classes` (`name`, `date_created`, `archive`) VALUES
('Sample Class', '2012-08-09 00:43:48', 0),
('fooClass', '2012-10-16 22:32:43', 0);
-- --------------------------------------------------------
--
-- Table structure for table `class_challenges`
--
CREATE TABLE IF NOT EXISTS `class_challenges` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`challenge_id` int(11) NOT NULL,
`class_id` int(11) NOT NULL,
`date_created` datetime NOT NULL,
PRIMARY KEY (`id`)
);
--
-- Dumping data for table `class_challenges`
--
INSERT INTO `class_challenges` (`challenge_id`, `class_id`, `date_created`) VALUES
(1, 1, '2012-08-09 01:01:07'),
(2, 1, '2012-08-09 01:01:07'),
(3, 1, '2012-08-09 01:01:07'),
(4, 1, '2012-08-09 01:01:07'),
(5, 1, '2012-08-09 01:01:07'),
(6, 1, '2012-08-09 01:01:07'),
(7, 1, '2012-08-09 01:01:07'),
(9, 1, '2012-08-09 01:01:07'),
(10, 1, '2012-08-09 01:01:07'),
(1, 2, '2012-10-16 22:32:49'),
(4, 2, '2012-10-16 22:32:52'),
(9, 2, '2012-10-16 22:32:53'),
(10, 2, '2012-10-16 22:32:55'),
(8, 2, '2012-10-16 22:32:58');
-- --------------------------------------------------------
--
-- Table structure for table `class_memberships`
--
CREATE TABLE IF NOT EXISTS `class_memberships` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`class_id` int(11) NOT NULL,
`date_created` datetime NOT NULL,
PRIMARY KEY (`user_id`,`class_id`),
UNIQUE KEY `id` (`id`)
);
--
-- Dumping data for table `class_memberships`
--
INSERT INTO `class_memberships` (`user_id`, `class_id`, `date_created`) VALUES
( 1, 1, '2012-08-09 00:59:00'),
( 2, 1, '2012-08-09 00:59:00'),
( 3, 1, '2012-08-09 00:59:00'),
( 4, 2, '2012-10-16 22:33:07'),
( 5, 2, '2012-10-16 22:33:13');
-- --------------------------------------------------------
--
-- Table structure for table `users`
--
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(255) NOT NULL,
`full_name` varchar(255) NOT NULL,
`email` varchar(100) NOT NULL,
`password` varchar(255) NOT NULL,
`joined` datetime NOT NULL,
`last_visit` datetime DEFAULT NULL,
`is_activated` int(1) DEFAULT '0',
`type` int(10) DEFAULT '0',
`token` int(10) DEFAULT '0',
PRIMARY KEY (`username`),
UNIQUE KEY `id` (`id`)
);
--
-- Dumping data for table `users`
--
INSERT INTO `users` (`username`, `full_name`, `email`, `password`, `joined`, `last_visit`, `is_activated`, `type`, `token`) VALUES
('bar', 'mr. bar', 'bar@owasp.com', '$P$BJ8UtXZYqS/Lokm8zFMwcxO8dq797P.', '2012-10-16 22:12:52', '2012-10-16 22:22:39', 0, 0, 0),
('foo', 'mr. foo', 'foo@owasp.com', '$P$BxCHeVG1RMF06UxwRbrVQtPA1yOwAq.', '2012-10-16 22:12:34', '2012-10-16 22:59:29', 0, 0, 0),
('sensei', 'waspy sifu', 'waspy@owasp.sifu', '$P$Bj/JtLJJR3bUD0LLWXL2UW9DuRVo0I.', '2012-10-16 22:36:06', '2012-10-16 22:37:04', 1, 2, 0);
--
-- Table structure for table `user_has_challenge_token`
--
DROP TABLE IF EXISTS `user_has_challenge_token`;
CREATE TABLE IF NOT EXISTS `user_has_challenge_token` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` varchar(512) NOT NULL,
`challenge_id` varchar(512) NOT NULL,
`token` varchar(256) NOT NULL,
PRIMARY KEY (`id`)
);
SHOW WARNINGS;

22
samples/SQL/filial.tab Normal file
View File

@@ -0,0 +1,22 @@
create table FILIAL
(
id NUMBER not null,
title_ua VARCHAR2(128) not null,
title_ru VARCHAR2(128) not null,
title_eng VARCHAR2(128) not null,
remove_date DATE,
modify_date DATE,
modify_user VARCHAR2(128)
)
;
alter table FILIAL
add constraint PK_ID primary key (ID);
grant select on FILIAL to ATOLL;
grant select on FILIAL to CRAMER2GIS;
grant select on FILIAL to DMS;
grant select on FILIAL to HPSM2GIS;
grant select on FILIAL to PLANMONITOR;
grant select on FILIAL to SIEBEL;
grant select on FILIAL to VBIS;
grant select on FILIAL to VPORTAL;

View File

@@ -0,0 +1,8 @@
if not exists(select * from sysobjects where name = '%object_name%' and type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
exec('create FUNCTION dbo.%object_name%() returns int as begin return null end')
GO
%object_ddl%
go

View File

@@ -0,0 +1,6 @@
use translog;
DROP VIEW IF EXISTS `suspendedtoday`;
create view suspendedtoday as
select * from suspended
where datediff(datetime, now()) = 0;

Some files were not shown because too many files have changed in this diff Show More