Merge branch 'master' into 675-local

Conflicts:
	.gitignore
	lib/linguist/languages.yml
	lib/linguist/samples.json
This commit is contained in:
Arfon Smith
2014-06-20 12:22:58 +01:00
443 changed files with 117062 additions and 2411 deletions

3
.gitignore vendored
View File

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

View File

@@ -1,8 +1,9 @@
before_install: sudo apt-get install libicu-dev -y
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
- ree
- 2.0.0
- 2.1.1
notifications:
disabled: true

View File

@@ -1,4 +1,4 @@
Copyright (c) 2011-2013 GitHub, Inc.
Copyright (c) 2011-2014 GitHub, Inc.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation

View File

@@ -1,18 +1,17 @@
# Linguist
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.
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.
## Features
### Language detection
Linguist defines the list of all languages known to GitHub in a [yaml file](https://github.com/github/linguist/blob/master/lib/linguist/languages.yml). In order for a file to be highlighted, a language and lexer must be defined there.
Linguist defines a list of all languages known to GitHub in a [yaml file](https://github.com/github/linguist/blob/master/lib/linguist/languages.yml). In order for a file to be highlighted, a language and a lexer must be defined there.
Most languages are detected by their file extension. This is the fastest and most common situation.
For disambiguating between files with common extensions, we use a [Bayesian classifier](https://github.com/github/linguist/blob/master/lib/linguist/classifier.rb). For an example, this helps us tell the difference between `.h` files which could be either C, C++, or Obj-C.
In the actual GitHub app we deal with `Grit::Blob` objects. For testing, there is a simple `FileBlob` API.
Most languages are detected by their file extension. For disambiguating between files with common extensions, we first apply some common-sense heuristics to pick out obvious languages. After that, we use a
[statistical
classifier](https://github.com/github/linguist/blob/master/lib/linguist/classifier.rb).
This process can help us tell the difference between, for example, `.h` files which could be either C, C++, or Obj-C.
```ruby
@@ -27,13 +26,11 @@ See [lib/linguist/language.rb](https://github.com/github/linguist/blob/master/li
The actual syntax highlighting is handled by our Pygments wrapper, [pygments.rb](https://github.com/tmm1/pygments.rb). It also provides a [Lexer abstraction](https://github.com/tmm1/pygments.rb/blob/master/lib/pygments/lexer.rb) that determines which highlighter should be used on a file.
We typically run on a pre-release version of Pygments, [pygments.rb](https://github.com/tmm1/pygments.rb), to get early access to new lexers. The [languages.yml](https://github.com/github/linguist/blob/master/lib/linguist/languages.yml) file is a dump of the lexers we have available on our server.
### Stats
The Language Graph you see on every repository is built by aggregating the languages of all repo's blobs. The top language in the graph determines the project's primary language. Collectively, these stats make up the [Top Languages](https://github.com/languages) page.
The Language stats bar that you see on every repository is built by aggregating the languages of each file in that repository. The top language in the graph determines the project's primary language.
The repository stats API can be used on a directory:
The repository stats API, accessed through `#languages`, can be used on a directory:
```ruby
project = Linguist::Repository.from_directory(".")
@@ -41,10 +38,27 @@ project.language.name #=> "Ruby"
project.languages #=> { "Ruby" => 0.98, "Shell" => 0.02 }
```
These stats are also printed out by the binary. Try running `linguist` on itself:
These stats are also printed out by the `linguist` binary. You can use the
`--breakdown` flag, and the binary will also output the breakdown of files by language.
$ bundle exec linguist lib/
100% Ruby
You can try running `linguist` on the `lib/` directory in this repository itself:
$ bundle exec linguist lib/ --breakdown
100.00% Ruby
Ruby:
linguist/blob_helper.rb
linguist/classifier.rb
linguist/file_blob.rb
linguist/generated.rb
linguist/heuristics.rb
linguist/language.rb
linguist/md5.rb
linguist/repository.rb
linguist/samples.rb
linguist/tokenizer.rb
linguist.rb
#### Ignore vendored files
@@ -82,14 +96,60 @@ To run the tests:
## Contributing
The majority of patches won't need to touch any Ruby code at all. The [master language list](https://github.com/github/linguist/blob/master/lib/linguist/languages.yml) is just a configuration file.
The majority of contributions won't need to touch any Ruby code at all. The [master language list](https://github.com/github/linguist/blob/master/lib/linguist/languages.yml) is just a YAML configuration file.
We try to only add languages once they have a some usage on GitHub, so please note in-the-wild usage examples in your pull request.
We try to only add languages once they have some usage on GitHub, so please note in-the-wild usage examples in your pull request.
Almost all bug fixes or new language additions should come with some additional code samples. Just drop them under [`samples/`](https://github.com/github/linguist/tree/master/samples) in the correct subdirectory and our test suite will automatically test them. In most cases you shouldn't need to add any new assertions.
To update the `samples.json` after adding new files to [`samples/`](https://github.com/github/linguist/tree/master/samples):
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.
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,5 +1,7 @@
require 'json'
require 'rake/clean'
require 'rake/testtask'
require 'yaml'
task :default => :test
@@ -13,6 +15,13 @@ task :samples do
File.open('lib/linguist/samples.json', 'w') { |io| io.write json }
end
task :build_gem do
languages = YAML.load_file("lib/linguist/languages.yml")
File.write("lib/linguist/languages.json", JSON.dump(languages))
`gem build github-linguist.gemspec`
File.delete("lib/linguist/languages.json")
end
namespace :classifier do
LIMIT = 1_000

View File

@@ -1,19 +1,39 @@
#!/usr/bin/env ruby
# linguist — detect language type for a file, or, given a directory, determine language breakdown
#
# usage: linguist <path>
# usage: linguist <path> [<--breakdown>]
require 'linguist/file_blob'
require 'linguist/repository'
path = ARGV[0] || Dir.pwd
# special case if not given a directory but still given the --breakdown option
if path == "--breakdown"
path = Dir.pwd
breakdown = true
end
ARGV.shift
breakdown = true if ARGV[0] == "--breakdown"
if File.directory?(path)
repo = Linguist::Repository.from_directory(path)
repo.languages.sort_by { |_, size| size }.reverse.each do |language, size|
percentage = ((size / repo.size.to_f) * 100).round
puts "%-4s %s" % ["#{percentage}%", language]
percentage = ((size / repo.size.to_f) * 100)
percentage = sprintf '%.2f' % percentage
puts "%-7s %s" % ["#{percentage}%", language]
end
if breakdown
puts
file_breakdown = repo.breakdown_by_file
file_breakdown.each do |lang, files|
puts "#{lang}:"
files.each do |file|
puts file
end
puts
end
end
elsif File.file?(path)
blob = Linguist::FileBlob.new(path, Dir.pwd)

View File

@@ -1,20 +1,25 @@
require File.expand_path('../lib/linguist/version', __FILE__)
Gem::Specification.new do |s|
s.name = 'github-linguist'
s.version = '2.9.4'
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.'
s.authors = "GitHub"
s.homepage = "https://github.com/github/linguist"
s.license = "MIT"
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.2'
s.add_development_dependency 'mocha'
s.add_dependency 'pygments.rb', '~> 0.6.0'
s.add_development_dependency 'json'
s.add_development_dependency 'mocha'
s.add_development_dependency 'rake'
s.add_development_dependency 'yajl-ruby'
end

View File

@@ -1,5 +1,7 @@
require 'linguist/blob_helper'
require 'linguist/generated'
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
@@ -190,9 +196,9 @@ module Linguist
# Public: Is the blob safe to colorize?
#
# We use Pygments for syntax highlighting blobs. Pygments
# can be too slow for very large blobs or for certain
# can be too slow for very large blobs or for certain
# corner-case blobs.
#
#
# Return true or false
def safe_to_colorize?
!large? && text? && !high_ratio_of_long_lines?
@@ -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

@@ -15,8 +15,8 @@ module Linguist
#
# Returns nothing.
#
# Set LINGUIST_DEBUG=1 or =2 to see probabilities per-token,
# per-language. See also dump_all_tokens, below.
# Set LINGUIST_DEBUG=1 or =2 to see probabilities per-token or
# per-language. See also #dump_all_tokens, below.
def self.train!(db, language, data)
tokens = Tokenizer.tokenize(data)
@@ -78,18 +78,13 @@ module Linguist
def classify(tokens, languages)
return [] if tokens.nil?
tokens = Tokenizer.tokenize(tokens) if tokens.is_a?(String)
scores = {}
if verbosity >= 2
dump_all_tokens(tokens, languages)
end
debug_dump_all_tokens(tokens, languages) if verbosity >= 2
languages.each do |language|
scores[language] = tokens_probability(tokens, language) +
language_probability(language)
if verbosity >= 1
printf "%10s = %10.3f + %7.3f = %10.3f\n",
language, tokens_probability(tokens, language), language_probability(language), scores[language]
end
scores[language] = tokens_probability(tokens, language) + language_probability(language)
debug_dump_probabilities(tokens, language, scores[language]) if verbosity >= 1
end
scores.sort { |a, b| b[1] <=> a[1] }.map { |score| [score[0], score[1]] }
@@ -135,6 +130,11 @@ module Linguist
@verbosity ||= (ENV['LINGUIST_DEBUG'] || 0).to_i
end
def debug_dump_probabilities(tokens, language, score)
printf("%10s = %10.3f + %7.3f = %10.3f\n",
language, tokens_probability(tokens, language), language_probability(language), score)
end
# Internal: show a table of probabilities for each <token,language> pair.
#
# The number in each table entry is the number of "points" that each
@@ -145,22 +145,22 @@ module Linguist
# how much more likely (log of probability ratio) that token is to
# appear in one language vs. the least-likely language. Dashes
# indicate the least-likely language (and zero points) for each token.
def dump_all_tokens(tokens, languages)
def debug_dump_all_tokens(tokens, languages)
maxlen = tokens.map { |tok| tok.size }.max
printf "%#{maxlen}s", ""
puts " #" + languages.map { |lang| sprintf("%10s", lang) }.join
tokmap = Hash.new(0)
tokens.each { |tok| tokmap[tok] += 1 }
tokmap.sort.each { |tok, count|
token_map = Hash.new(0)
tokens.each { |tok| token_map[tok] += 1 }
token_map.sort.each { |tok, count|
arr = languages.map { |lang| [lang, token_probability(tok, lang)] }
min = arr.map { |a,b| b }.min
minlog = Math.log(min)
if !arr.inject(true) { |result, n| result && n[1] == arr[0][1] }
printf "%#{maxlen}s%5d", tok, count
puts arr.map { |ent|
ent[1] == min ? " -" : sprintf("%10.3f", count * (Math.log(ent[1]) - minlog))
}.join

View File

@@ -58,7 +58,13 @@ module Linguist
generated_parser? ||
generated_net_docfile? ||
generated_net_designer_file? ||
generated_protocol_buffer?
generated_postscript? ||
generated_protocol_buffer? ||
generated_jni_header? ||
composer_lock? ||
node_modules? ||
vcr_cassette? ||
generated_by_zephir?
end
# Internal: Is the blob an XCode project file?
@@ -73,14 +79,16 @@ module Linguist
# Internal: Is the blob minified files?
#
# Consider a file minified if it contains more than 5% spaces.
# Consider a file minified if the average line length is
# greater then 110c.
#
# Currently, only JS and CSS files are detected by this method.
#
# Returns true or false.
def minified_files?
return unless ['.js', '.css'].include? extname
if data && data.length > 200
(data.each_char.count{ |c| c <= ' ' } / data.length.to_f) < 0.05
if lines.any?
(lines.inject(0) { |n, l| n += l.length } / lines.length) > 110
else
false
end
@@ -171,6 +179,29 @@ module Linguist
false
end
# Internal: Is the blob of PostScript generated?
#
# PostScript files are often generated by other programs. If they tell us so,
# we can detect them.
#
# Returns true or false.
def generated_postscript?
return false unless ['.ps', '.eps'].include? extname
# We analyze the "%%Creator:" comment, which contains the author/generator
# of the file. If there is one, it should be in one of the first few lines.
creator = lines[0..9].find {|line| line =~ /^%%Creator: /}
return false if creator.nil?
# Most generators write their version number, while human authors' or companies'
# names don't contain numbers. So look if the line contains digits. Also
# look for some special cases without version numbers.
return creator =~ /[0-9]/ ||
creator.include?("mpage") ||
creator.include?("draw") ||
creator.include?("ImageMagick")
end
# Internal: Is the blob a C++, Java or Python source file generated by the
# Protocol Buffer compiler?
#
@@ -181,5 +212,47 @@ module Linguist
return lines[0].include?("Generated by the protocol buffer compiler. DO NOT EDIT!")
end
# Internal: Is the blob a C/C++ header generated by the Java JNI tool javah?
#
# Returns true of false.
def generated_jni_header?
return false unless extname == '.h'
return false unless lines.count > 2
return lines[0].include?("/* DO NOT EDIT THIS FILE - it is machine generated */") &&
lines[1].include?("#include <jni.h>")
end
# Internal: Is the blob part of node_modules/, which are not meant for humans in pull requests.
#
# Returns true or false.
def node_modules?
!!name.match(/node_modules\//)
end
# Internal: Is the blob a generated php composer lock file?
#
# Returns true or false.
def composer_lock?
!!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
def vcr_cassette?
return false unless extname == '.yml'
return false unless lines.count > 2
# VCR Cassettes have "recorded_with: VCR" in the second last line.
return lines[-2].include?("recorded_with: VCR")
end
end
end

View File

@@ -0,0 +1,90 @@
module Linguist
# A collection of simple heuristics that can be used to better analyze languages.
class Heuristics
ACTIVE = false
# Public: Given an array of String language names,
# apply heuristics against the given data and return an array
# of matching languages, or nil.
#
# data - Array of tokens or String data to analyze.
# languages - Array of language name Strings to restrict to.
#
# Returns an array of Languages or []
def self.find_by_heuristics(data, languages)
if active?
if languages.all? { |l| ["Objective-C", "C++"].include?(l) }
disambiguate_c(data, languages)
end
if languages.all? { |l| ["Perl", "Prolog"].include?(l) }
disambiguate_pl(data, languages)
end
if languages.all? { |l| ["ECL", "Prolog"].include?(l) }
disambiguate_ecl(data, languages)
end
if languages.all? { |l| ["TypeScript", "XML"].include?(l) }
disambiguate_ts(data, languages)
end
if languages.all? { |l| ["Common Lisp", "OpenCL"].include?(l) }
disambiguate_cl(data, languages)
end
if languages.all? { |l| ["Rebol", "R"].include?(l) }
disambiguate_r(data, languages)
end
end
end
# .h extensions are ambigious between C, C++, and Objective-C.
# We want to shortcut look for Objective-C _and_ now C++ too!
#
# Returns an array of Languages or []
def self.disambiguate_c(data, languages)
matches = []
matches << Language["Objective-C"] if data.include?("@interface")
matches << Language["C++"] if data.include?("#include <cstdint>")
matches
end
def self.disambiguate_pl(data, languages)
matches = []
matches << Language["Prolog"] if data.include?(":-")
matches << Language["Perl"] if data.include?("use strict")
matches
end
def self.disambiguate_ecl(data, languages)
matches = []
matches << Language["Prolog"] if data.include?(":-")
matches << Language["ECL"] if data.include?(":=")
matches
end
def self.disambiguate_ts(data, languages)
matches = []
if (data.include?("</translation>"))
matches << Language["XML"]
else
matches << Language["TypeScript"]
end
matches
end
def self.disambiguate_cl(data, languages)
matches = []
matches << Language["Common Lisp"] if data.include?("(defun ")
matches << Language["OpenCL"] if /\/\* |\/\/ |^\}/.match(data)
matches
end
def self.disambiguate_r(data, languages)
matches = []
matches << Language["Rebol"] if /\bRebol\b/i.match(data)
matches << Language["R"] if data.include?("<-")
matches
end
def self.active?
!!ACTIVE
end
end
end

View File

@@ -1,8 +1,13 @@
require 'escape_utils'
require 'pygments'
require 'yaml'
begin
require 'json'
rescue LoadError
end
require 'linguist/classifier'
require 'linguist/heuristics'
require 'linguist/samples'
module Linguist
@@ -15,17 +20,28 @@ module Linguist
@index = {}
@name_index = {}
@alias_index = {}
@extension_index = Hash.new { |h,k| h[k] = [] }
@filename_index = Hash.new { |h,k| h[k] = [] }
@extension_index = Hash.new { |h,k| h[k] = [] }
@interpreter_index = Hash.new { |h,k| h[k] = [] }
@filename_index = Hash.new { |h,k| h[k] = [] }
# Valid Languages types
TYPES = [:data, :markup, :programming]
TYPES = [:data, :markup, :programming, :prose]
# Names of non-programming languages that we will still detect
#
# Returns an array
def self.detectable_markup
["CSS", "Less", "Sass"]
["CSS", "Less", "Sass", "SCSS", "Stylus", "TeX"]
end
# Detect languages by a specific type
#
# type - A symbol that exists within TYPES
#
# Returns an array
def self.by_type(type)
all.select { |h| h.type == type }
end
# Internal: Create a new Language object
@@ -63,6 +79,10 @@ module Linguist
@extension_index[extension] << language
end
language.interpreters.each do |interpreter|
@interpreter_index[interpreter] << language
end
language.filenames.each do |filename|
@filename_index[filename] << language
end
@@ -87,16 +107,32 @@ module Linguist
name += ".script!"
end
# First try to find languages that match based on filename.
possible_languages = find_by_filename(name)
# If there is more than one possible language with that extension (or no
# extension at all, in the case of extensionless scripts), we need to continue
# our detection work
if possible_languages.length > 1
data = data.call() if data.respond_to?(:call)
possible_language_names = possible_languages.map(&:name)
# Don't bother with emptiness
if data.nil? || data == ""
nil
elsif result = Classifier.classify(Samples::DATA, data, possible_languages.map(&:name)).first
Language[result[0]]
# Check if there's a shebang line and use that as authoritative
elsif (result = find_by_shebang(data)) && !result.empty?
result.first
# No shebang. Still more work to do. Try to find it with our heuristics.
elsif (determined = Heuristics.find_by_heuristics(data, possible_language_names)) && !determined.empty?
determined.first
# Lastly, fall back to the probablistic classifier.
elsif classified = Classifier.classify(Samples::DATA, data, possible_language_names ).first
# Return the actual Language object based of the string language name (i.e., first element of `#classify`)
Language[classified[0]]
end
else
# Simplest and most common case, we can just return the one match based on extension
possible_languages.first
end
end
@@ -148,7 +184,23 @@ 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)
@filename_index[basename] + @extension_index[extname]
langs = @filename_index[basename] +
@extension_index[extname]
langs.compact.uniq
end
# Public: Look up Languages by shebang line.
#
# data - Array of tokens or String data to analyze.
#
# Examples
#
# Language.find_by_shebang("#!/bin/bash\ndate;")
# # => [#<Language name="Bash">]
#
# Returns the matching Language
def self.find_by_shebang(data)
@interpreter_index[Linguist.interpreter_from_shebang(data)]
end
# Public: Look up Language by its name or lexer.
@@ -236,17 +288,9 @@ module Linguist
# Set extensions or default to [].
@extensions = attributes[:extensions] || []
@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
@@ -334,19 +378,14 @@ module Linguist
# Returns the extensions Array
attr_reader :extensions
# Deprecated: Get primary extension
# Public: Get interpreters
#
# Defaults to the first extension but can be overridden
# in the languages.yml.
# Examples
#
# The primary extension can not be nil. Tests should verify this.
# # => ['awk', 'gawk', 'mawk' ...]
#
# 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
# Returns the interpreters Array
attr_reader :interpreters
# Public: Get filenames
#
@@ -356,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.
#
@@ -415,7 +475,7 @@ module Linguist
#
# Returns html String
def colorize(text, options = {})
lexer.highlight(text, options = {})
lexer.highlight(text, options)
end
# Public: Return name as String representation
@@ -441,11 +501,22 @@ module Linguist
end
extensions = Samples::DATA['extnames']
interpreters = Samples::DATA['interpreters']
filenames = Samples::DATA['filenames']
popular = YAML.load_file(File.expand_path("../popular.yml", __FILE__))
YAML.load_file(File.expand_path("../languages.yml", __FILE__)).each do |name, options|
languages_yml = File.expand_path("../languages.yml", __FILE__)
languages_json = File.expand_path("../languages.json", __FILE__)
if File.exist?(languages_json) && defined?(JSON)
languages = JSON.load(File.read(languages_json))
else
languages = YAML.load_file(languages_yml)
end
languages.each do |name, options|
options['extensions'] ||= []
options['interpreters'] ||= []
options['filenames'] ||= []
if extnames = extensions[name]
@@ -456,6 +527,18 @@ module Linguist
end
end
if interpreters == nil
interpreters = {}
end
if interpreter_names = interpreters[name]
interpreter_names.each do |interpreter|
if !options['interpreters'].include?(interpreter)
options['interpreters'] << interpreter
end
end
end
if fns = filenames[name]
fns.each do |filename|
if !options['filenames'].include?(filename)
@@ -475,8 +558,8 @@ module Linguist
:group_name => options['group'],
:searchable => options.key?('searchable') ? options['searchable'] : true,
:search_term => options['search_term'],
:extensions => options['extensions'].sort,
:primary_extension => options['primary_extension'],
:extensions => [options['extensions'].first] + options['extensions'][1..-1].sort,
:interpreters => options['interpreters'].sort,
:filenames => options['filenames'],
:popular => popular.include?(name)
)

File diff suppressed because it is too large Load Diff

View File

@@ -29,6 +29,7 @@ module Linguist
@computed_stats = false
@language = @size = nil
@sizes = Hash.new { 0 }
@file_breakdown = Hash.new { |h,k| h[k] = Array.new }
end
# Public: Returns a breakdown of language stats.
@@ -60,6 +61,12 @@ module Linguist
@size
end
# Public: Return the language breakdown of this repository by file
def breakdown_by_file
compute_stats
@file_breakdown
end
# Internal: Compute language breakdown for each blob in the Repository.
#
# Returns nothing
@@ -75,6 +82,10 @@ module Linguist
# Only include programming languages and acceptable markup languages
if blob.language.type == :programming || Language.detectable_markup.include?(blob.language.name)
# Build up the per-file breakdown stats
@file_breakdown[blob.language.group.name] << blob.name
@sizes[blob.language.group] += blob.size
end
end

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,8 @@
require 'yaml'
begin
require 'json'
rescue LoadError
require 'yaml'
end
require 'linguist/md5'
require 'linguist/classifier'
@@ -14,7 +18,8 @@ module Linguist
# Hash of serialized samples object
if File.exist?(PATH)
DATA = YAML.load_file(PATH)
serializer = defined?(JSON) ? JSON : YAML
DATA = serializer.load(File.read(PATH))
end
# Public: Iterate over each sample.
@@ -52,6 +57,7 @@ module Linguist
yield({
:path => File.join(dirname, filename),
:language => category,
:interpreter => File.exist?(filename) ? Linguist.interpreter_from_shebang(File.read(filename)) : nil,
:extname => File.extname(filename)
})
end
@@ -67,6 +73,7 @@ module Linguist
def self.data
db = {}
db['extnames'] = {}
db['interpreters'] = {}
db['filenames'] = {}
each do |sample|
@@ -80,6 +87,14 @@ module Linguist
end
end
if sample[:interpreter]
db['interpreters'][language_name] ||= []
if !db['interpreters'][language_name].include?(sample[:interpreter])
db['interpreters'][language_name] << sample[:interpreter]
db['interpreters'][language_name].sort!
end
end
if sample[:filename]
db['filenames'][language_name] ||= []
db['filenames'][language_name] << sample[:filename]
@@ -95,4 +110,40 @@ module Linguist
db
end
end
# Used to retrieve the interpreter from the shebang line of a file's
# data.
def self.interpreter_from_shebang(data)
lines = data.lines.to_a
if lines.any? && (match = lines[0].match(/(.+)\n?/)) && (bang = match[0]) =~ /^#!/
bang.sub!(/^#! /, '#!')
tokens = bang.split(' ')
pieces = tokens.first.split('/')
if pieces.size > 1
script = pieces.last
else
script = pieces.first.sub('#!', '')
end
script = script == 'env' ? tokens[1] : script
# "python2.6" -> "python"
if script =~ /((?:\d+\.?)+)/
script.sub! $1, ''
end
# Check for multiline shebang hacks that call `exec`
if script == 'sh' &&
lines[0...5].any? { |l| l.match(/exec (\w+).+\$0.+\$@/) }
script = $1
end
script
else
nil
end
end
end

View File

@@ -10,7 +10,10 @@
## Vendor Conventions ##
# Caches
- cache/
- (^|/)cache/
# Dependencies
- ^[Dd]ependencies/
# C deps
# https://github.com/joyent/node
@@ -24,20 +27,34 @@
# Node dependencies
- node_modules/
# Bower Components
- bower_components/
# Erlang bundles
- ^rebar$
# Bootstrap minified css and js
- (^|/)bootstrap([^.]*)(\.min)?\.(js|css)$
# Foundation css
- foundation.min.css
- foundation.css
# Vendored dependencies
- vendor/
- thirdparty/
- vendors?/
# Debian packaging
- ^debian/
# Haxelib projects often contain a neko bytecode file named run.n
- run.n$
## Commonly Bundled JavaScript frameworks ##
# jQuery
- (^|/)jquery([^.]*)(\.min)?\.js$
- (^|/)jquery\-\d\.\d(\.\d)?(\.min)?\.js$
- (^|/)jquery\-\d\.\d+(\.\d+)?(\.min)?\.js$
# jQuery UI
- (^|/)jquery\-ui(\-\d\.\d+(\.\d+)?)?(\.\w+)?(\.min)?\.(js|css)$
@@ -49,6 +66,9 @@
- (^|/)controls\.js$
- (^|/)dragdrop\.js$
# Typescript definition files
- (.*?)\.d\.ts$
# MooTools
- (^|/)mootools([^.]*)\d+\.\d+.\d+([^.]*)\.js$
@@ -75,6 +95,19 @@
- (^|/)shCore\.js$
- (^|/)shLegacy\.js$
# 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
@@ -86,16 +119,26 @@
# WAF
- ^waf$
# .osx
- ^.osx$
## Obj-C ##
# Sparkle
- (^|/)Sparkle/
## Groovy ##
# Gradle
- (^|/)gradlew$
- (^|/)gradlew\.bat$
- (^|/)gradle/wrapper/
## .NET ##
# Visual Studio IntelliSense
- -vsdoc\.js$
- \.intellisense\.js$
# jQuery validation plugin (MS bundles this with asp.net mvc)
- (^|/)jquery([^.]*)\.validate(\.unobtrusive)?(\.min)?\.js$
@@ -105,17 +148,36 @@
- (^|/)[Mm]icrosoft([Mm]vc)?([Aa]jax|[Vv]alidation)(\.debug)?\.js$
# NuGet
- ^[Pp]ackages/
- ^[Pp]ackages\/.+\.\d+\/
# ExtJS
- (^|/)extjs/
- (^|/)extjs/.*?\.js$
- (^|/)extjs/.*?\.xml$
- (^|/)extjs/.*?\.txt$
- (^|/)extjs/.*?\.html$
- (^|/)extjs/.*?\.properties$
- (^|/)extjs/.sencha/
- (^|/)extjs/docs/
- (^|/)extjs/builds/
- (^|/)extjs/cmd/
- (^|/)extjs/examples/
- (^|/)extjs/locale/
- (^|/)extjs/packages/
- (^|/)extjs/plugins/
- (^|/)extjs/resources/
- (^|/)extjs/src/
- (^|/)extjs/welcome/
# Html5shiv
- (^|/)html5shiv(\.min)?\.js$
# Samples folders
- ^[Ss]amples/
# LICENSE, README, git config files
- ^COPYING$
- ^LICENSE$
- LICENSE$
- License$
- gitattributes$
- gitignore$
- gitmodules$
@@ -125,5 +187,24 @@
# Test fixtures
- ^[Tt]est/fixtures/
# PhoneGap/Cordova
- (^|/)cordova([^.]*)(\.min)?\.js$
- (^|/)cordova\-\d\.\d(\.\d)?(\.min)?\.js$
# Vagrant
- ^Vagrantfile$
# .DS_Store's
- .[Dd][Ss]_[Ss]tore$
# 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

View File

@@ -0,0 +1,110 @@
(* ****** ****** *)
//
// HX-2014-01
// CoYoneda Lemma:
//
(* ****** ****** *)
//
#include
"share/atspre_staload.hats"
//
(* ****** ****** *)
staload
"libats/ML/SATS/basis.sats"
staload
"libats/ML/SATS/list0.sats"
(* ****** ****** *)
staload _ = "libats/ML/DATS/list0.dats"
(* ****** ****** *)
sortdef ftype = type -> type
(* ****** ****** *)
infixr (->) ->>
typedef ->> (a:type, b:type) = a -<cloref1> b
(* ****** ****** *)
typedef
functor(F:ftype) =
{a,b:type} (a ->> b) ->> F(a) ->> F(b)
(* ****** ****** *)
typedef
list0 (a:type) = list0 (a)
extern
val functor_list0 : functor (list0)
(* ****** ****** *)
implement
functor_list0{a,b}
(f) = lam xs => list0_map<a><b> (xs, f)
(* ****** ****** *)
datatype
CoYoneda
(F:ftype, r:type) = {a:type} CoYoneda of (a ->> r, F(a))
// end of [CoYoneda]
(* ****** ****** *)
//
extern
fun CoYoneda_phi
: {F:ftype}functor(F) -> {r:type} (F (r) ->> CoYoneda (F, r))
extern
fun CoYoneda_psi
: {F:ftype}functor(F) -> {r:type} (CoYoneda (F, r) ->> F (r))
//
(* ****** ****** *)
implement
CoYoneda_phi(ftor) = lam (fx) => CoYoneda (lam x => x, fx)
implement
CoYoneda_psi(ftor) = lam (CoYoneda(f, fx)) => ftor (f) (fx)
(* ****** ****** *)
datatype int0 = I of (int)
datatype bool = True | False // boxed boolean
(* ****** ****** *)
//
fun bool2string
(x:bool): string =
(
case+ x of True() => "True" | False() => "False"
)
//
implement
fprint_val<bool> (out, x) = fprint (out, bool2string(x))
//
(* ****** ****** *)
fun int2bool (i: int0): bool =
let val+I(i) = i in if i > 0 then True else False end
(* ****** ****** *)
val myintlist0 = g0ofg1($list{int0}((I)1, (I)0, (I)1, (I)0, (I)0))
val myboolist0 = CoYoneda{list0,bool}{int0}(lam (i) => int2bool(i), myintlist0)
val myboolist0 = CoYoneda_psi{list0}(functor_list0){bool}(myboolist0)
(* ****** ****** *)
val ((*void*)) = fprintln! (stdout_ref, "myboolist0 = ", myboolist0)
(* ****** ****** *)
implement main0 () = ()
(* ****** ****** *)
(* end of [CoYonedaLemma.dats] *)

View File

@@ -0,0 +1,178 @@
(* ****** ****** *)
//
// HX-2013-11
//
// Implementing a variant of
// the problem of Dining Philosophers
//
(* ****** ****** *)
//
#include
"share/atspre_define.hats"
#include
"share/atspre_staload.hats"
//
(* ****** ****** *)
staload
UN = "prelude/SATS/unsafe.sats"
(* ****** ****** *)
staload "libc/SATS/stdlib.sats"
staload "libc/SATS/unistd.sats"
(* ****** ****** *)
staload "{$LIBATSHWXI}/teaching/mythread/SATS/channel.sats"
(* ****** ****** *)
staload _ = "libats/DATS/deqarray.dats"
staload _ = "{$LIBATSHWXI}/teaching/mythread/DATS/channel.dats"
(* ****** ****** *)
staload "./DiningPhil2.sats"
(* ****** ****** *)
implement phil_left (n) = n
implement phil_right (n) = (n+1) \nmod NPHIL
(* ****** ****** *)
//
extern
fun randsleep (n: intGte(1)): void
//
implement
randsleep (n) =
ignoret (sleep($UN.cast{uInt}(rand() mod n + 1)))
// end of [randsleep]
//
(* ****** ****** *)
implement
phil_think (n) =
{
val () = println! ("phil_think(", n, ") starts")
val () = randsleep (6)
val () = println! ("phil_think(", n, ") finishes")
}
(* ****** ****** *)
implement
phil_dine (n, lf, rf) =
{
val () = println! ("phil_dine(", n, ") starts")
val () = randsleep (3)
val () = println! ("phil_dine(", n, ") finishes")
}
(* ****** ****** *)
implement
phil_loop (n) = let
//
val () = phil_think (n)
//
val nl = phil_left (n)
val nr = phil_right (n)
//
val ch_lfork = fork_changet (nl)
val ch_rfork = fork_changet (nr)
//
val lf = channel_takeout (ch_lfork)
val () = println! ("phil_loop(", n, ") picks left fork")
//
val () = randsleep (2) // HX: try to actively induce deadlock
//
val rf = channel_takeout (ch_rfork)
val () = println! ("phil_loop(", n, ") picks right fork")
//
val () = phil_dine (n, lf, rf)
//
val ch_forktray = forktray_changet ()
val () = channel_insert (ch_forktray, lf)
val () = channel_insert (ch_forktray, rf)
//
in
phil_loop (n)
end // end of [phil_loop]
(* ****** ****** *)
implement
cleaner_wash (f) =
{
val f = fork_get_num (f)
val () = println! ("cleaner_wash(", f, ") starts")
val () = randsleep (1)
val () = println! ("cleaner_wash(", f, ") finishes")
}
(* ****** ****** *)
implement
cleaner_return (f) =
{
val n = fork_get_num (f)
val ch = fork_changet (n)
val () = channel_insert (ch, f)
}
(* ****** ****** *)
implement
cleaner_loop () = let
//
val ch = forktray_changet ()
val f0 = channel_takeout (ch)
//
val () = cleaner_wash (f0)
val () = cleaner_return (f0)
//
in
cleaner_loop ()
end // end of [cleaner_loop]
(* ****** ****** *)
dynload "DiningPhil2.sats"
dynload "DiningPhil2_fork.dats"
dynload "DiningPhil2_thread.dats"
(* ****** ****** *)
local
//
staload
"{$LIBATSHWXI}/teaching/mythread/SATS/mythread.sats"
//
in (* in of [local] *)
//
val () = mythread_create_cloptr (llam () => phil_loop (0))
val () = mythread_create_cloptr (llam () => phil_loop (1))
val () = mythread_create_cloptr (llam () => phil_loop (2))
val () = mythread_create_cloptr (llam () => phil_loop (3))
val () = mythread_create_cloptr (llam () => phil_loop (4))
//
val () = mythread_create_cloptr (llam () => cleaner_loop ())
//
end // end of [local]
(* ****** ****** *)
implement
main0 () =
{
//
val () = println! ("DiningPhil2: starting")
val ((*void*)) = while (true) ignoret (sleep(1))
//
} (* end of [main0] *)
(* ****** ****** *)
(* end of [DiningPhil2.dats] *)

View File

@@ -0,0 +1,71 @@
(* ****** ****** *)
//
// HX-2013-11
//
// Implementing a variant of
// the problem of Dining Philosophers
//
(* ****** ****** *)
#include
"share/atspre_define.hats"
(* ****** ****** *)
staload "{$LIBATSHWXI}/teaching/mythread/SATS/channel.sats"
(* ****** ****** *)
%{#
#define NPHIL 5
%} // end of [%{#]
#define NPHIL 5
(* ****** ****** *)
typedef nphil = natLt(NPHIL)
(* ****** ****** *)
fun phil_left (n: nphil): nphil
fun phil_right (n: nphil): nphil
(* ****** ****** *)
//
fun phil_loop (n: nphil): void
//
(* ****** ****** *)
fun cleaner_loop ((*void*)): void
(* ****** ****** *)
absvtype fork_vtype = ptr
vtypedef fork = fork_vtype
(* ****** ****** *)
fun fork_get_num (!fork): nphil
(* ****** ****** *)
fun phil_dine
(n: nphil, lf: !fork, rf: !fork): void
// end of [phil_dine]
fun phil_think (n: nphil): void
(* ****** ****** *)
fun cleaner_wash (f: !fork): void
fun cleaner_return (f: fork): void
(* ****** ****** *)
//
fun fork_changet (n: nphil): channel(fork)
//
fun forktray_changet ((*void*)): channel(fork)
//
(* ****** ****** *)
(* end of [DiningPhil2.sats] *)

View File

@@ -0,0 +1,89 @@
(* ****** ****** *)
//
// HX-2013-11
//
// Implementing a variant of
// the problem of Dining Philosophers
//
(* ****** ****** *)
//
#include
"share/atspre_define.hats"
#include
"share/atspre_staload.hats"
//
(* ****** ****** *)
staload
UN = "prelude/SATS/unsafe.sats"
(* ****** ****** *)
staload "{$LIBATSHWXI}/teaching/mythread/SATS/channel.sats"
(* ****** ****** *)
staload _ = "libats/DATS/deqarray.dats"
staload _ = "{$LIBATSHWXI}/teaching/mythread/DATS/channel.dats"
(* ****** ****** *)
staload "./DiningPhil2.sats"
(* ****** ****** *)
datavtype fork = FORK of (nphil)
(* ****** ****** *)
assume fork_vtype = fork
(* ****** ****** *)
implement
fork_get_num (f) = let val FORK(n) = f in n end
(* ****** ****** *)
local
val
the_forkarray = let
//
typedef t = channel(fork)
//
implement
array_tabulate$fopr<t>
(n) = ch where
{
val n = $UN.cast{nphil}(n)
val ch = channel_create_exn<fork> (i2sz(2))
val () = channel_insert (ch, FORK (n))
}
//
in
arrayref_tabulate<t> (i2sz(NPHIL))
end // end of [val]
in (* in of [local] *)
implement fork_changet (n) = the_forkarray[n]
end // end of [local]
(* ****** ****** *)
local
val the_forktray =
channel_create_exn<fork> (i2sz(NPHIL+1))
in (* in of [local] *)
implement forktray_changet () = the_forktray
end // end of [local]
(* ****** ****** *)
(* end of [DiningPhil2_fork.dats] *)

View File

@@ -0,0 +1,43 @@
(* ****** ****** *)
//
// HX-2013-11
//
// Implementing a variant of
// the problem of Dining Philosophers
//
(* ****** ****** *)
//
#include "share/atspre_define.hats"
#include "share/atspre_staload.hats"
//
(* ****** ****** *)
staload "{$LIBATSHWXI}/teaching/mythread/SATS/mythread.sats"
(* ****** ****** *)
local
//
#include "{$LIBATSHWXI}/teaching/mythread/DATS/mythread.dats"
//
in (* in of [local] *)
//
// HX: it is intentionally left to be empty
//
end // end of [local]
(* ****** ****** *)
local
//
#include "{$LIBATSHWXI}/teaching/mythread/DATS/mythread_posix.dats"
//
in (* in of [local] *)
//
// HX: it is intentionally left to be empty
//
end // end of [local]
(* ****** ****** *)
(* end of [DiningPhil2_thread.dats] *)

View File

@@ -0,0 +1,178 @@
(* ****** ****** *)
//
// HX-2014-01
// Yoneda Lemma:
// The hardest "trivial" theorem :)
//
(* ****** ****** *)
//
#include
"share/atspre_staload.hats"
//
(* ****** ****** *)
staload
"libats/ML/SATS/basis.sats"
staload
"libats/ML/SATS/list0.sats"
staload
"libats/ML/SATS/option0.sats"
(* ****** ****** *)
staload _ = "libats/ML/DATS/list0.dats"
staload _ = "libats/ML/DATS/option0.dats"
(* ****** ****** *)
sortdef ftype = type -> type
(* ****** ****** *)
infixr (->) ->>
typedef ->> (a:type, b:type) = a -<cloref1> b
(* ****** ****** *)
typedef
functor(F:ftype) =
{a,b:type} (a ->> b) ->> F(a) ->> F(b)
(* ****** ****** *)
typedef
list0 (a:type) = list0 (a)
extern
val functor_list0 : functor (list0)
(* ****** ****** *)
implement
functor_list0{a,b}
(f) = lam xs => list0_map<a><b> (xs, f)
(* ****** ****** *)
typedef
option0 (a:type) = option0 (a)
extern
val functor_option0 : functor (option0)
(* ****** ****** *)
implement
functor_option0{a,b}
(f) = lam opt => option0_map<a><b> (opt, f)
(* ****** ****** *)
extern
val functor_homres
: {c:type} functor (lam(r:type) => c ->> r)
(* ****** ****** *)
implement
functor_homres{c}{a,b} (f) = lam (r) => lam (x) => f (r(x))
(* ****** ****** *)
//
extern
fun Yoneda_phi : {F:ftype}functor(F) ->
{a:type}F(a) ->> ({r:type}(a ->> r) ->> F(r))
extern
fun Yoneda_psi : {F:ftype}functor(F) ->
{a:type}({r:type}(a ->> r) ->> F(r)) ->> F(a)
//
(* ****** ****** *)
//
implement
Yoneda_phi
(ftor) = lam(fx) => lam (m) => ftor(m)(fx)
//
implement
Yoneda_psi (ftor) = lam(mf) => mf(lam x => x)
//
(* ****** ****** *)
(*
(* ****** ****** *)
//
// HX-2014-01-05:
// Another version based on Natural Transformation
//
(* ****** ****** *)
typedef
natrans(F:ftype, G:ftype) = {x:type} (F(x) ->> G(x))
(* ****** ****** *)
//
extern
fun Yoneda_phi_nat : {F:ftype}functor(F) ->
{a:type} F(a) ->> natrans(lam (r:type) => (a ->> r), F)
extern
fun Yoneda_psi_nat : {F:ftype}functor(F) ->
{a:type} natrans(lam (r:type) => (a ->> r), F) ->> F(a)
//
(* ****** ****** *)
//
implement
Yoneda_phi_nat
(ftor) = lam(fx) => lam (m) => ftor(m)(fx)
//
implement
Yoneda_psi_nat (ftor) = lam(mf) => mf(lam x => x)
//
(* ****** ****** *)
*)
(* ****** ****** *)
datatype bool = True | False // boxed boolean
(* ****** ****** *)
//
fun bool2string
(x:bool): string =
(
case+ x of True() => "True" | False() => "False"
)
//
implement
fprint_val<bool> (out, x) = fprint (out, bool2string(x))
//
(* ****** ****** *)
//
val myboolist0 =
$list_t{bool}(True, False, True, False, False)
val myboolist0 = g0ofg1_list (myboolist0)
//
(* ****** ****** *)
//
extern
val Yoneda_bool_list0 : {r:type} (bool ->> r) ->> list0(r)
//
implement
Yoneda_bool_list0 =
Yoneda_phi(functor_list0){bool}(myboolist0)
//
(* ****** ****** *)
//
val myboolist1 =
Yoneda_psi(functor_list0){bool}(Yoneda_bool_list0)
//
(* ****** ****** *)
val () = fprintln! (stdout_ref, "myboolist0 = ", myboolist0)
val () = fprintln! (stdout_ref, "myboolist1 = ", myboolist1)
(* ****** ****** *)
implement main0 () = ()
(* ****** ****** *)
(* end of [YonedaLemma.dats] *)

187
samples/ATS/linset.hats Normal file
View File

@@ -0,0 +1,187 @@
(***********************************************************************)
(* *)
(* Applied Type System *)
(* *)
(***********************************************************************)
(*
** ATS/Postiats - Unleashing the Potential of Types!
** Copyright (C) 2011-2013 Hongwei Xi, ATS Trustful Software, Inc.
** All rights reserved
**
** ATS is free software; you can redistribute it and/or modify it under
** the terms of the GNU GENERAL PUBLIC LICENSE (GPL) as published by the
** Free Software Foundation; either version 3, or (at your option) any
** later version.
**
** ATS is distributed in the hope that it will be useful, but WITHOUT ANY
** WARRANTY; without even the implied warranty of MERCHANTABILITY or
** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
** for more details.
**
** You should have received a copy of the GNU General Public License
** along with ATS; see the file COPYING. If not, please write to the
** Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
** 02110-1301, USA.
*)
(* ****** ****** *)
(* Author: Hongwei Xi *)
(* Authoremail: hwxi AT cs DOT bu DOT edu *)
(* Start time: December, 2012 *)
(* ****** ****** *)
//
// HX: shared by linset_listord (* ordered list *)
// HX: shared by linset_avltree (* AVL-tree-based *)
//
(* ****** ****** *)
//
// HX-2013-02:
// for sets of nonlinear elements
//
absvtype set_vtype (a:t@ype+) = ptr
//
(* ****** ****** *)
vtypedef set (a:t0p) = set_vtype (a)
(* ****** ****** *)
fun{a:t0p}
compare_elt_elt (x1: a, x2: a):<> int
(* ****** ****** *)
fun{} linset_nil{a:t0p} ():<> set(a)
fun{} linset_make_nil{a:t0p} ():<> set(a)
(* ****** ****** *)
fun{a:t0p} linset_sing (x: a):<!wrt> set(a)
fun{a:t0p} linset_make_sing (x: a):<!wrt> set(a)
(* ****** ****** *)
fun{a:t0p}
linset_make_list (xs: List(INV(a))):<!wrt> set(a)
(* ****** ****** *)
fun{}
linset_is_nil {a:t0p} (xs: !set(INV(a))):<> bool
fun{}
linset_isnot_nil {a:t0p} (xs: !set(INV(a))):<> bool
(* ****** ****** *)
fun{a:t0p} linset_size (!set(INV(a))): size_t
(* ****** ****** *)
fun{a:t0p}
linset_is_member (xs: !set(INV(a)), x0: a):<> bool
fun{a:t0p}
linset_isnot_member (xs: !set(INV(a)), x0: a):<> bool
(* ****** ****** *)
fun{a:t0p}
linset_copy (!set(INV(a))):<!wrt> set(a)
fun{a:t0p}
linset_free (xs: set(INV(a))):<!wrt> void
(* ****** ****** *)
//
fun{a:t0p}
linset_insert
(xs: &set(INV(a)) >> _, x0: a):<!wrt> bool
//
(* ****** ****** *)
//
fun{a:t0p}
linset_takeout
(
&set(INV(a)) >> _, a, res: &(a?) >> opt(a, b)
) :<!wrt> #[b:bool] bool(b) // endfun
fun{a:t0p}
linset_takeout_opt (&set(INV(a)) >> _, a):<!wrt> Option_vt(a)
//
(* ****** ****** *)
//
fun{a:t0p}
linset_remove
(xs: &set(INV(a)) >> _, x0: a):<!wrt> bool
//
(* ****** ****** *)
//
// HX: choosing an element in an unspecified manner
//
fun{a:t0p}
linset_choose
(
xs: !set(INV(a)), x: &a? >> opt (a, b)
) :<!wrt> #[b:bool] bool(b)
//
fun{a:t0p}
linset_choose_opt (xs: !set(INV(a))):<!wrt> Option_vt(a)
//
(* ****** ****** *)
fun{a:t0p}
linset_takeoutmax
(
xs: &set(INV(a)) >> _, res: &a? >> opt(a, b)
) :<!wrt> #[b:bool] bool (b)
fun{a:t0p}
linset_takeoutmax_opt (xs: &set(INV(a)) >> _):<!wrt> Option_vt(a)
(* ****** ****** *)
fun{a:t0p}
linset_takeoutmin
(
xs: &set(INV(a)) >> _, res: &a? >> opt(a, b)
) :<!wrt> #[b:bool] bool (b)
fun{a:t0p}
linset_takeoutmin_opt (xs: &set(INV(a)) >> _):<!wrt> Option_vt(a)
(* ****** ****** *)
//
fun{}
fprint_linset$sep (FILEref): void // ", "
//
fun{a:t0p}
fprint_linset (out: FILEref, xs: !set(INV(a))): void
//
overload fprint with fprint_linset
//
(* ****** ****** *)
//
fun{
a:t0p}{env:vt0p
} linset_foreach$fwork
(x: a, env: &(env) >> _): void
//
fun{a:t0p}
linset_foreach (set: !set(INV(a))): void
fun{
a:t0p}{env:vt0p
} linset_foreach_env
(set: !set(INV(a)), env: &(env) >> _): void
// end of [linset_foreach_env]
//
(* ****** ****** *)
fun{a:t0p}
linset_listize (xs: set(INV(a))): List0_vt (a)
(* ****** ****** *)
fun{a:t0p}
linset_listize1 (xs: !set(INV(a))): List0_vt (a)
(* ****** ****** *)
(* end of [linset.hats] *)

View File

@@ -0,0 +1,504 @@
(***********************************************************************)
(* *)
(* Applied Type System *)
(* *)
(***********************************************************************)
(*
** ATS/Postiats - Unleashing the Potential of Types!
** Copyright (C) 2011-2013 Hongwei Xi, ATS Trustful Software, Inc.
** All rights reserved
**
** ATS is free software; you can redistribute it and/or modify it under
** the terms of the GNU GENERAL PUBLIC LICENSE (GPL) as published by the
** Free Software Foundation; either version 3, or (at your option) any
** later version.
**
** ATS is distributed in the hope that it will be useful, but WITHOUT ANY
** WARRANTY; without even the implied warranty of MERCHANTABILITY or
** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
** for more details.
**
** You should have received a copy of the GNU General Public License
** along with ATS; see the file COPYING. If not, please write to the
** Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
** 02110-1301, USA.
*)
(* ****** ****** *)
(* Author: Hongwei Xi *)
(* Authoremail: hwxi AT cs DOT bu DOT edu *)
(* Start time: February, 2013 *)
(* ****** ****** *)
//
// HX-2013-08:
// a set is represented as a sorted list in descending order;
// note that descending order is chosen to faciliate set comparison
//
(* ****** ****** *)
staload
UN = "prelude/SATS/unsafe.sats"
(* ****** ****** *)
staload "libats/SATS/linset_listord.sats"
(* ****** ****** *)
#include "./SHARE/linset.hats" // code reuse
#include "./SHARE/linset_node.hats" // code reuse
(* ****** ****** *)
assume
set_vtype (elt:t@ype) = List0_vt (elt)
(* ****** ****** *)
implement{}
linset_nil () = list_vt_nil ()
implement{}
linset_make_nil () = list_vt_nil ()
(* ****** ****** *)
implement
{a}(*tmp*)
linset_sing
(x) = list_vt_cons{a}(x, list_vt_nil)
// end of [linset_sing]
implement{a}
linset_make_sing
(x) = list_vt_cons{a}(x, list_vt_nil)
// end of [linset_make_sing]
(* ****** ****** *)
implement{}
linset_is_nil (xs) = list_vt_is_nil (xs)
implement{}
linset_isnot_nil (xs) = list_vt_is_cons (xs)
(* ****** ****** *)
implement{a}
linset_size (xs) =
let val n = list_vt_length(xs) in i2sz(n) end
// end of [linset_size]
(* ****** ****** *)
implement{a}
linset_is_member
(xs, x0) = let
//
fun aux
{n:nat} .<n>.
(
xs: !list_vt (a, n)
) :<> bool = let
in
//
case+ xs of
| list_vt_cons (x, xs) => let
val sgn = compare_elt_elt<a> (x0, x) in
if sgn > 0 then false else (if sgn < 0 then aux (xs) else true)
end // end of [list_vt_cons]
| list_vt_nil ((*void*)) => false
//
end // end of [aux]
//
in
aux (xs)
end // end of [linset_is_member]
(* ****** ****** *)
implement{a}
linset_copy (xs) = list_vt_copy<a> (xs)
implement{a}
linset_free (xs) = list_vt_free<a> (xs)
(* ****** ****** *)
implement{a}
linset_insert
(xs, x0) = let
//
fun
mynode_cons
{n:nat} .<>.
(
nx: mynode1 (a), xs: list_vt (a, n)
) : list_vt (a, n+1) = let
//
val xs1 =
$UN.castvwtp0{List1_vt(a)}(nx)
val+@list_vt_cons (_, xs2) = xs1
prval () = $UN.cast2void (xs2); val () = (xs2 := xs)
//
in
fold@ (xs1); xs1
end // end of [mynode_cons]
//
fun ins
{n:nat} .<n>. // tail-recursive
(
xs: &list_vt (a, n) >> list_vt (a, n1)
) : #[n1:nat | n <= n1; n1 <= n+1] bool =
(
case+ xs of
| @list_vt_cons
(x, xs1) => let
val sgn =
compare_elt_elt<a> (x0, x)
// end of [val]
in
if sgn > 0 then let
prval () = fold@ (xs)
val nx = mynode_make_elt<a> (x0)
val ((*void*)) = xs := mynode_cons (nx, xs)
in
false
end else if sgn < 0 then let
val ans = ins (xs1)
prval () = fold@ (xs)
in
ans
end else let // [x0] is found
prval () = fold@ (xs)
in
true (* [x0] in [xs] *)
end (* end of [if] *)
end // end of [list_vt_cons]
| list_vt_nil () => let
val nx = mynode_make_elt<a> (x0)
val ((*void*)) = xs := mynode_cons (nx, xs)
in
false
end // end of [list_vt_nil]
) (* end of [ins] *)
//
in
$effmask_all (ins (xs))
end // end of [linset_insert]
(* ****** ****** *)
(*
//
HX-2013-08:
[linset_remove] moved up
//
implement{a}
linset_remove
(xs, x0) = let
//
fun rem
{n:nat} .<n>. // tail-recursive
(
xs: &list_vt (a, n) >> list_vt (a, n1)
) : #[n1:nat | n1 <= n; n <= n1+1] bool =
(
case+ xs of
| @list_vt_cons
(x, xs1) => let
val sgn =
compare_elt_elt<a> (x0, x)
// end of [val]
in
if sgn > 0 then let
prval () = fold@ (xs)
in
false
end else if sgn < 0 then let
val ans = rem (xs1)
prval () = fold@ (xs)
in
ans
end else let // x0 = x
val xs1_ = xs1
val ((*void*)) = free@{a}{0}(xs)
val () = xs := xs1_
in
true // [x0] in [xs]
end (* end of [if] *)
end // end of [list_vt_cons]
| list_vt_nil () => false
) (* end of [rem] *)
//
in
$effmask_all (rem (xs))
end // end of [linset_remove]
*)
(* ****** ****** *)
(*
** By Brandon Barker
*)
implement
{a}(*tmp*)
linset_choose
(xs, x0) = let
in
//
case+ xs of
| list_vt_cons
(x, xs1) => let
val () = x0 := x
prval () = opt_some{a}(x0)
in
true
end // end of [list_vt_cons]
| list_vt_nil () => let
prval () = opt_none{a}(x0)
in
false
end // end of [list_vt_nil]
//
end // end of [linset_choose]
(* ****** ****** *)
implement
{a}{env}
linset_foreach_env (xs, env) = let
//
implement
list_vt_foreach$fwork<a><env>
(x, env) = linset_foreach$fwork<a><env> (x, env)
//
in
list_vt_foreach_env<a><env> (xs, env)
end // end of [linset_foreach_env]
(* ****** ****** *)
implement{a}
linset_listize (xs) = xs
(* ****** ****** *)
implement{a}
linset_listize1 (xs) = list_vt_copy (xs)
(* ****** ****** *)
//
// HX: functions for processing mynodes
//
(* ****** ****** *)
implement{
} mynode_null{a} () =
$UN.castvwtp0{mynode(a,null)}(the_null_ptr)
// end of [mynode_null]
(* ****** ****** *)
implement
{a}(*tmp*)
mynode_make_elt
(x) = let
//
val nx = list_vt_cons{a}{0}(x, _ )
//
in
$UN.castvwtp0{mynode1(a)}(nx)
end // end of [mynode_make_elt]
(* ****** ****** *)
implement{
} mynode_free
{a}(nx) = () where {
val nx =
$UN.castvwtp0{List1_vt(a)}(nx)
//
val+~list_vt_cons (_, nx2) = nx
//
prval ((*void*)) = $UN.cast2void (nx2)
//
} (* end of [mynode_free] *)
(* ****** ****** *)
implement
{a}(*tmp*)
mynode_get_elt
(nx) = (x) where {
//
val nx1 =
$UN.castvwtp1{List1_vt(a)}(nx)
//
val+list_vt_cons (x, _) = nx1
//
prval ((*void*)) = $UN.cast2void (nx1)
//
} (* end of [mynode_get_elt] *)
(* ****** ****** *)
implement
{a}(*tmp*)
mynode_set_elt
{l} (nx, x0) =
{
//
val nx1 =
$UN.castvwtp1{List1_vt(a)}(nx)
//
val+@list_vt_cons (x, _) = nx1
//
val () = x := x0
//
prval () = fold@ (nx1)
prval () = $UN.cast2void (nx1)
//
prval () = __assert (nx) where
{
extern praxi __assert (nx: !mynode(a?, l) >> mynode (a, l)): void
} (* end of [prval] *)
//
} (* end of [mynode_set_elt] *)
(* ****** ****** *)
implement
{a}(*tmp*)
mynode_getfree_elt
(nx) = (x) where {
//
val nx =
$UN.castvwtp0{List1_vt(a)}(nx)
//
val+~list_vt_cons (x, nx2) = nx
//
prval ((*void*)) = $UN.cast2void (nx2)
//
} (* end of [mynode_getfree_elt] *)
(* ****** ****** *)
(*
fun{a:t0p}
linset_takeout_ngc
(set: &set(INV(a)) >> _, x0: a):<!wrt> mynode0 (a)
// end of [linset_takeout_ngc]
*)
implement
{a}(*tmp*)
linset_takeout_ngc
(set, x0) = let
//
fun takeout
(
xs: &List0_vt (a) >> _
) : mynode0(a) = let
in
//
case+ xs of
| @list_vt_cons
(x, xs1) => let
prval pf_x = view@x
prval pf_xs1 = view@xs1
val sgn =
compare_elt_elt<a> (x0, x)
// end of [val]
in
if sgn > 0 then let
prval () = fold@ (xs)
in
mynode_null{a}((*void*))
end else if sgn < 0 then let
val res = takeout (xs1)
prval ((*void*)) = fold@ (xs)
in
res
end else let // x0 = x
val xs1_ = xs1
val res = $UN.castvwtp0{mynode1(a)}((pf_x, pf_xs1 | xs))
val () = xs := xs1_
in
res // [x0] in [xs]
end (* end of [if] *)
end // end of [list_vt_cons]
| list_vt_nil () => mynode_null{a}((*void*))
//
end (* end of [takeout] *)
//
in
$effmask_all (takeout (set))
end // end of [linset_takeout_ngc]
(* ****** ****** *)
implement
{a}(*tmp*)
linset_takeoutmax_ngc
(xs) = let
in
//
case+ xs of
| @list_vt_cons
(x, xs1) => let
prval pf_x = view@x
prval pf_xs1 = view@xs1
val xs_ = xs
val () = xs := xs1
in
$UN.castvwtp0{mynode1(a)}((pf_x, pf_xs1 | xs_))
end // end of [list_vt_cons]
| @list_vt_nil () => let
prval () = fold@ (xs)
in
mynode_null{a}((*void*))
end // end of [list_vt_nil]
//
end // end of [linset_takeoutmax_ngc]
(* ****** ****** *)
implement
{a}(*tmp*)
linset_takeoutmin_ngc
(xs) = let
//
fun unsnoc
{n:pos} .<n>.
(
xs: &list_vt (a, n) >> list_vt (a, n-1)
) :<!wrt> mynode1 (a) = let
//
val+@list_vt_cons (x, xs1) = xs
//
prval pf_x = view@x and pf_xs1 = view@xs1
//
in
//
case+ xs1 of
| list_vt_cons _ =>
let val res = unsnoc(xs1) in fold@xs; res end
// end of [list_vt_cons]
| list_vt_nil () => let
val xs_ = xs
val () = xs := list_vt_nil{a}()
in
$UN.castvwtp0{mynode1(a)}((pf_x, pf_xs1 | xs_))
end // end of [list_vt_nil]
//
end // end of [unsnoc]
//
in
//
case+ xs of
| list_vt_cons _ => unsnoc (xs)
| list_vt_nil () => mynode_null{a}((*void*))
//
end // end of [linset_takeoutmin_ngc]
(* ****** ****** *)
(* end of [linset_listord.dats] *)

View File

@@ -0,0 +1,51 @@
(***********************************************************************)
(* *)
(* Applied Type System *)
(* *)
(***********************************************************************)
(*
** ATS/Postiats - Unleashing the Potential of Types!
** Copyright (C) 2011-2013 Hongwei Xi, ATS Trustful Software, Inc.
** All rights reserved
**
** ATS is free software; you can redistribute it and/or modify it under
** the terms of the GNU GENERAL PUBLIC LICENSE (GPL) as published by the
** Free Software Foundation; either version 3, or (at your option) any
** later version.
**
** ATS is distributed in the hope that it will be useful, but WITHOUT ANY
** WARRANTY; without even the implied warranty of MERCHANTABILITY or
** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
** for more details.
**
** You should have received a copy of the GNU General Public License
** along with ATS; see the file COPYING. If not, please write to the
** Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
** 02110-1301, USA.
*)
(* ****** ****** *)
//
// Author: Hongwei Xi
// Authoremail: hwxiATcsDOTbuDOTedu
// Time: October, 2010
//
(* ****** ****** *)
#define ATS_PACKNAME "ATSLIB.libats.linset_listord"
#define ATS_STALOADFLAG 0 // no static loading at run-time
(* ****** ****** *)
#include "./SHARE/linset.hats"
#include "./SHARE/linset_node.hats"
(* ****** ****** *)
castfn
linset2list {a:t0p} (xs: set (INV(a))):<> List0_vt (a)
(* ****** ****** *)
(* end of [linset_listord.sats] *)

215
samples/ATS/main.atxt Normal file
View File

@@ -0,0 +1,215 @@
%{
#include "./../ATEXT/atextfun.hats"
%}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<title>EFFECTIVATS-DiningPhil2</title>
#patscode_style()
</head>
<body>
<h1>
Effective ATS: Dining Philosophers
</h1>
In this article, I present an implementation of a slight variant of the
famous problem of 5-Dining-Philosophers by Dijkstra that makes simple but
convincing use of linear types.
<h2>
The Original Problem
</h2>
There are five philosophers sitting around a table and there are also 5
forks placed on the table such that each fork is located between the left
hand of a philosopher and the right hand of another philosopher. Each
philosopher does the following routine repeatedly: thinking and dining. In
order to dine, a philosopher needs to first acquire two forks: one located
on his left-hand side and the other on his right-hand side. After
finishing dining, a philosopher puts the two acquired forks onto the table:
one on his left-hand side and the other on his right-hand side.
<h2>
A Variant of the Original Problem
</h2>
The following twist is added to the original version:
<p>
After a fork is used, it becomes a "dirty" fork and needs to be put in a
tray for dirty forks. There is a cleaner who cleans dirty forks and then
puts them back on the table.
<h2>
Channels for Communication
</h2>
A channel is just a shared queue of fixed capacity. The following two
functions are for inserting an element into and taking an element out of a
given channel:
<pre
class="patsyntax">
#pats2xhtml_sats("\
fun{a:vt0p} channel_insert (channel (a), a): void
fun{a:vt0p} channel_takeout (chan: channel (a)): (a)
")</pre>
If [channel_insert] is called on a channel that is full, then the caller is
blocked until an element is taken out of the channel. If [channel_takeout]
is called on a channel that is empty, then the caller is blocked until an
element is inserted into the channel.
<h2>
A Channel for Each Fork
</h2>
Forks are resources given a linear type. Each fork is initially stored in a
channel, which can be obtained by calling the following function:
<pre
class="patsyntax">
#pats2xhtml_sats("\
fun fork_changet (n: nphil): channel(fork)
")</pre>
where the type [nphil] is defined to be [natLt(5)] (for natural numbers
less than 5). The channels for storing forks are chosen to be of capacity
2. The reason that channels of capacity 2 are chosen to store at most one
element (in each of them) is to guarantee that these channels can never be
full (so that there is no attempt made to send signals to awake callers
supposedly being blocked due to channels being full).
<h2>
A Channel for the Fork Tray
</h2>
A tray for storing "dirty" forks is also a channel, which can be obtained
by calling the following function:
<pre
class="patsyntax">
#pats2xhtml_sats("\
fun forktray_changet ((*void*)): channel(fork)
")</pre>
The capacity chosen for the channel is 6 (instead of 5) so that it can
never become full (as there are only 5 forks in total).
<h2>
Philosopher Loop
</h2>
Each philosopher is implemented as a loop:
<pre
class="patsyntax">
#pats2xhtml_dats('\
implement
phil_loop (n) = let
//
val () = phil_think (n)
//
val nl = phil_left (n) // = n
val nr = phil_right (n) // = (n+1) % 5
//
val ch_lfork = fork_changet (nl)
val ch_rfork = fork_changet (nr)
//
val lf = channel_takeout (ch_lfork)
val () = println! ("phil_loop(", n, ") picks left fork")
//
val () = randsleep (2) // sleep up to 2 seconds
//
val rf = channel_takeout (ch_rfork)
val () = println! ("phil_loop(", n, ") picks right fork")
//
val () = phil_dine (n, lf, rf)
//
val ch_forktray = forktray_changet ()
val () = channel_insert (ch_forktray, lf) // left fork to dirty tray
val () = channel_insert (ch_forktray, rf) // right fork to dirty tray
//
in
phil_loop (n)
end // end of [phil_loop]
')</pre>
It should be straighforward to follow the code for [phil_loop].
<h2>
Fork Cleaner Loop
</h2>
A cleaner is implemented as a loop:
<pre
class="patsyntax">
#pats2xhtml_dats('\
implement
cleaner_loop () = let
//
val ch = forktray_changet ()
val f0 = channel_takeout (ch) // [f0] is dirty
//
val () = cleaner_wash (f0) // washes dirty [f0]
val () = cleaner_return (f0) // puts back cleaned [f0]
//
in
cleaner_loop ()
end // end of [cleaner_loop]
')</pre>
The function [cleaner_return] first finds out the number of a given fork
and then uses the number to locate the channel for storing the fork. Its
actual implementation is given as follows:
<pre
class="patsyntax">
#pats2xhtml_dats('\
implement
cleaner_return (f) =
{
val n = fork_get_num (f)
val ch = fork_changet (n)
val () = channel_insert (ch, f)
}
')</pre>
It should now be straighforward to follow the code for [cleaner_loop].
<h2>
Testing
</h2>
The entire code of this implementation is stored in the following files:
<pre>
DiningPhil2.sats
DiningPhil2.dats
DiningPhil2_fork.dats
DiningPhil2_thread.dats
</pre>
There is also a Makefile available for compiling the ATS source code into
an excutable for testing. One should be able to encounter a deadlock after
running the simulation for a while.
<hr size="2">
This article is written by <a href="http://www.cs.bu.edu/~hwxi/">Hongwei Xi</a>.
</body>
</html>
%{
implement main () = fprint_filsub (stdout_ref, "main_atxt.txt")
%}

39
samples/Agda/NatCat.agda Normal file
View File

@@ -0,0 +1,39 @@
module NatCat where
open import Relation.Binary.PropositionalEquality
-- If you can show that a relation only ever has one inhabitant
-- you get the category laws for free
module
EasyCategory
(obj : Set)
(_⟶_ : obj obj Set)
(_∘_ : {x y z} x y y z x z)
(id : x x x)
(single-inhabitant : (x y : obj) (r s : x y) r s)
where
idʳ : x y (r : x y) r id y r
idʳ x y r = single-inhabitant x y (r id y) r
idˡ : x y (r : x y) id x r r
idˡ x y r = single-inhabitant x y (id x r) r
∘-assoc : w x y z (r : w x) (s : x y) (t : y z) (r s) t r (s t)
∘-assoc w x y z r s t = single-inhabitant w z ((r s) t) (r (s t))
open import Data.Nat
same : (x y : ) (r s : x y) r s
same .0 y z≤n z≤n = refl
same .(suc m) .(suc n) (s≤s {m} {n} r) (s≤s s) = cong s≤s (same m n r s)
≤-trans : x y z x y y z x z
≤-trans .0 y z z≤n s = z≤n
≤-trans .(suc m) .(suc n) .(suc n₁) (s≤s {m} {n} r) (s≤s {.n} {n₁} s) = s≤s (≤-trans m n n₁ r s)
≤-refl : x x x
≤-refl zero = z≤n
≤-refl (suc x) = s≤s (≤-refl x)
module Nat-EasyCategory = EasyCategory _≤_ (λ {x}{y}{z} ≤-trans x y z) ≤-refl same

View File

@@ -0,0 +1,59 @@
module examples/systems/file_system
/*
* Model of a generic file system.
*/
abstract sig Object {}
sig Name {}
sig File extends Object {} { some d: Dir | this in d.entries.contents }
sig Dir extends Object {
entries: set DirEntry,
parent: lone Dir
} {
parent = this.~@contents.~@entries
all e1, e2 : entries | e1.name = e2.name => e1 = e2
this !in this.^@parent
this != Root => Root in this.^@parent
}
one sig Root extends Dir {} { no parent }
lone sig Cur extends Dir {}
sig DirEntry {
name: Name,
contents: Object
} {
one this.~entries
}
/**
* all directories besides root have one parent
*/
pred OneParent_buggyVersion {
all d: Dir - Root | one d.parent
}
/**
* all directories besides root have one parent
*/
pred OneParent_correctVersion {
all d: Dir - Root | (one d.parent && one contents.d)
}
/**
* Only files may be linked (that is, have more than one entry)
* That is, all directories are the contents of at most one directory entry
*/
pred NoDirAliases {
all o: Dir | lone o.~contents
}
check { OneParent_buggyVersion => NoDirAliases } for 5 expect 1
check { OneParent_correctVersion => NoDirAliases } for 5 expect 0

View File

@@ -0,0 +1,83 @@
module examples/systems/marksweepgc
/*
* Model of mark and sweep garbage collection.
*/
// a node in the heap
sig Node {}
sig HeapState {
left, right : Node -> lone Node,
marked : set Node,
freeList : lone Node
}
pred clearMarks[hs, hs' : HeapState] {
// clear marked set
no hs'.marked
// left and right fields are unchanged
hs'.left = hs.left
hs'.right = hs.right
}
/**
* simulate the recursion of the mark() function using transitive closure
*/
fun reachable[hs: HeapState, n: Node] : set Node {
n + n.^(hs.left + hs.right)
}
pred mark[hs: HeapState, from : Node, hs': HeapState] {
hs'.marked = hs.reachable[from]
hs'.left = hs.left
hs'.right = hs.right
}
/**
* complete hack to simulate behavior of code to set freeList
*/
pred setFreeList[hs, hs': HeapState] {
// especially hackish
hs'.freeList.*(hs'.left) in (Node - hs.marked)
all n: Node |
(n !in hs.marked) => {
no hs'.right[n]
hs'.left[n] in (hs'.freeList.*(hs'.left))
n in hs'.freeList.*(hs'.left)
} else {
hs'.left[n] = hs.left[n]
hs'.right[n] = hs.right[n]
}
hs'.marked = hs.marked
}
pred GC[hs: HeapState, root : Node, hs': HeapState] {
some hs1, hs2: HeapState |
hs.clearMarks[hs1] && hs1.mark[root, hs2] && hs2.setFreeList[hs']
}
assert Soundness1 {
all h, h' : HeapState, root : Node |
h.GC[root, h'] =>
(all live : h.reachable[root] | {
h'.left[live] = h.left[live]
h'.right[live] = h.right[live]
})
}
assert Soundness2 {
all h, h' : HeapState, root : Node |
h.GC[root, h'] =>
no h'.reachable[root] & h'.reachable[h'.freeList]
}
assert Completeness {
all h, h' : HeapState, root : Node |
h.GC[root, h'] =>
(Node - h'.reachable[root]) in h'.reachable[h'.freeList]
}
check Soundness1 for 3 expect 0
check Soundness2 for 3 expect 0
check Completeness for 3 expect 0

217
samples/Alloy/views.als Normal file
View File

@@ -0,0 +1,217 @@
module examples/systems/views
/*
* Model of views in object-oriented programming.
*
* Two object references, called the view and the backing,
* are related by a view mechanism when changes to the
* backing are automatically propagated to the view. Note
* that the state of a view need not be a projection of the
* state of the backing; the keySet method of Map, for
* example, produces two view relationships, and for the
* one in which the map is modified by changes to the key
* set, the value of the new map cannot be determined from
* the key set. Note that in the iterator view mechanism,
* the iterator is by this definition the backing object,
* since changes are propagated from iterator to collection
* and not vice versa. Oddly, a reference may be a view of
* more than one backing: there can be two iterators on the
* same collection, eg. A reference cannot be a view under
* more than one view type.
*
* A reference is made dirty when it is a backing for a view
* with which it is no longer related by the view invariant.
* This usually happens when a view is modified, either
* directly or via another backing. For example, changing a
* collection directly when it has an iterator invalidates
* it, as does changing the collection through one iterator
* when there are others.
*
* More work is needed if we want to model more closely the
* failure of an iterator when its collection is invalidated.
*
* As a terminological convention, when there are two
* complementary view relationships, we will give them types
* t and t'. For example, KeySetView propagates from map to
* set, and KeySetView' propagates from set to map.
*
* author: Daniel Jackson
*/
open util/ordering[State] as so
open util/relation as rel
sig Ref {}
sig Object {}
-- t->b->v in views when v is view of type t of backing b
-- dirty contains refs that have been invalidated
sig State {
refs: set Ref,
obj: refs -> one Object,
views: ViewType -> refs -> refs,
dirty: set refs
-- , anyviews: Ref -> Ref -- for visualization
}
-- {anyviews = ViewType.views}
sig Map extends Object {
keys: set Ref,
map: keys -> one Ref
}{all s: State | keys + Ref.map in s.refs}
sig MapRef extends Ref {}
fact {State.obj[MapRef] in Map}
sig Iterator extends Object {
left, done: set Ref,
lastRef: lone done
}{all s: State | done + left + lastRef in s.refs}
sig IteratorRef extends Ref {}
fact {State.obj[IteratorRef] in Iterator}
sig Set extends Object {
elts: set Ref
}{all s: State | elts in s.refs}
sig SetRef extends Ref {}
fact {State.obj[SetRef] in Set}
abstract sig ViewType {}
one sig KeySetView, KeySetView', IteratorView extends ViewType {}
fact ViewTypes {
State.views[KeySetView] in MapRef -> SetRef
State.views[KeySetView'] in SetRef -> MapRef
State.views[IteratorView] in IteratorRef -> SetRef
all s: State | s.views[KeySetView] = ~(s.views[KeySetView'])
}
/**
* mods is refs modified directly or by view mechanism
* doesn't handle possibility of modifying an object and its view at once?
* should we limit frame conds to non-dirty refs?
*/
pred modifies [pre, post: State, rs: set Ref] {
let vr = pre.views[ViewType], mods = rs.*vr {
all r: pre.refs - mods | pre.obj[r] = post.obj[r]
all b: mods, v: pre.refs, t: ViewType |
b->v in pre.views[t] => viewFrame [t, pre.obj[v], post.obj[v], post.obj[b]]
post.dirty = pre.dirty +
{b: pre.refs | some v: Ref, t: ViewType |
b->v in pre.views[t] && !viewFrame [t, pre.obj[v], post.obj[v], post.obj[b]]
}
}
}
pred allocates [pre, post: State, rs: set Ref] {
no rs & pre.refs
post.refs = pre.refs + rs
}
/**
* models frame condition that limits change to view object from v to v' when backing object changes to b'
*/
pred viewFrame [t: ViewType, v, v', b': Object] {
t in KeySetView => v'.elts = dom [b'.map]
t in KeySetView' => b'.elts = dom [v'.map]
t in KeySetView' => (b'.elts) <: (v.map) = (b'.elts) <: (v'.map)
t in IteratorView => v'.elts = b'.left + b'.done
}
pred MapRef.keySet [pre, post: State, setRefs: SetRef] {
post.obj[setRefs].elts = dom [pre.obj[this].map]
modifies [pre, post, none]
allocates [pre, post, setRefs]
post.views = pre.views + KeySetView->this->setRefs + KeySetView'->setRefs->this
}
pred MapRef.put [pre, post: State, k, v: Ref] {
post.obj[this].map = pre.obj[this].map ++ k->v
modifies [pre, post, this]
allocates [pre, post, none]
post.views = pre.views
}
pred SetRef.iterator [pre, post: State, iterRef: IteratorRef] {
let i = post.obj[iterRef] {
i.left = pre.obj[this].elts
no i.done + i.lastRef
}
modifies [pre,post,none]
allocates [pre, post, iterRef]
post.views = pre.views + IteratorView->iterRef->this
}
pred IteratorRef.remove [pre, post: State] {
let i = pre.obj[this], i' = post.obj[this] {
i'.left = i.left
i'.done = i.done - i.lastRef
no i'.lastRef
}
modifies [pre,post,this]
allocates [pre, post, none]
pre.views = post.views
}
pred IteratorRef.next [pre, post: State, ref: Ref] {
let i = pre.obj[this], i' = post.obj[this] {
ref in i.left
i'.left = i.left - ref
i'.done = i.done + ref
i'.lastRef = ref
}
modifies [pre, post, this]
allocates [pre, post, none]
pre.views = post.views
}
pred IteratorRef.hasNext [s: State] {
some s.obj[this].left
}
assert zippishOK {
all
ks, vs: SetRef,
m: MapRef,
ki, vi: IteratorRef,
k, v: Ref |
let s0=so/first,
s1=so/next[s0],
s2=so/next[s1],
s3=so/next[s2],
s4=so/next[s3],
s5=so/next[s4],
s6=so/next[s5],
s7=so/next[s6] |
({
precondition [s0, ks, vs, m]
no s0.dirty
ks.iterator [s0, s1, ki]
vs.iterator [s1, s2, vi]
ki.hasNext [s2]
vi.hasNext [s2]
ki.this/next [s2, s3, k]
vi.this/next [s3, s4, v]
m.put [s4, s5, k, v]
ki.remove [s5, s6]
vi.remove [s6, s7]
} => no State.dirty)
}
pred precondition [pre: State, ks, vs, m: Ref] {
// all these conditions and other errors discovered in scope of 6 but 8,3
// in initial state, must have view invariants hold
(all t: ViewType, b, v: pre.refs |
b->v in pre.views[t] => viewFrame [t, pre.obj[v], pre.obj[v], pre.obj[b]])
// sets are not aliases
-- ks != vs
// sets are not views of map
-- no (ks+vs)->m & ViewType.pre.views
// no iterator currently on either set
-- no Ref->(ks+vs) & ViewType.pre.views
}
check zippishOK for 6 but 8 State, 3 ViewType expect 1
/**
* experiment with controlling heap size
*/
fact {all s: State | #s.obj < 5}

View File

@@ -0,0 +1,13 @@
Gregory Romé has written an AsciiDoc plugin for the Redmine project management application.
https://github.com/foo-users/foo
へと `vicmd` キーマップを足してみている試み、
アニメーションgifです。
tag::romé[]
Gregory Romé has written an AsciiDoc plugin for the Redmine project management application.
end::romé[]
== Überschrift
* Codierungen sind verrückt auf älteren Versionen von Ruby

10
samples/AsciiDoc/list.asc Normal file
View File

@@ -0,0 +1,10 @@
AsciiDoc Home Page
==================
Example Articles
~~~~~~~~~~~~~~~~
- Item 1
- Item 2
- Item 3

View File

@@ -0,0 +1,25 @@
Document Title
==============
Doc Writer <thedoc@asciidoctor.org>
:idprefix: id_
Preamble paragraph.
NOTE: This is test, only a test.
== Section A
*Section A* paragraph.
=== Section A Subsection
*Section A* 'subsection' paragraph.
== Section B
*Section B* paragraph.
.Section B list
* Item 1
* Item 2
* Item 3

View File

@@ -0,0 +1,41 @@
package com.blogspot.miguelinlas3.aspectj.cache;
import java.util.Map;
import java.util.WeakHashMap;
import org.aspectj.lang.JoinPoint;
import com.blogspot.miguelinlas3.aspectj.cache.marker.Cachable;
/**
* This simple aspect simulates the behaviour of a very simple cache
*
* @author migue
*
*/
public aspect CacheAspect {
public pointcut cache(Cachable cachable): execution(@Cachable * * (..)) && @annotation(cachable);
Object around(Cachable cachable): cache(cachable){
String evaluatedKey = this.evaluateKey(cachable.scriptKey(), thisJoinPoint);
if(cache.containsKey(evaluatedKey)){
System.out.println("Cache hit for key " + evaluatedKey);
return this.cache.get(evaluatedKey);
}
System.out.println("Cache miss for key " + evaluatedKey);
Object value = proceed(cachable);
cache.put(evaluatedKey, value);
return value;
}
protected String evaluateKey(String key, JoinPoint joinPoint) {
// TODO add some smart staff to allow simple scripting in @Cachable annotation
return key;
}
protected Map<String, Object> cache = new WeakHashMap<String, Object>();
}

View File

@@ -0,0 +1,50 @@
package aspects.caching;
import java.util.Map;
/**
* Cache aspect for optimize recursive functions.
*
* @author Migueli
* @date 05/11/2013
* @version 1.0
*
*/
public abstract aspect OptimizeRecursionCache {
@SuppressWarnings("rawtypes")
private Map _cache;
public OptimizeRecursionCache() {
_cache = getCache();
}
@SuppressWarnings("rawtypes")
abstract public Map getCache();
abstract public pointcut operation(Object o);
pointcut topLevelOperation(Object o): operation(o) && !cflowbelow(operation(Object));
before(Object o) : topLevelOperation(o) {
System.out.println("Seeking value for " + o);
}
Object around(Object o) : operation(o) {
Object cachedValue = _cache.get(o);
if (cachedValue != null) {
System.out.println("Found cached value for " + o + ": " + cachedValue);
return cachedValue;
}
return proceed(o);
}
@SuppressWarnings("unchecked")
after(Object o) returning(Object result) : topLevelOperation(o) {
_cache.put(o, result);
}
after(Object o) returning(Object result) : topLevelOperation(o) {
System.out.println("cache size: " + _cache.size());
}
}

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,147 @@
Local bk = CreateBank(8)
PokeFloat bk, 0, -1
Print Bin(PeekInt(bk, 0))
Print %1000000000000000
Print Bin(1 Shl 31)
Print $1f
Print $ff
Print $1f + (127 - 15)
Print Hex(%01111111100000000000000000000000)
Print Hex(~%11111111100000000000000000000000)
Print Bin(FloatToHalf(-2.5))
Print HalfToFloat(FloatToHalf(-200000000000.0))
Print Bin(FToI(-2.5))
WaitKey
End
; Half-precision (16-bit) arithmetic library
;============================================
Global Half_CBank_
Function FToI(f#)
If Half_CBank_ = 0 Then Half_CBank_ = CreateBank(4)
PokeFloat Half_CBank_, 0, f
Return PeekInt(Half_CBank_, 0)
End Function
Function HalfToFloat#(h)
Local signBit, exponent, fraction, fBits
signBit = (h And 32768) <> 0
exponent = (h And %0111110000000000) Shr 10
fraction = (h And %0000001111111111)
If exponent = $1F Then exponent = $FF : ElseIf exponent Then exponent = (exponent - 15) + 127
fBits = (signBit Shl 31) Or (exponent Shl 23) Or (fraction Shl 13)
If Half_CBank_ = 0 Then Half_CBank_ = CreateBank(4)
PokeInt Half_CBank_, 0, fBits
Return PeekFloat(Half_CBank_, 0)
End Function
Function FloatToHalf(f#)
Local signBit, exponent, fraction, fBits
If Half_CBank_ = 0 Then Half_CBank_ = CreateBank(4)
PokeFloat Half_CBank_, 0, f
fBits = PeekInt(Half_CBank_, 0)
signBit = (fBits And (1 Shl 31)) <> 0
exponent = (fBits And $7F800000) Shr 23
fraction = fBits And $007FFFFF
If exponent
exponent = exponent - 127
If Abs(exponent) > $1F
If exponent <> ($FF - 127) Then fraction = 0
exponent = $1F * Sgn(exponent)
Else
exponent = exponent + 15
EndIf
exponent = exponent And %11111
EndIf
fraction = fraction Shr 13
Return (signBit Shl 15) Or (exponent Shl 10) Or fraction
End Function
Function HalfAdd(l, r)
End Function
Function HalfSub(l, r)
End Function
Function HalfMul(l, r)
End Function
Function HalfDiv(l, r)
End Function
Function HalfLT(l, r)
End Function
Function HalfGT(l, r)
End Function
; Double-precision (64-bit) arithmetic library)
;===============================================
Global DoubleOut[1], Double_CBank_
Function DoubleToFloat#(d[1])
End Function
Function FloatToDouble(f#)
End Function
Function IntToDouble(i)
End Function
Function SefToDouble(s, e, f)
End Function
Function DoubleAdd(l, r)
End Function
Function DoubleSub(l, r)
End Function
Function DoubleMul(l, r)
End Function
Function DoubleDiv(l, r)
End Function
Function DoubleLT(l, r)
End Function
Function DoubleGT(l, r)
End Function
;~IDEal Editor Parameters:
;~F#1A#20#2F
;~C#Blitz3D

369
samples/BlitzBasic/LList.bb Normal file
View File

@@ -0,0 +1,369 @@
; Double-linked list container class
;====================================
; with thanks to MusicianKool, for concept and issue fixes
Type LList
Field head_.ListNode
Field tail_.ListNode
End Type
Type ListNode
Field pv_.ListNode
Field nx_.ListNode
Field Value
End Type
Type Iterator
Field Value
Field l_.LList
Field cn_.ListNode, cni_
End Type
;Create a new LList object
Function CreateList.LList()
Local l.LList = New LList
l\head_ = New ListNode
l\tail_ = New ListNode
l\head_\nx_ = l\tail_ ;End caps
l\head_\pv_ = l\head_ ;These make it more or less safe to iterate freely
l\head_\Value = 0
l\tail_\nx_ = l\tail_
l\tail_\pv_ = l\head_
l\tail_\Value = 0
Return l
End Function
;Free a list and all elements (not any values)
Function FreeList(l.LList)
ClearList l
Delete l\head_
Delete l\tail_
Delete l
End Function
;Remove all the elements from a list (does not free values)
Function ClearList(l.LList)
Local n.ListNode = l\head_\nx_
While n <> l\tail_
Local nx.ListNode = n\nx_
Delete n
n = nx
Wend
l\head_\nx_ = l\tail_
l\tail_\pv_ = l\head_
End Function
;Count the number of elements in a list (slow)
Function ListLength(l.LList)
Local i.Iterator = GetIterator(l), elems
While EachIn(i)
elems = elems + 1
Wend
Return elems
End Function
;Return True if a list contains a given value
Function ListContains(l.LList, Value)
Return (ListFindNode(l, Value) <> Null)
End Function
;Create a linked list from the intvalues in a bank (slow)
Function ListFromBank.LList(bank)
Local l.LList = CreateList()
Local size = BankSize(bank), p
For p = 0 To size - 4 Step 4
ListAddLast l, PeekInt(bank, p)
Next
Return l
End Function
;Create a bank containing all the values in a list (slow)
Function ListToBank(l.LList)
Local size = ListLength(l) * 4
Local bank = CreateBank(size)
Local i.Iterator = GetIterator(l), p = 0
While EachIn(i)
PokeInt bank, p, i\Value
p = p + 4
Wend
Return bank
End Function
;Swap the contents of two list objects
Function SwapLists(l1.LList, l2.LList)
Local tempH.ListNode = l1\head_, tempT.ListNode = l1\tail_
l1\head_ = l2\head_
l1\tail_ = l2\tail_
l2\head_ = tempH
l2\tail_ = tempT
End Function
;Create a new list containing the same values as the first
Function CopyList.LList(lo.LList)
Local ln.LList = CreateList()
Local i.Iterator = GetIterator(lo) : While EachIn(i)
ListAddLast ln, i\Value
Wend
Return ln
End Function
;Reverse the order of elements of a list
Function ReverseList(l.LList)
Local n1.ListNode, n2.ListNode, tmp.ListNode
n1 = l\head_
n2 = l\head_\nx_
While n1 <> l\tail_
n1\pv_ = n2
tmp = n2\nx_
n2\nx_ = n1
n1 = n2
n2 = tmp
Wend
tmp = l\head_
l\head_ = l\tail_
l\tail_ = tmp
l\head_\pv_ = l\head_
l\tail_\nx_ = l\tail_
End Function
;Search a list to retrieve the first node with the given value
Function ListFindNode.ListNode(l.LList, Value)
Local n.ListNode = l\head_\nx_
While n <> l\tail_
If n\Value = Value Then Return n
n = n\nx_
Wend
Return Null
End Function
;Append a value to the end of a list (fast) and return the node
Function ListAddLast.ListNode(l.LList, Value)
Local n.ListNode = New ListNode
n\pv_ = l\tail_\pv_
n\nx_ = l\tail_
n\Value = Value
l\tail_\pv_ = n
n\pv_\nx_ = n
Return n
End Function
;Attach a value to the start of a list (fast) and return the node
Function ListAddFirst.ListNode(l.LList, Value)
Local n.ListNode = New ListNode
n\pv_ = l\head_
n\nx_ = l\head_\nx_
n\Value = Value
l\head_\nx_ = n
n\nx_\pv_ = n
Return n
End Function
;Remove the first occurence of the given value from a list
Function ListRemove(l.LList, Value)
Local n.ListNode = ListFindNode(l, Value)
If n <> Null Then RemoveListNode n
End Function
;Remove a node from a list
Function RemoveListNode(n.ListNode)
n\pv_\nx_ = n\nx_
n\nx_\pv_ = n\pv_
Delete n
End Function
;Return the value of the element at the given position from the start of the list,
;or backwards from the end of the list for a negative index
Function ValueAtIndex(l.LList, index)
Local n.ListNode = ListNodeAtIndex(l, index)
If n <> Null Then Return n\Value : Else Return 0
End Function
;Return the ListNode at the given position from the start of the list, or backwards
;from the end of the list for a negative index, or Null if invalid
Function ListNodeAtIndex.ListNode(l.LList, index)
Local e, n.ListNode
If index >= 0
n = l\head_
For e = 0 To index
n = n\nx_
Next
If n = l\tail_ Then n = Null ;Beyond the end of the list - not valid
Else ;Negative index - count backward
n = l\tail_
For e = 0 To index Step -1
n = n\pv_
Next
If n = l\head_ Then n = Null ;Before the start of the list - not valid
EndIf
Return n
End Function
;Replace a value at the given position (added by MusicianKool)
Function ReplaceValueAtIndex(l.LList,index,value)
Local n.ListNode = ListNodeAtIndex(l,index)
If n <> Null Then n\Value = value:Else Return 0
End Function
;Remove and return a value at the given position (added by MusicianKool)
Function RemoveNodeAtIndex(l.LList,index)
Local n.ListNode = ListNodeAtIndex(l,index),tval
If n <> Null Then tval = n\Value:RemoveListNode(n):Return tval:Else Return 0
End Function
;Retrieve the first value from a list
Function ListFirst(l.LList)
If l\head_\nx_ <> l\tail_ Then Return l\head_\nx_\Value
End Function
;Retrieve the last value from a list
Function ListLast(l.LList)
If l\tail_\pv_ <> l\head_ Then Return l\tail_\pv_\Value
End Function
;Remove the first element from a list, and return its value
Function ListRemoveFirst(l.LList)
Local val
If l\head_\nx_ <> l\tail_
val = l\head_\nx_\Value
RemoveListNode l\head_\nx_
EndIf
Return val
End Function
;Remove the last element from a list, and return its value
Function ListRemoveLast(l.LList)
Local val
If l\tail_\pv_ <> l\head_
val = l\tail_\pv_\Value
RemoveListNode l\tail_\pv_
EndIf
Return val
End Function
;Insert a value into a list before the specified node, and return the new node
Function InsertBeforeNode.ListNode(Value, n.ListNode)
Local bef.ListNode = New ListNode
bef\pv_ = n\pv_
bef\nx_ = n
bef\Value = Value
n\pv_ = bef
bef\pv_\nx_ = bef
Return bef
End Function
;Insert a value into a list after the specified node, and return then new node
Function InsertAfterNode.ListNode(Value, n.ListNode)
Local aft.ListNode = New ListNode
aft\nx_ = n\nx_
aft\pv_ = n
aft\Value = Value
n\nx_ = aft
aft\nx_\pv_ = aft
Return aft
End Function
;Get an iterator object to use with a loop
;This function means that most programs won't have to think about deleting iterators manually
;(in general only a small, constant number will be created)
Function GetIterator.Iterator(l.LList)
Local i.Iterator
If l = Null Then RuntimeError "Cannot create Iterator for Null"
For i = Each Iterator ;See if there's an available iterator at the moment
If i\l_ = Null Then Exit
Next
If i = Null Then i = New Iterator ;If there wasn't, create one
i\l_ = l
i\cn_ = l\head_
i\cni_ = -1
i\Value = 0 ;No especial reason why this has to be anything, but meh
Return i
End Function
;Use as the argument to While to iterate over the members of a list
Function EachIn(i.Iterator)
i\cn_ = i\cn_\nx_
If i\cn_ <> i\l_\tail_ ;Still items in the list
i\Value = i\cn_\Value
i\cni_ = i\cni_ + 1
Return True
Else
i\l_ = Null ;Disconnect from the list, having reached the end
i\cn_ = Null
i\cni_ = -1
Return False
EndIf
End Function
;Remove from the containing list the element currently pointed to by an iterator
Function IteratorRemove(i.Iterator)
If (i\cn_ <> i\l_\head_) And (i\cn_ <> i\l_\tail_)
Local temp.ListNode = i\cn_
i\cn_ = i\cn_\pv_
i\cni_ = i\cni_ - 1
i\Value = 0
RemoveListNode temp
Return True
Else
Return False
EndIf
End Function
;Call this before breaking out of an EachIn loop, to disconnect the iterator from the list
Function IteratorBreak(i.Iterator)
i\l_ = Null
i\cn_ = Null
i\cni_ = -1
i\Value = 0
End Function
;~IDEal Editor Parameters:
;~F#5#A#10#18#2A#32#3E#47#4C#58#66#6F#78#8F#9B#A9#B7#BD#C5#CC
;~F#E3#E9#EF#F4#F9#103#10D#11B#12B#13F#152#163
;~C#Blitz3D

View File

@@ -0,0 +1,66 @@
Local i, start, result
Local s.Sum3Obj = New Sum3Obj
For i = 1 To 100000
s = New Sum3Obj
result = Handle Before s
Delete s
Next
start = MilliSecs()
For i = 1 To 1000000
result = Sum3_(MakeSum3Obj(i, i, i))
Next
start = MilliSecs() - start
Print start
start = MilliSecs()
For i = 1 To 1000000
result = Sum3(i, i, i)
Next
start = MilliSecs() - start
Print start
WaitKey
End
Function Sum3(a, b, c)
Return a + b + c
End Function
Type Sum3Obj
Field isActive
Field a, b, c
End Type
Function MakeSum3Obj(a, b, c)
Local s.Sum3Obj = Last Sum3Obj
If s\isActive Then s = New Sum3Obj
s\isActive = True
s\a = a
s\b = b
s\c = c
Restore label
Read foo
Return Handle(s)
End Function
.label
Data (10 + 2), 12, 14
:
Function Sum3_(a_)
Local a.Sum3Obj = Object.Sum3Obj a_
Local return_ = a\a + a\b + a\c
Insert a Before First Sum3Obj :: a\isActive = False
Return return_
End Function
;~IDEal Editor Parameters:
;~C#Blitz3D

167
samples/Bluespec/TL.bsv Normal file
View File

@@ -0,0 +1,167 @@
package TL;
interface TL;
method Action ped_button_push();
(* always_enabled *)
method Action set_car_state_N(Bool x);
(* always_enabled *)
method Action set_car_state_S(Bool x);
(* always_enabled *)
method Action set_car_state_E(Bool x);
(* always_enabled *)
method Action set_car_state_W(Bool x);
method Bool lampRedNS();
method Bool lampAmberNS();
method Bool lampGreenNS();
method Bool lampRedE();
method Bool lampAmberE();
method Bool lampGreenE();
method Bool lampRedW();
method Bool lampAmberW();
method Bool lampGreenW();
method Bool lampRedPed();
method Bool lampAmberPed();
method Bool lampGreenPed();
endinterface: TL
typedef enum {
AllRed,
GreenNS, AmberNS,
GreenE, AmberE,
GreenW, AmberW,
GreenPed, AmberPed} TLstates deriving (Eq, Bits);
typedef UInt#(5) Time32;
typedef UInt#(20) CtrSize;
(* synthesize *)
module sysTL(TL);
Time32 allRedDelay = 2;
Time32 amberDelay = 4;
Time32 nsGreenDelay = 20;
Time32 ewGreenDelay = 10;
Time32 pedGreenDelay = 10;
Time32 pedAmberDelay = 6;
CtrSize clocks_per_sec = 100;
Reg#(TLstates) state <- mkReg(AllRed);
Reg#(TLstates) next_green <- mkReg(GreenNS);
Reg#(Time32) secs <- mkReg(0);
Reg#(Bool) ped_button_pushed <- mkReg(False);
Reg#(Bool) car_present_N <- mkReg(True);
Reg#(Bool) car_present_S <- mkReg(True);
Reg#(Bool) car_present_E <- mkReg(True);
Reg#(Bool) car_present_W <- mkReg(True);
Bool car_present_NS = car_present_N || car_present_S;
Reg#(CtrSize) cycle_ctr <- mkReg(0);
rule dec_cycle_ctr (cycle_ctr != 0);
cycle_ctr <= cycle_ctr - 1;
endrule
Rules low_priority_rule = (rules
rule inc_sec (cycle_ctr == 0);
secs <= secs + 1;
cycle_ctr <= clocks_per_sec;
endrule endrules);
function Action next_state(TLstates ns);
action
state <= ns;
secs <= 0;
endaction
endfunction: next_state
function TLstates green_seq(TLstates x);
case (x)
GreenNS: return (GreenE);
GreenE: return (GreenW);
GreenW: return (GreenNS);
endcase
endfunction
function Bool car_present(TLstates x);
case (x)
GreenNS: return (car_present_NS);
GreenE: return (car_present_E);
GreenW: return (car_present_W);
endcase
endfunction
function Rules make_from_green_rule(TLstates green_state, Time32 delay, Bool car_is_present, TLstates ns);
return (rules
rule from_green (state == green_state && (secs >= delay || !car_is_present));
next_state(ns);
endrule endrules);
endfunction: make_from_green_rule
function Rules make_from_amber_rule(TLstates amber_state, TLstates ng);
return (rules
rule from_amber (state == amber_state && secs >= amberDelay);
next_state(AllRed);
next_green <= ng;
endrule endrules);
endfunction: make_from_amber_rule
Rules hprs[7];
hprs[1] = make_from_green_rule(GreenNS, nsGreenDelay, car_present_NS, AmberNS);
hprs[2] = make_from_amber_rule(AmberNS, GreenE);
hprs[3] = make_from_green_rule(GreenE, ewGreenDelay, car_present_E, AmberE);
hprs[4] = make_from_amber_rule(AmberE, GreenW);
hprs[5] = make_from_green_rule(GreenW, ewGreenDelay, car_present_W, AmberW);
hprs[6] = make_from_amber_rule(AmberW, GreenNS);
hprs[0] = (rules
rule fromAllRed (state == AllRed && secs >= allRedDelay);
if (ped_button_pushed) action
ped_button_pushed <= False;
next_state(GreenPed);
endaction else if (car_present(next_green))
next_state(next_green);
else if (car_present(green_seq(next_green)))
next_state(green_seq(next_green));
else if (car_present(green_seq(green_seq(next_green))))
next_state(green_seq(green_seq(next_green)));
else
noAction;
endrule: fromAllRed endrules);
Rules high_priority_rules = hprs[0];
for (Integer i = 1; i<7; i=i+1)
high_priority_rules = rJoin(hprs[i], high_priority_rules);
addRules(preempts(high_priority_rules, low_priority_rule));
method Action ped_button_push();
ped_button_pushed <= True;
endmethod: ped_button_push
method Action set_car_state_N(b) ; car_present_N <= b; endmethod
method Action set_car_state_S(b) ; car_present_S <= b; endmethod
method Action set_car_state_E(b) ; car_present_E <= b; endmethod
method Action set_car_state_W(b) ; car_present_W <= b; endmethod
method lampRedNS() = (!(state == GreenNS || state == AmberNS));
method lampAmberNS() = (state == AmberNS);
method lampGreenNS() = (state == GreenNS);
method lampRedE() = (!(state == GreenE || state == AmberE));
method lampAmberE() = (state == AmberE);
method lampGreenE() = (state == GreenE);
method lampRedW() = (!(state == GreenW || state == AmberW));
method lampAmberW() = (state == AmberW);
method lampGreenW() = (state == GreenW);
method lampRedPed() = (!(state == GreenPed || state == AmberPed));
method lampAmberPed() = (state == AmberPed);
method lampGreenPed() = (state == GreenPed);
endmodule: sysTL
endpackage: TL

109
samples/Bluespec/TbTL.bsv Normal file
View File

@@ -0,0 +1,109 @@
package TbTL;
import TL::*;
interface Lamp;
method Bool changed;
method Action show_offs;
method Action show_ons;
method Action reset;
endinterface
module mkLamp#(String name, Bool lamp)(Lamp);
Reg#(Bool) prev <- mkReg(False);
method changed = (prev != lamp);
method Action show_offs;
if (prev && !lamp)
$write (name + " off, ");
endmethod
method Action show_ons;
if (!prev && lamp)
$write (name + " on, ");
endmethod
method Action reset;
prev <= lamp;
endmethod
endmodule
(* synthesize *)
module mkTest();
let dut <- sysTL;
Reg#(Bit#(16)) ctr <- mkReg(0);
Reg#(Bool) carN <- mkReg(False);
Reg#(Bool) carS <- mkReg(False);
Reg#(Bool) carE <- mkReg(False);
Reg#(Bool) carW <- mkReg(False);
Lamp lamps[12];
lamps[0] <- mkLamp("0: NS red ", dut.lampRedNS);
lamps[1] <- mkLamp("1: NS amber", dut.lampAmberNS);
lamps[2] <- mkLamp("2: NS green", dut.lampGreenNS);
lamps[3] <- mkLamp("3: E red ", dut.lampRedE);
lamps[4] <- mkLamp("4: E amber", dut.lampAmberE);
lamps[5] <- mkLamp("5: E green", dut.lampGreenE);
lamps[6] <- mkLamp("6: W red ", dut.lampRedW);
lamps[7] <- mkLamp("7: W amber", dut.lampAmberW);
lamps[8] <- mkLamp("8: W green", dut.lampGreenW);
lamps[9] <- mkLamp("9: Ped red ", dut.lampRedPed);
lamps[10] <- mkLamp("10: Ped amber", dut.lampAmberPed);
lamps[11] <- mkLamp("11: Ped green", dut.lampGreenPed);
rule start (ctr == 0);
$dumpvars;
endrule
rule detect_cars;
dut.set_car_state_N(carN);
dut.set_car_state_S(carS);
dut.set_car_state_E(carE);
dut.set_car_state_W(carW);
endrule
rule go;
ctr <= ctr + 1;
if (ctr == 5000) carN <= True;
if (ctr == 6500) carN <= False;
if (ctr == 12_000) dut.ped_button_push;
endrule
rule stop (ctr > 32768);
$display("TESTS FINISHED");
$finish(0);
endrule
function do_offs(l) = l.show_offs;
function do_ons(l) = l.show_ons;
function do_reset(l) = l.reset;
function do_it(f);
action
for (Integer i=0; i<12; i=i+1)
f(lamps[i]);
endaction
endfunction
function any_changes();
Bool b = False;
for (Integer i=0; i<12; i=i+1)
b = b || lamps[i].changed;
return b;
endfunction
rule show (any_changes());
do_it(do_offs);
do_it(do_ons);
do_it(do_reset);
$display("(at time %d)", $time);
endrule
endmodule
endpackage

View File

@@ -0,0 +1,305 @@
' *********************************************************
' ** Simple Grid Screen Demonstration App
' ** Jun 2010
' ** Copyright (c) 2010 Roku Inc. All Rights Reserved.
' *********************************************************
'************************************************************
'** Application startup
'************************************************************
Sub Main()
'initialize theme attributes like titles, logos and overhang color
initTheme()
gridstyle = "Flat-Movie"
'set to go, time to get started
while gridstyle <> ""
print "starting grid style= ";gridstyle
screen=preShowGridScreen(gridstyle)
gridstyle = showGridScreen(screen, gridstyle)
end while
End Sub
'*************************************************************
'** Set the configurable theme attributes for the application
'**
'** Configure the custom overhang and Logo attributes
'** These attributes affect the branding of the application
'** and are artwork, colors and offsets specific to the app
'*************************************************************
Sub initTheme()
app = CreateObject("roAppManager")
app.SetTheme(CreateDefaultTheme())
End Sub
'******************************************************
'** @return The default application theme.
'** Screens can make slight adjustments to the default
'** theme by getting it from here and then overriding
'** individual theme attributes.
'******************************************************
Function CreateDefaultTheme() as Object
theme = CreateObject("roAssociativeArray")
theme.ThemeType = "generic-dark"
' All these are greyscales
theme.GridScreenBackgroundColor = "#363636"
theme.GridScreenMessageColor = "#808080"
theme.GridScreenRetrievingColor = "#CCCCCC"
theme.GridScreenListNameColor = "#FFFFFF"
' Color values work here
theme.GridScreenDescriptionTitleColor = "#001090"
theme.GridScreenDescriptionDateColor = "#FF005B"
theme.GridScreenDescriptionRuntimeColor = "#5B005B"
theme.GridScreenDescriptionSynopsisColor = "#606000"
'used in the Grid Screen
theme.CounterTextLeft = "#FF0000"
theme.CounterSeparator = "#00FF00"
theme.CounterTextRight = "#0000FF"
theme.GridScreenLogoHD = "pkg:/images/Overhang_Test_HD.png"
theme.GridScreenLogoOffsetHD_X = "0"
theme.GridScreenLogoOffsetHD_Y = "0"
theme.GridScreenOverhangHeightHD = "99"
theme.GridScreenLogoSD = "pkg:/images/Overhang_Test_SD43.png"
theme.GridScreenOverhangHeightSD = "66"
theme.GridScreenLogoOffsetSD_X = "0"
theme.GridScreenLogoOffsetSD_Y = "0"
' to use your own focus ring artwork
'theme.GridScreenFocusBorderSD = "pkg:/images/GridCenter_Border_Movies_SD43.png"
'theme.GridScreenBorderOffsetSD = "(-26,-25)"
'theme.GridScreenFocusBorderHD = "pkg:/images/GridCenter_Border_Movies_HD.png"
'theme.GridScreenBorderOffsetHD = "(-28,-20)"
' to use your own description background artwork
'theme.GridScreenDescriptionImageSD = "pkg:/images/Grid_Description_Background_SD43.png"
'theme.GridScreenDescriptionOffsetSD = "(125,170)"
'theme.GridScreenDescriptionImageHD = "pkg:/images/Grid_Description_Background_HD.png"
'theme.GridScreenDescriptionOffsetHD = "(190,255)"
return theme
End Function
'******************************************************
'** Perform any startup/initialization stuff prior to
'** initially showing the screen.
'******************************************************
Function preShowGridScreen(style as string) As Object
m.port=CreateObject("roMessagePort")
screen = CreateObject("roGridScreen")
screen.SetMessagePort(m.port)
' screen.SetDisplayMode("best-fit")
screen.SetDisplayMode("scale-to-fill")
screen.SetGridStyle(style)
return screen
End Function
'******************************************************
'** Display the gird screen and wait for events from
'** the screen. The screen will show retreiving while
'** we fetch and parse the feeds for the show posters
'******************************************************
Function showGridScreen(screen As Object, gridstyle as string) As string
print "enter showGridScreen"
categoryList = getCategoryList()
categoryList[0] = "GridStyle: " + gridstyle
screen.setupLists(categoryList.count())
screen.SetListNames(categoryList)
StyleButtons = getGridControlButtons()
screen.SetContentList(0, StyleButtons)
for i = 1 to categoryList.count()-1
screen.SetContentList(i, getShowsForCategoryItem(categoryList[i]))
end for
screen.Show()
while true
print "Waiting for message"
msg = wait(0, m.port)
'msg = wait(0, screen.GetMessagePort()) ' getmessageport does not work on gridscreen
print "Got Message:";type(msg)
if type(msg) = "roGridScreenEvent" then
print "msg= "; msg.GetMessage() " , index= "; msg.GetIndex(); " data= "; msg.getData()
if msg.isListItemFocused() then
print"list item focused | current show = "; msg.GetIndex()
else if msg.isListItemSelected() then
row = msg.GetIndex()
selection = msg.getData()
print "list item selected row= "; row; " selection= "; selection
' Did we get a selection from the gridstyle selection row?
if (row = 0)
' yes, return so we can come back with new style
return StyleButtons[selection].Title
endif
'm.curShow = displayShowDetailScreen(showList[msg.GetIndex()])
else if msg.isScreenClosed() then
return ""
end if
end If
end while
End Function
'**********************************************************
'** When a poster on the home screen is selected, we call
'** this function passing an roAssociativeArray with the
'** ContentMetaData for the selected show. This data should
'** be sufficient for the springboard to display
'**********************************************************
Function displayShowDetailScreen(category as Object, showIndex as Integer) As Integer
'add code to create springboard, for now we do nothing
return 1
End Function
'**************************************************************
'** Return the list of categories to display in the filter
'** banner. The result is an roArray containing the names of
'** all of the categories. All just static data for the example.
'***************************************************************
Function getCategoryList() As Object
categoryList = [ "GridStyle", "Reality", "History", "News", "Comedy", "Drama"]
return categoryList
End Function
'********************************************************************
'** Given the category from the filter banner, return an array
'** of ContentMetaData objects (roAssociativeArray's) representing
'** the shows for the category. For this example, we just cheat and
'** create and return a static array with just the minimal items
'** set, but ideally, you'd go to a feed service, fetch and parse
'** this data dynamically, so content for each category is dynamic
'********************************************************************
Function getShowsForCategoryItem(category As Object) As Object
print "getting shows for category "; category
showList = [
{
Title: category + ": Header",
releaseDate: "1976",
length: 3600-600,
Description:"This row is category " + category,
hdBranded: true,
HDPosterUrl:"http://upload.wikimedia.org/wikipedia/commons/4/43/Gold_star_on_blue.gif",
SDPosterUrl:"http://upload.wikimedia.org/wikipedia/commons/4/43/Gold_star_on_blue.gif",
Description:"Short Synopsis #1",
Synopsis:"Length",
StarRating:10,
}
{
Title: category + ": Beverly Hillbillies",
releaseDate: "1969",
rating: "PG",
Description:"Come and listen to a story about a man named Jed: Poor mountaineer, barely kept his family fed. Then one day he was shootin at some food, and up through the ground came a bubblin crude. Oil that is, black gold, Texas tea.",
numEpisodes:42,
contentType:"season",
HDPosterUrl:"http://upload.wikimedia.org/wikipedia/en/4/4e/The_Beverly_Hillbillies.jpg",
SDPosterUrl:"http://upload.wikimedia.org/wikipedia/en/4/4e/The_Beverly_Hillbillies.jpg",
StarRating:80,
UserStarRating:40
}
{
Title: category + ": Babylon 5",
releaseDate: "1996",
rating: "PG",
Description:"The show centers on the Babylon 5 space station: a focal point for politics, diplomacy, and conflict during the years 2257-2262.",
numEpisodes:102,
contentType:"season",
HDPosterUrl:"http://upload.wikimedia.org/wikipedia/en/9/9d/Smb5-s4.jpg",
SDPosterUrl:"http://upload.wikimedia.org/wikipedia/en/9/9d/Smb5-s4.jpg",
StarRating:80,
UserStarRating:40
}
{
Title: category + ": John F. Kennedy",
releaseDate: "1961",
rating: "PG",
Description:"My fellow citizens of the world: ask not what America will do for you, but what together we can do for the freedom of man.",
HDPosterUrl:"http://upload.wikimedia.org/wikipedia/en/5/52/Jfk_happy_birthday_1.jpg",
SDPosterUrl:"http://upload.wikimedia.org/wikipedia/en/5/52/Jfk_happy_birthday_1.jpg",
StarRating:100
}
{
Title: category + ": Man on the Moon",
releaseDate: "1969",
rating: "PG",
Description:"That's one small step for a man, one giant leap for mankind.",
HDPosterUrl:"http://upload.wikimedia.org/wikipedia/commons/1/1e/Apollo_11_first_step.jpg",
SDPosterUrl:"http://upload.wikimedia.org/wikipedia/commons/1/1e/Apollo_11_first_step.jpg",
StarRating:100
}
{
Title: category + ": I have a Dream",
releaseDate: "1963",
rating: "PG",
Description:"I have a dream that my four little children will one day live in a nation where they will not be judged by the color of their skin, but by the content of their character.",
HDPosterUrl:"http://upload.wikimedia.org/wikipedia/commons/8/81/Martin_Luther_King_-_March_on_Washington.jpg",
SDPosterUrl:"http://upload.wikimedia.org/wikipedia/commons/8/81/Martin_Luther_King_-_March_on_Washington.jpg",
StarRating:100
}
]
return showList
End Function
function getGridControlButtons() as object
buttons = [
{ Title: "Flat-Movie"
ReleaseDate: "HD:5x2 SD:5x2"
Description: "Flat-Movie (Netflix) style"
HDPosterUrl:"http://upload.wikimedia.org/wikipedia/commons/4/43/Gold_star_on_blue.gif"
SDPosterUrl:"http://upload.wikimedia.org/wikipedia/commons/4/43/Gold_star_on_blue.gif"
}
{ Title: "Flat-Landscape"
ReleaseDate: "HD:5x3 SD:4x3"
Description: "Channel Store"
HDPosterUrl:"http://upload.wikimedia.org/wikipedia/commons/thumb/9/96/Dunkery_Hill.jpg/800px-Dunkery_Hill.jpg",
SDPosterUrl:"http://upload.wikimedia.org/wikipedia/commons/thumb/9/96/Dunkery_Hill.jpg/800px-Dunkery_Hill.jpg",
}
{ Title: "Flat-Portrait"
ReleaseDate: "HD:5x2 SD:5x2"
Description: "3x4 style posters"
HDPosterUrl:"http://upload.wikimedia.org/wikipedia/commons/9/9f/Kane_George_Gurnett.jpg",
SDPosterUrl:"http://upload.wikimedia.org/wikipedia/commons/9/9f/Kane_George_Gurnett.jpg",
}
{ Title: "Flat-Square"
ReleaseDate: "HD:7x3 SD:6x3"
Description: "1x1 style posters"
HDPosterUrl:"http://upload.wikimedia.org/wikipedia/commons/thumb/d/de/SQUARE_SHAPE.svg/536px-SQUARE_SHAPE.svg.png",
SDPosterUrl:"http://upload.wikimedia.org/wikipedia/commons/thumb/d/de/SQUARE_SHAPE.svg/536px-SQUARE_SHAPE.svg.png",
}
{ Title: "Flat-16x9"
ReleaseDate: "HD:5x3 SD:4x3"
Description: "HD style posters"
HDPosterUrl:"http://upload.wikimedia.org/wikipedia/commons/thumb/2/22/%C3%89cran_TV_plat.svg/200px-%C3%89cran_TV_plat.svg.png",
SDPosterUrl:"http://upload.wikimedia.org/wikipedia/commons/thumb/2/22/%C3%89cran_TV_plat.svg/200px-%C3%89cran_TV_plat.svg.png",
}
]
return buttons
End Function

45
samples/C#/Index.cshtml Normal file
View File

@@ -0,0 +1,45 @@
@{
ViewBag.Title = "Home Page";
}
@section featured {
<section class="featured">
<div class="content-wrapper">
<hgroup class="title">
<h1>@ViewBag.Title.</h1>
<h2>@ViewBag.Message</h2>
</hgroup>
<p>
To learn more about ASP.NET MVC visit
<a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>.
The page features <mark>videos, tutorials, and samples</mark> to help you get the most from ASP.NET MVC.
If you have any questions about ASP.NET MVC visit
<a href="http://forums.asp.net/1146.aspx/1?MVC" title="ASP.NET MVC Forum">our forums</a>.
</p>
</div>
</section>
}
<h3>We suggest the following:</h3>
<ol class="round">
<li class="one">
<h5>Getting Started</h5>
ASP.NET MVC gives you a powerful, patterns-based way to build dynamic websites that
enables a clean separation of concerns and that gives you full control over markup
for enjoyable, agile development. ASP.NET MVC includes many features that enable
fast, TDD-friendly development for creating sophisticated applications that use
the latest web standards.
<a href="http://go.microsoft.com/fwlink/?LinkId=245151">Learn more…</a>
</li>
<li class="two">
<h5>Add NuGet packages and jump-start your coding</h5>
NuGet makes it easy to install and update free libraries and tools.
<a href="http://go.microsoft.com/fwlink/?LinkId=245153">Learn more…</a>
</li>
<li class="three">
<h5>Find Web Hosting</h5>
You can easily find a web hosting company that offers the right mix of features
and price for your applications.
<a href="http://go.microsoft.com/fwlink/?LinkId=245157">Learn more…</a>
</li>
</ol>

21
samples/C#/Program.cs Normal file
View File

@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LittleSampleApp
{
/// <summary>
/// Just what it says on the tin. A little sample application for Linguist to try out.
///
/// </summary>
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello, I am a little sample application to test GitHub's Linguist module.");
Console.WriteLine("I also include a Razor MVC file just to prove it handles cshtml files now.");
}
}
}

42
samples/C++/CsvStreamer.h Normal file
View File

@@ -0,0 +1,42 @@
#pragma once
#include <string>
#include <vector>
#include <fstream>
#include "util.h"
using namespace std;
#define DEFAULT_DELIMITER ','
class CsvStreamer
{
private:
ofstream file; // File output stream
vector<string> row_buffer; // Buffer which stores a row's data before being flushed/written
int fields; // Number of fields (columns)
long rows; // Number of rows (records) including header row
char delimiter; // Delimiter character; comma by default
string sanitize(string); // Returns a string ready for output into the file
public:
CsvStreamer(); // Empty CSV streamer... be sure to open the file before writing!
CsvStreamer(string, char); // Same as open(string, char)...
CsvStreamer(string); // Opens an output CSV file given a file path/name
~CsvStreamer(); // Ensures the output file is closed and saved
void open(string); // Opens an output CSV file given a file path/name (default delimiter)
void open(string, char); // Opens an output CSV file given a file path/name and a delimiting character (default comma)
void add_field(string); // If still on first line, adds a new field to the header row
void save_fields(); // Call this to save the header row; all new writes should be through append()
void append(string); // Appends the current row with this data for the next field; quoted only if needed (leading/trailing spaces are trimmed)
void append(string, bool); // Like append(string) but can specify whether to trim spaces at either end of the data (false to keep spaces)
void append(float); // Appends the current row with this number
void append(double); // Appends the current row with this number
void append(long); // Appends the current row with this number
void append(int); // Appends the current row with this number
void writeln(); // Flushes what was in the row buffer into the file (writes the row)
void close(); // Saves and closes the file
int field_count(); // Gets the number of fields (columns)
long row_count(); // Gets the number of records (rows) -- NOT including the header row
};

32
samples/C++/Field.h Normal file
View File

@@ -0,0 +1,32 @@
/*****************************************************************************
* Dwarf Mine - The 13-11 Benchmark
*
* Copyright (c) 2013 Bünger, Thomas; Kieschnick, Christian; Kusber,
* Michael; Lohse, Henning; Wuttke, Nikolai; Xylander, Oliver; Yao, Gary;
* Zimmermann, Florian
*
* 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.
*****************************************************************************/
#pragma once
enum Field { Free, Black, White, Illegal };
typedef Field Player;

530
samples/C++/Math.inl Normal file
View File

@@ -0,0 +1,530 @@
/*
===========================================================================
The Open Game Libraries.
Copyright (C) 2007-2010 Lusito Software
Author: Santo Pfingsten (TTK-Bandit)
Purpose: Math namespace
-----------------------------------------
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
===========================================================================
*/
#ifndef __OG_MATH_INL__
#define __OG_MATH_INL__
namespace og {
/*
==============================================================================
Math
==============================================================================
*/
/*
================
Math::Abs
================
*/
OG_INLINE int Math::Abs( int i ) {
#if 1
if ( i & 0x80000000 )
return 0x80000000 - (i & MASK_SIGNED);
return i;
#else
int y = x >> 31;
return ( ( x ^ y ) - y );
#endif
}
/*
================
Math::Fabs
================
*/
OG_INLINE float Math::Fabs( float f ) {
#if 1
uInt *pf = reinterpret_cast<uInt*>(&f);
*(pf) &= MASK_SIGNED;
return f;
#else
return fabsf( f );
#endif
}
/*
================
Math::Round
================
*/
OG_INLINE float Math::Round( float f ) {
return floorf( f + 0.5f );
}
/*
================
Math::Floor
================
*/
OG_INLINE float Math::Floor( float f ) {
return floorf( f );
}
/*
================
Math::Ceil
================
*/
OG_INLINE float Math::Ceil( float f ) {
return ceilf( f );
}
/*
================
Math::Ftoi
ok since this is SSE, why should the other ftoi be the faster one ?
and: we might need to add a check for SSE extensions..
because sse isn't *really* faster (I actually read that GCC does not handle
SSE extensions perfectly. I'll find the link and send it to you when you're online)
================
*/
OG_INLINE int Math::Ftoi( float f ) {
//! @todo needs testing
// note: sse function cvttss2si
#if OG_ASM_MSVC
int i;
#if defined(OG_FTOI_USE_SSE)
if( SysInfo::cpu.general.SSE ) {
__asm cvttss2si eax, f
__asm mov i, eax
return i;
} else
#endif
{
__asm fld f
__asm fistp i
//__asm mov eax, i // do we need this ? O_o
}
return i;
#elif OG_ASM_GNU
int i;
#if defined(OG_FTOI_USE_SSE)
if( SysInfo::cpu.general.SSE ) {
__asm__ __volatile__( "cvttss2si %1 \n\t"
: "=m" (i)
: "m" (f)
);
} else
#endif
{
__asm__ __volatile__( "flds %1 \n\t"
"fistpl %0 \n\t"
: "=m" (i)
: "m" (f)
);
}
return i;
#else
// we use c++ cast instead of c cast (not sure why id did that)
return static_cast<int>(f);
#endif
}
/*
================
Math::FtoiFast
================
*/
OG_INLINE int Math::FtoiFast( float f ) {
#if OG_ASM_MSVC
int i;
__asm fld f
__asm fistp i
//__asm mov eax, i // do we need this ? O_o
return i;
#elif OG_ASM_GNU
int i;
__asm__ __volatile__( "flds %1 \n\t"
"fistpl %0 \n\t"
: "=m" (i)
: "m" (f)
);
return i;
#else
// we use c++ cast instead of c cast (not sure why id did that)
return static_cast<int>(f);
#endif
}
/*
================
Math::Ftol
================
*/
OG_INLINE long Math::Ftol( float f ) {
#if OG_ASM_MSVC
long i;
__asm fld f
__asm fistp i
//__asm mov eax, i // do we need this ? O_o
return i;
#elif OG_ASM_GNU
long i;
__asm__ __volatile__( "flds %1 \n\t"
"fistpl %0 \n\t"
: "=m" (i)
: "m" (f)
);
return i;
#else
// we use c++ cast instead of c cast (not sure why id did that)
return static_cast<long>(f);
#endif
}
/*
================
Math::Sign
================
*/
OG_INLINE float Math::Sign( float f ) {
if ( f > 0.0f )
return 1.0f;
if ( f < 0.0f )
return -1.0f;
return 0.0f;
}
/*
================
Math::Fmod
================
*/
OG_INLINE float Math::Fmod( float numerator, float denominator ) {
return fmodf( numerator, denominator );
}
/*
================
Math::Modf
================
*/
OG_INLINE float Math::Modf( float f, float& i ) {
return modff( f, &i );
}
OG_INLINE float Math::Modf( float f ) {
float i;
return modff( f, &i );
}
/*
================
Math::Sqrt
================
*/
OG_INLINE float Math::Sqrt( float f ) {
return sqrtf( f );
}
/*
================
Math::InvSqrt
Cannot be 0.0f
================
*/
OG_INLINE float Math::InvSqrt( float f ) {
OG_ASSERT( f != 0.0f );
return 1.0f / sqrtf( f );
}
/*
================
Math::RSqrt
Can be 0.0f
================
*/
OG_INLINE float Math::RSqrt( float f ) {
float g = 0.5f * f;
int i = *reinterpret_cast<int *>(&f);
// do a guess
i = 0x5f375a86 - ( i>>1 );
f = *reinterpret_cast<float *>(&i);
// Newtons calculation
f = f * ( 1.5f - g * f * f );
return f;
}
/*
================
Math::Log/Log2/Log10
Log of 0 is bad.
I've also heard you're not really
supposed to do log of negatives, yet
they work fine.
================
*/
OG_INLINE float Math::Log( float f ) {
OG_ASSERT( f != 0.0f );
return logf( f );
}
OG_INLINE float Math::Log2( float f ) {
OG_ASSERT( f != 0.0f );
return INV_LN_2 * logf( f );
}
OG_INLINE float Math::Log10( float f ) {
OG_ASSERT( f != 0.0f );
return INV_LN_10 * logf( f );
}
/*
================
Math::Pow
================
*/
OG_INLINE float Math::Pow( float base, float exp ) {
return powf( base, exp );
}
/*
================
Math::Exp
================
*/
OG_INLINE float Math::Exp( float f ) {
return expf( f );
}
/*
================
Math::IsPowerOfTwo
================
*/
OG_INLINE bool Math::IsPowerOfTwo( int x ) {
// This is the faster of the two known methods
// with the x > 0 check moved to the beginning
return x > 0 && ( x & ( x - 1 ) ) == 0;
}
/*
================
Math::HigherPowerOfTwo
================
*/
OG_INLINE int Math::HigherPowerOfTwo( int x ) {
x--;
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
return x + 1;
}
/*
================
Math::LowerPowerOfTwo
================
*/
OG_INLINE int Math::LowerPowerOfTwo( int x ) {
return HigherPowerOfTwo( x ) >> 1;
}
/*
================
Math::FloorPowerOfTwo
================
*/
OG_INLINE int Math::FloorPowerOfTwo( int x ) {
return IsPowerOfTwo( x ) ? x : LowerPowerOfTwo( x );
}
/*
================
Math::CeilPowerOfTwo
================
*/
OG_INLINE int Math::CeilPowerOfTwo( int x ) {
return IsPowerOfTwo( x ) ? x : HigherPowerOfTwo( x );
}
/*
================
Math::ClosestPowerOfTwo
================
*/
OG_INLINE int Math::ClosestPowerOfTwo( int x ) {
if ( IsPowerOfTwo( x ) )
return x;
int high = HigherPowerOfTwo( x );
int low = high >> 1;
return ((high-x) < (x-low)) ? high : low;
}
/*
================
Math::Digits
================
*/
OG_INLINE int Math::Digits( int x ) {
int digits = 1;
int step = 10;
while (step <= x) {
digits++;
step *= 10;
}
return digits;
}
/*
================
Math::Sin/ASin
================
*/
OG_INLINE float Math::Sin( float f ) {
return sinf( f );
}
OG_INLINE float Math::ASin( float f ) {
if ( f <= -1.0f )
return -HALF_PI;
if ( f >= 1.0f )
return HALF_PI;
return asinf( f );
}
/*
================
Math::Cos/ACos
================
*/
OG_INLINE float Math::Cos( float f ) {
return cosf( f );
}
OG_INLINE float Math::ACos( float f ) {
if ( f <= -1.0f )
return PI;
if ( f >= 1.0f )
return 0.0f;
return acosf( f );
}
/*
================
Math::Tan/ATan
================
*/
OG_INLINE float Math::Tan( float f ) {
return tanf( f );
}
OG_INLINE float Math::ATan( float f ) {
return atanf( f );
}
OG_INLINE float Math::ATan( float f1, float f2 ) {
return atan2f( f1, f2 );
}
/*
================
Math::SinCos
================
*/
OG_INLINE void Math::SinCos( float f, float &s, float &c ) {
#if OG_ASM_MSVC
// sometimes assembler is just waaayy faster
_asm {
fld f
fsincos
mov ecx, c
mov edx, s
fstp dword ptr [ecx]
fstp dword ptr [edx]
}
#elif OG_ASM_GNU
asm ("fsincos" : "=t" (c), "=u" (s) : "0" (f));
#else
s = Sin(f);
c = Sqrt( 1.0f - s * s ); // faster than calling Cos(f)
#endif
}
/*
================
Math::Deg2Rad
================
*/
OG_INLINE float Math::Deg2Rad( float f ) {
return f * DEG_TO_RAD;
}
/*
================
Math::Rad2Deg
================
*/
OG_INLINE float Math::Rad2Deg( float f ) {
return f * RAD_TO_DEG;
}
/*
================
Math::Square
================
*/
OG_INLINE float Math::Square( float v ) {
return v * v;
}
/*
================
Math::Cube
================
*/
OG_INLINE float Math::Cube( float v ) {
return v * v * v;
}
/*
================
Math::Sec2Ms
================
*/
OG_INLINE int Math::Sec2Ms( int sec ) {
return sec * 1000;
}
/*
================
Math::Ms2Sec
================
*/
OG_INLINE int Math::Ms2Sec( int ms ) {
return FtoiFast( ms * 0.001f );
}
}
#endif

32
samples/C++/Types.h Normal file
View File

@@ -0,0 +1,32 @@
/*****************************************************************************
* Dwarf Mine - The 13-11 Benchmark
*
* Copyright (c) 2013 Bünger, Thomas; Kieschnick, Christian; Kusber,
* Michael; Lohse, Henning; Wuttke, Nikolai; Xylander, Oliver; Yao, Gary;
* Zimmermann, Florian
*
* 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.
*****************************************************************************/
#pragma once
#include <cstdint>
typedef uint32_t smallPrime_t;

1129
samples/C++/bcm2835.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,39 +0,0 @@
void foo()
{
cudaArray* cu_array;
texture<float, 2, cudaReadModeElementType> tex;
// Allocate array
cudaChannelFormatDesc description = cudaCreateChannelDesc<float>();
cudaMallocArray(&cu_array, &description, width, height);
// Copy image data to array
cudaMemcpyToArray(cu_array, image, width*height*sizeof(float), cudaMemcpyHostToDevice);
// Set texture parameters (default)
tex.addressMode[0] = cudaAddressModeClamp;
tex.addressMode[1] = cudaAddressModeClamp;
tex.filterMode = cudaFilterModePoint;
tex.normalized = false; // do not normalize coordinates
// Bind the array to the texture
cudaBindTextureToArray(tex, cu_array);
// Run kernel
dim3 blockDim(16, 16, 1);
dim3 gridDim((width + blockDim.x - 1)/ blockDim.x, (height + blockDim.y - 1) / blockDim.y, 1);
kernel<<< gridDim, blockDim, 0 >>>(d_data, height, width);
// Unbind the array from the texture
cudaUnbindTexture(tex);
} //end foo()
__global__ void kernel(float* odata, int height, int width)
{
unsigned int x = blockIdx.x*blockDim.x + threadIdx.x;
unsigned int y = blockIdx.y*blockDim.y + threadIdx.y;
if (x < width && y < height) {
float c = tex2D(tex, x, y);
odata[y*width+x] = c;
}
}

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

138
samples/C++/libcanister.h Normal file
View File

@@ -0,0 +1,138 @@
#ifndef LIBCANIH
#define LIBCANIH
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <cstring>
#define int64 unsigned long long
//#define DEBUG
#ifdef DEBUG
#define dout cout
#else
#define dout if (0) cerr
#endif
using namespace std;
namespace libcanister
{
//the canmem object is a generic memory container used commonly
//throughout the canister framework to hold memory of uncertain
//length which may or may not contain null bytes.
class canmem
{
public:
char* data; //the raw memory block
int size; //the absolute length of the block
canmem(); //creates an unallocated canmem
canmem(int allocsize); //creates an allocated, blank canmem of size
canmem(char* strdata); //automates the creation of zero-limited canmems
~canmem(); //cleans up the canmem
void zeromem(); //overwrites this canmem
void fragmem(); //overwrites this canmem with fragment notation
void countlen(); //counts length of zero-limited strings and stores it in size
void trim(); //removes any nulls from the end of the string
static canmem null(); //returns a singleton null canmem
};
//contains information about the canister
class caninfo
{
public:
canmem path; //physical path
canmem internalname; //a name for the canister
int numfiles; //the number of files in the canister
};
//necessary for the use of this class as a type in canfile
class canister;
//this object holds the definition of a 'file' within the
//canister 'filesystem.'
class canfile
{
public:
libcanister::canister* parent; //the canister that holds this file
canmem path; //internal path ('filename')
canmem data; //the file's decompressed contents
int isfrag; //0 = probably not fragment, 1 = definitely a fragment (ignore)
int cfid; //'canfile id' -- a unique ID for this file
int64 dsize; //ondisk size (compressed form size)
int cachestate; //0 = not in memory, 1 = in memory, 2 = in memory and needs flush
//-1 = error, check the data for the message
void cache(); //pull the file from disk and cache it in memory
void cachedump(); //deletes the contents of this file from the memory cache after assuring the on disk copy is up to date
void cachedumpfinal(fstream& infile); //same as cachedump, but more efficient during closing procedures
void flush(); //updates the on disk copy, but retains the memory cache
};
//the primary class
//this defines and controls a single canister
class canister
{
//table of contents
//absolutely worthless to the control code in the canister
//but quite useful to programs using the API, as they may
//desire to enumerate the files in a canister for a user's
//use or for their own.
//contains a newline-delimited list of files in the container.
canfile TOC;
public:
caninfo info; //the general info about this canister
//the raw canfiles -- recommended that programs do not modify
//these files directly, but not enforced.
canfile* files;
bool readonly; //if true then no write routines will do anything
//maximum number of files to have in memory at any given
//time, change this to whatever suits your application.
int cachemax;
int cachecnt; //number of files in the cache (should not be modified)
//both initialize the canister from a physical location
canister (canmem fspath);
canister (char* fspath);
//destroys the canister (after flushing the modded buffers, of course)
~canister();
//open the fspath
//does it exist?
// | --- yes --- opening it (return 1)
// | --- yes --- file is corrupted, halting (return -1)
// | --- no --- making a new one (return 0)
int open();
//close the canister, flush all buffers, clean up
int close();
//deletes the file at path inside this canister
int delFile(canmem path);
//pulls the contents of the file from disk or memory and returns it as a file
canfile getFile(canmem path);
//creates a file if it does not exist, otherwise overwrites
//returns whether operation succeeded
bool writeFile(canmem path, canmem data);
bool writeFile(canfile file);
//get the 'table of contents', a file containing a newline delimited
//list of the file paths in the container which have contents
canfile getTOC();
//brings the cache back within the cachemax limit
//important: sCFID is the safe CFID
//(the CFID of the file we want to avoid uncaching)
//really just used internally, but it can't do any harm.
void cacheclean(int sCFID, bool dFlush = false);
};
}
#endif

92
samples/C++/metrics.h Normal file
View File

@@ -0,0 +1,92 @@
// Copyright 2011 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef NINJA_METRICS_H_
#define NINJA_METRICS_H_
#include <string>
#include <vector>
using namespace std;
#include "util.h" // For int64_t.
/// The Metrics module is used for the debug mode that dumps timing stats of
/// various actions. To use, see METRIC_RECORD below.
/// A single metrics we're tracking, like "depfile load time".
struct Metric {
string name;
/// Number of times we've hit the code path.
int count;
/// Total time (in micros) we've spent on the code path.
int64_t sum;
};
/// A scoped object for recording a metric across the body of a function.
/// Used by the METRIC_RECORD macro.
struct ScopedMetric {
explicit ScopedMetric(Metric* metric);
~ScopedMetric();
private:
Metric* metric_;
/// Timestamp when the measurement started.
/// Value is platform-dependent.
int64_t start_;
};
/// The singleton that stores metrics and prints the report.
struct Metrics {
Metric* NewMetric(const string& name);
/// Print a summary report to stdout.
void Report();
private:
vector<Metric*> metrics_;
};
/// Get the current time as relative to some epoch.
/// Epoch varies between platforms; only useful for measuring elapsed time.
int64_t GetTimeMillis();
/// A simple stopwatch which returns the time
/// in seconds since Restart() was called.
struct Stopwatch {
public:
Stopwatch() : started_(0) {}
/// Seconds since Restart() call.
double Elapsed() const {
return 1e-6 * static_cast<double>(Now() - started_);
}
void Restart() { started_ = Now(); }
private:
uint64_t started_;
uint64_t Now() const;
};
/// The primary interface to metrics. Use METRIC_RECORD("foobar") at the top
/// of a function to get timing stats recorded for each call of the function.
#define METRIC_RECORD(name) \
static Metric* metrics_h_metric = \
g_metrics ? g_metrics->NewMetric(name) : NULL; \
ScopedMetric metrics_h_scoped(metrics_h_metric);
extern Metrics* g_metrics;
#endif // NINJA_METRICS_H_

View File

@@ -0,0 +1,6 @@
#include <cstdint>
namespace Gui
{
}

26
samples/C++/rpc.h Normal file
View File

@@ -0,0 +1,26 @@
// Copyright (C) 2013 Simon Que
//
// This file is part of DuinoCube.
//
// DuinoCube is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// DuinoCube is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with DuinoCube. If not, see <http://www.gnu.org/licenses/>.
// DuinoCube remote procedure call functions.
#include <stdint.h>
// Initializes RPC system.
void rpc_init();
// Runs the RPC server loop forever.
void rpc_server_loop();

102
samples/C/bootstrap.h Normal file
View File

@@ -0,0 +1,102 @@
#ifndef BOOTSTRAP_H
#define BOOTSTRAP_H
#include <stdio.h>
#include "cxrs.h"
/* If we're not using GNU C, elide __attribute__ */
#ifndef __GNUC__
# define __attribute__(x) /*NOTHING*/
#endif
typedef struct object object;
object *true;
object *false;
object *eof;
object *empty_list;
object *global_enviroment;
enum obj_type {
scm_bool,
scm_empty_list,
scm_eof,
scm_char,
scm_int,
scm_pair,
scm_symbol,
scm_prim_fun,
scm_lambda,
scm_str,
scm_file
};
typedef object *(*prim_proc)(object *args);
object *read(FILE *in);
object *eval(object *code, object *env);
void print(FILE *out, object *obj, int display);
int check_type(enum obj_type type, object *obj, int err_on_false);
static inline int is_true(object *obj)
{
return obj != false;
}
object *make_int(int value);
int obj2int(object *i);
object *make_bool(int value);
int obj2bool(object *b);
object *make_char(char c);
char obj2char(object *ch);
object *make_str(char *str);
char *obj2str(object *str);
object *cons(object *car, object *cdr);
object *car(object *pair);
object *cdr(object *pair);
void set_car(object *pair, object *new);
void set_cdr(object *pair, object *new);
object *make_symbol(char *name);
char *sym2str(object *sym);
object *get_symbol(char *name) __attribute__((pure));
object *make_prim_fun(prim_proc fun);
prim_proc obj2prim_proc(object *proc);
object *make_lambda(object *args, object *code, object *env);
object *lambda_code(object *lambda);
object *lambda_args(object *lambda);
object *make_port(FILE *handle, int direction);
int port_direction(object *port);
FILE *port_handle(object *port);
void set_port_handle_to_null(object *port);
/*both of these should never be called*/
object *apply_proc(object *);
object *eval_proc(object *);
object *maybe_add_begin(object *code);
void init_enviroment(object *env);
void eval_err(char *msg, object *code) __attribute__((noreturn));
void define_var(object *var, object *val, object *env);
void set_var(object *var, object *val, object *env);
object *get_var(object *var, object *env);
object *cond2nested_if(object *cond);
object *let2lambda(object *let);
object *and2nested_if(object *and);
object *or2nested_if(object *or);
#endif /*include guard*/

56
samples/C/dynarray.cats Normal file
View File

@@ -0,0 +1,56 @@
/* ******************************************************************* */
/* */
/* Applied Type System */
/* */
/* ******************************************************************* */
/*
** ATS/Postiats - Unleashing the Potential of Types!
** Copyright (C) 2011-20?? Hongwei Xi, ATS Trustful Software, Inc.
** All rights reserved
**
** ATS is free software; you can redistribute it and/or modify it under
** the terms of the GNU GENERAL PUBLIC LICENSE (GPL) as published by the
** Free Software Foundation; either version 3, or (at your option) any
** later version.
**
** ATS is distributed in the hope that it will be useful, but WITHOUT ANY
** WARRANTY; without even the implied warranty of MERCHANTABILITY or
** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
** for more details.
**
** You should have received a copy of the GNU General Public License
** along with ATS; see the file COPYING. If not, please write to the
** Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
** 02110-1301, USA.
*/
/* ****** ****** */
/*
(* Author: Hongwei Xi *)
(* Authoremail: hwxi AT cs DOT bu DOT edu *)
(* Start time: March, 2013 *)
*/
/* ****** ****** */
#ifndef ATSHOME_LIBATS_DYNARRAY_CATS
#define ATSHOME_LIBATS_DYNARRAY_CATS
/* ****** ****** */
#include <string.h>
/* ****** ****** */
#define atslib_dynarray_memcpy memcpy
#define atslib_dynarray_memmove memmove
/* ****** ****** */
#endif // ifndef ATSHOME_LIBATS_DYNARRAY_CATS
/* ****** ****** */
/* end of [dynarray.cats] */

61
samples/C/jni_layer.h Normal file
View File

@@ -0,0 +1,61 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class jni_JniLayer */
#ifndef _Included_jni_JniLayer
#define _Included_jni_JniLayer
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: jni_JniLayer
* Method: jni_layer_initialize
* Signature: ([II)J
*/
JNIEXPORT jlong JNICALL Java_jni_JniLayer_jni_1layer_1initialize
(JNIEnv *, jobject, jintArray, jint, jint);
/*
* Class: jni_JniLayer
* Method: jni_layer_mainloop
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_jni_JniLayer_jni_1layer_1mainloop
(JNIEnv *, jobject, jlong);
/*
* Class: jni_JniLayer
* Method: jni_layer_set_button
* Signature: (JII)V
*/
JNIEXPORT void JNICALL Java_jni_JniLayer_jni_1layer_1set_1button
(JNIEnv *, jobject, jlong, jint, jint);
/*
* Class: jni_JniLayer
* Method: jni_layer_set_analog
* Signature: (JIIF)V
*/
JNIEXPORT void JNICALL Java_jni_JniLayer_jni_1layer_1set_1analog
(JNIEnv *, jobject, jlong, jint, jint, jfloat);
/*
* Class: jni_JniLayer
* Method: jni_layer_report_analog_chg
* Signature: (JI)V
*/
JNIEXPORT void JNICALL Java_jni_JniLayer_jni_1layer_1report_1analog_1chg
(JNIEnv *, jobject, jlong, jint);
/*
* Class: jni_JniLayer
* Method: jni_layer_kill
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_jni_JniLayer_jni_1layer_1kill
(JNIEnv *, jobject, jlong);
#ifdef __cplusplus
}
#endif
#endif

47
samples/C/readline.cats Normal file
View File

@@ -0,0 +1,47 @@
/*
** API in ATS for GNU-readline
*/
/* ****** ****** */
/*
** Permission to use, copy, modify, and distribute this software for any
** purpose with or without fee is hereby granted, provided that the above
** copyright notice and this permission notice appear in all copies.
**
** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
** WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
** MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
** ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
** WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
** ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
** OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* ****** ****** */
#ifndef READLINE_READLINE_CATS
#define READLINE_READLINE_CATS
/* ****** ****** */
#include <readline/readline.h>
/* ****** ****** */
//
#define \
atscntrb_readline_rl_library_version() ((char*)rl_library_version)
//
#define atscntrb_readline_rl_readline_version() (rl_readline_version)
//
/* ****** ****** */
#define atscntrb_readline_readline readline
/* ****** ****** */
#endif // ifndef READLINE_READLINE_CATS
/* ****** ****** */
/* end of [readline.cats] */

5
samples/C/syscalldefs.h Normal file
View File

@@ -0,0 +1,5 @@
static const syscalldef syscalldefs[] = {
[SYSCALL_OR_NUM(0, SYS_restart_syscall)] = MAKE_UINT16(0, 1),
[SYSCALL_OR_NUM(1, SYS_exit)] = MAKE_UINT16(1, 17),
[SYSCALL_OR_NUM(2, SYS_fork)] = MAKE_UINT16(0, 22),
};

12
samples/Cirru/array.cirru Normal file
View File

@@ -0,0 +1,12 @@
print $ array
int 1
string 2
print $ array
int 1
array
int 2
string 3
array
string 4

View File

@@ -0,0 +1,7 @@
set f $ block (a b c)
print a b c
call f (int 1) (int 2) (int 3)
f (int 1) (int 2) (int 3)

7
samples/Cirru/bool.cirru Normal file
View File

@@ -0,0 +1,7 @@
print $ bool true
print $ bool false
print $ bool yes
print $ bool no
print $ bool 1
print $ bool 0

14
samples/Cirru/map.cirru Normal file
View File

@@ -0,0 +1,14 @@
print $ map
a $ int 5
b $ array (int 1) (int 2)
c $ map
int 1
array (int 4)
set m $ map
a $ int 1
set m b $ int 2
print m

View File

@@ -0,0 +1,3 @@
print $ int 1
print $ float 1.2

View File

@@ -0,0 +1,2 @@
require ./stdio.cr

23
samples/Cirru/scope.cirru Normal file
View File

@@ -0,0 +1,23 @@
set a (int 2)
print (self)
set c (child)
under c
under parent
print a
print $ get c a
set c x (int 3)
print $ get c x
set just-print $ code
print a
print just-print
eval (self) just-print
eval just-print

55
samples/Cirru/stdio.cirru Normal file
View File

@@ -0,0 +1,55 @@
set a $ string 1
print a
print (string 1)
print nothing
print
map
a (int 4)
b $ map
a $ int 5
b $ int 6
c $ map
int 7
print
array
int 1
int 2
array
int 3
int 4
print
array
int 1
map
a $ int 2
b $ array
int 3
print
int 1
int 2
print $ code
set a 1
print (get a)
print $ array
int a
array
int a
set container (map)
set container code $ code
set a 1
print (get a)
print $ array
int a
array
int a
print container

View File

@@ -0,0 +1,3 @@
print $ string a
print $ string "a b"

17
samples/Clojure/for.clj Normal file
View File

@@ -0,0 +1,17 @@
(defn prime? [n]
(not-any? zero? (map #(rem n %) (range 2 n))))
(range 3 33 2)
'(3 5 7 9 11 13 15 17 19 21 23 25 27 29 31)
;; :when continues through the collection even if some have the
;; condition evaluate to false, like filter
(for [x (range 3 33 2) :when (prime? x)]
x)
'(3 5 7 11 13 17 19 23 29 31)
;; :while stops at the first collection element that evaluates to
;; false, like take-while
(for [x (range 3 33 2) :while (prime? x)]
x)
'(3 5 7)

View File

@@ -0,0 +1,8 @@
[:html
[:head
[:meta {:charset "utf-8"}]
[:link {:rel "stylesheet" :href "css/bootstrap.min.css"}]
[:script {:src "app.js"}]]
[:body
[:div.nav
[:p "Hello world!"]]]]

View File

@@ -0,0 +1,13 @@
(defn into-array
([aseq]
(into-array nil aseq))
([type aseq]
(let [n (count aseq)
a (make-array n)]
(loop [aseq (seq aseq)
i 0]
(if (< i n)
(do
(aset a i (first aseq))
(recur (next aseq) (inc i)))
a)))))

View File

@@ -0,0 +1,15 @@
(defprotocol ISound (sound []))
(deftype Cat []
ISound
(sound [_] "Meow!"))
(deftype Dog []
ISound
(sound [_] "Woof!"))
(extend-type default
ISound
(sound [_] "... silence ..."))
(sound 1) ;; => "... silence ..."

View File

@@ -0,0 +1,5 @@
(defn rand
"Returns a random floating point number between 0 (inclusive) and
n (default 1) (exclusive)."
([] (scm* [n] (random-real)))
([n] (* (rand) n)))

20
samples/Clojure/svg.cljx Normal file
View File

@@ -0,0 +1,20 @@
^:clj (ns c2.svg
(:use [c2.core :only [unify]]
[c2.maths :only [Pi Tau radians-per-degree
sin cos mean]]))
^:cljs (ns c2.svg
(:use [c2.core :only [unify]]
[c2.maths :only [Pi Tau radians-per-degree
sin cos mean]])
(:require [c2.dom :as dom]))
;;Stub for float fn, which does not exist on cljs runtime
^:cljs (def float identity)
(defn ->xy
"Convert coordinates (potentially map of `{:x :y}`) to 2-vector."
[coordinates]
(cond
(and (vector? coordinates) (= 2 (count coordinates))) coordinates
(map? coordinates) [(:x coordinates) (:y coordinates)]))

View File

@@ -0,0 +1,20 @@
(deftest function-tests
(is (= 3
(count [1 2 3])))
(is (= false
(not true)))
(is (= true
(contains? {:foo 1 :bar 2} :foo)))
(is (= {"foo" 1, "baz" 3}
(select-keys {:foo 1 :bar 2 :baz 3} [:foo :baz])))
(is (= [1 2 3]
(vals {:foo 1 :bar 2 :baz 3})))
(is (= ["foo" "bar" "baz"]
(keys {:foo 1 :bar 2 :baz 3})))
(is (= [2 4 6]
(filter (fn [x] (=== (rem x 2) 0)) [1 2 3 4 5 6]))))

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,21 @@
;;;; -*- lisp -*-
(in-package :foo)
;;; Header comment.
(defvar *foo*)
(eval-when (:execute :compile-toplevel :load-toplevel)
(defun add (x &optional y &key z)
(declare (ignore z))
;; Inline comment.
(+ x (or y 1))))
#|
Multi-line comment.
|#
(defmacro foo (x &body b)
(if x
`(1+ ,x) ;After-line comment.
42))

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,47 @@
= Creole
Creole is a Creole-to-HTML converter for Creole, the lightweight markup
language (http://wikicreole.org/). Github uses this converter to render *.creole files.
Project page on github:
* http://github.com/minad/creole
Travis-CI:
* https://travis-ci.org/minad/creole
RDOC:
* http://rdoc.info/projects/minad/creole
== INSTALLATION
{{{
gem install creole
}}}
== SYNOPSIS
{{{
require 'creole'
html = Creole.creolize('== Creole text')
}}}
== BUGS
If you found a bug, please report it at the Creole project's tracker
on GitHub:
http://github.com/minad/creole/issues
== AUTHORS
* Lars Christensen (larsch)
* Daniel Mendler (minad)
== LICENSE
Creole is Copyright (c) 2008 - 2013 Lars Christensen, Daniel Mendler. It is free software, and
may be redistributed under the terms specified in the README file of
the Ruby distribution.

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

View File

@@ -0,0 +1,52 @@
__global__ void scalarProdGPU(
float *d_C,
float *d_A,
float *d_B,
int vectorN,
int elementN
)
{
//Accumulators cache
__shared__ float accumResult[ACCUM_N];
////////////////////////////////////////////////////////////////////////////
// Cycle through every pair of vectors,
// taking into account that vector counts can be different
// from total number of thread blocks
////////////////////////////////////////////////////////////////////////////
for (int vec = blockIdx.x; vec < vectorN; vec += gridDim.x)
{
int vectorBase = IMUL(elementN, vec);
int vectorEnd = vectorBase + elementN;
////////////////////////////////////////////////////////////////////////
// Each accumulator cycles through vectors with
// stride equal to number of total number of accumulators ACCUM_N
// At this stage ACCUM_N is only preferred be a multiple of warp size
// to meet memory coalescing alignment constraints.
////////////////////////////////////////////////////////////////////////
for (int iAccum = threadIdx.x; iAccum < ACCUM_N; iAccum += blockDim.x)
{
float sum = 0;
for (int pos = vectorBase + iAccum; pos < vectorEnd; pos += ACCUM_N)
sum += d_A[pos] * d_B[pos];
accumResult[iAccum] = sum;
}
////////////////////////////////////////////////////////////////////////
// Perform tree-like reduction of accumulators' results.
// ACCUM_N has to be power of two at this stage
////////////////////////////////////////////////////////////////////////
for (int stride = ACCUM_N / 2; stride > 0; stride >>= 1)
{
__syncthreads();
for (int iAccum = threadIdx.x; iAccum < stride; iAccum += blockDim.x)
accumResult[iAccum] += accumResult[stride + iAccum];
}
if (threadIdx.x == 0) d_C[vec] = accumResult[0];
}
}

46
samples/Cuda/vectorAdd.cu Normal file
View File

@@ -0,0 +1,46 @@
#include <stdio.h>
#include <cuda_runtime.h>
/**
* CUDA Kernel Device code
*
* Computes the vector addition of A and B into C. The 3 vectors have the same
* number of elements numElements.
*/
__global__ void
vectorAdd(const float *A, const float *B, float *C, int numElements)
{
int i = blockDim.x * blockIdx.x + threadIdx.x;
if (i < numElements)
{
C[i] = A[i] + B[i];
}
}
/**
* Host main routine
*/
int
main(void)
{
// Error code to check return values for CUDA calls
cudaError_t err = cudaSuccess;
// Launch the Vector Add CUDA Kernel
int threadsPerBlock = 256;
int blocksPerGrid =(numElements + threadsPerBlock - 1) / threadsPerBlock;
vectorAdd<<<blocksPerGrid, threadsPerBlock>>>(d_A, d_B, d_C, numElements);
err = cudaGetLastError();
if (err != cudaSuccess)
{
fprintf(stderr, "Failed to launch vectorAdd kernel (error code %s)!\n", cudaGetErrorString(err));
exit(EXIT_FAILURE);
}
// Reset the device and exit
err = cudaDeviceReset();
return 0;
}

87
samples/DM/example.dm Normal file
View File

@@ -0,0 +1,87 @@
// This is a single line comment.
/*
This is a multi-line comment
*/
// Pre-processor keywords
#define PI 3.1415
#if PI == 4
#define G 5
#elif PI == 3
#define I 6
#else
#define K 7
#endif
var/GlobalCounter = 0
var/const/CONST_VARIABLE = 2
var/list/MyList = list("anything", 1, new /datum/entity)
var/list/EmptyList[99] // creates a list of 99 null entries
var/list/NullList = null
/*
Entity Class
*/
/datum/entity
var/name = "Entity"
var/number = 0
/datum/entity/proc/myFunction()
world.log << "Entity has called myFunction"
/datum/entity/New()
number = GlobalCounter++
/*
Unit Class, Extends from Entity
*/
/datum/entity/unit
name = "Unit"
/datum/entity/unit/New()
..() // calls the parent's proc; equal to super() and base() in other languages
number = rand(1, 99)
/datum/entity/unit/myFunction()
world.log << "Unit has overriden and called myFunction"
// Global Function
/proc/ReverseList(var/list/input)
var/list/output = list()
for(var/i = input.len; i >= 1; i--) // IMPORTANT: List Arrays count from 1.
output += input[i] // "+= x" is ".Add(x)"
return output
// Bitflags
/proc/DoStuff()
var/bitflag = 0
bitflag |= 8
return bitflag
/proc/DoOtherStuff()
var/bitflag = 65535 // 16 bits is the maximum amount
bitflag &= ~8
return bitflag
// Logic
/proc/DoNothing()
var/pi = PI
if(pi == 4)
world.log << "PI is 4"
else if(pi == CONST_VARIABLE)
world.log << "PI is [CONST_VARIABLE]!"
else
world.log << "PI is approximety [pi]"
#undef PI // Undefine PI

View File

@@ -1,15 +1,19 @@
import 'dart:math' as math;
class Point {
num x, y;
Point(this.x, this.y);
distanceTo(Point other) {
num distanceTo(Point other) {
var dx = x - other.x;
var dy = y - other.y;
return Math.sqrt(dx * dx + dy * dy);
return math.sqrt(dx * dx + dy * dy);
}
var x, y;
}
main() {
Point p = new Point(2, 3);
Point q = new Point(3, 4);
void main() {
var p = new Point(2, 3);
var q = new Point(3, 4);
print('distance from p to q = ${p.distanceTo(q)}');
}

View File

@@ -0,0 +1,16 @@
quiet
wow
such language
very syntax
github recognized wow
loud
such language much friendly
rly friendly is true
plz console.loge with 'such friend, very inclusive'
but
plz console.loge with 'no love for doge'
wow
wow
module.exports is language

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>

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