mirror of
				https://github.com/KevinMidboe/linguist.git
				synced 2025-10-29 17:50:22 +00:00 
			
		
		
		
	Compare commits
	
		
			392 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | b9ecf61dcb | ||
|  | 437f81c4a0 | ||
|  | 26dad7dada | ||
|  | b1e5d6f8f8 | ||
|  | 8c7b54d6e3 | ||
|  | 529d3faaf8 | ||
|  | 9f0f4657a2 | ||
|  | 90ff1b5896 | ||
|  | feb82e34d6 | ||
|  | 4d7a34c177 | ||
|  | 5c3385ecd8 | ||
|  | a1af3a509c | ||
|  | 2913a87cc4 | ||
|  | 69cc86c572 | ||
|  | 60144c907e | ||
|  | 0d03a94cde | ||
|  | 6af5adaac1 | ||
|  | 17a28f2e91 | ||
|  | baaa7a5c13 | ||
|  | cfeb2a833c | ||
|  | 8b4acf7023 | ||
|  | 7393c2ef91 | ||
|  | 4948ec2999 | ||
|  | 408a325732 | ||
|  | 5ca211b9f7 | ||
|  | bc7596a8b5 | ||
|  | 6762ca8aa7 | ||
|  | 986611ac36 | ||
|  | 94b4ad1de6 | ||
|  | 3e2f18bf3f | ||
|  | 48c06cc299 | ||
|  | f10821ac49 | ||
|  | cd5298dee6 | ||
|  | a8c955609a | ||
|  | aa72012d41 | ||
|  | 458831b885 | ||
|  | f5e4789ccb | ||
|  | 1b712d2800 | ||
|  | e274196441 | ||
|  | c4c3c27cfe | ||
|  | a2dd9d2c8c | ||
|  | 06e095e5fc | ||
|  | b26d5bc1b1 | ||
|  | 607792e1b2 | ||
|  | fb38135a61 | ||
|  | a5d5b6e6c7 | ||
|  | 2fd2cdf68a | ||
|  | 11049ca3ca | ||
|  | c29bea19ef | ||
|  | 8c8434ed64 | ||
|  | 9281bd043a | ||
|  | 6771f7c272 | ||
|  | 76b896a66d | ||
|  | a12520763c | ||
|  | 819bb7caab | ||
|  | 152205a146 | ||
|  | 85dbcb5444 | ||
|  | df09a746a0 | ||
|  | 5199fcf0a2 | ||
|  | dd557ed00a | ||
|  | addf4e2485 | ||
|  | d9be472ccb | ||
|  | 32828a9af5 | ||
|  | d206131df0 | ||
|  | 65eaf98d0b | ||
|  | 12429b90fe | ||
|  | 621042e639 | ||
|  | 526244be11 | ||
|  | bc53d0b55e | ||
|  | 907d3c5a36 | ||
|  | 898f1e215e | ||
|  | 324ac83489 | ||
|  | 00a873dcc7 | ||
|  | bc34345a56 | ||
|  | 659d27cae5 | ||
|  | 29072d6eae | ||
|  | 1fd59361b5 | ||
|  | 5896bb8fa3 | ||
|  | ea1fc90cf5 | ||
|  | 463f48f04f | ||
|  | cd58a30c7c | ||
|  | c4260ae681 | ||
|  | d40b4a33de | ||
|  | 87498679bd | ||
|  | f4e254202b | ||
|  | e91d225e7d | ||
|  | b90d940aef | ||
|  | b83a364b0e | ||
|  | dbff196b08 | ||
|  | 5b7316fb2a | ||
|  | fa4dfe39ba | ||
|  | 89999e60bf | ||
|  | 4819fb12a3 | ||
|  | 27a4eeb206 | ||
|  | bacf4d5780 | ||
|  | f92fed60f8 | ||
|  | 5e797b548c | ||
|  | 700e2f1b2b | ||
|  | 861656978b | ||
|  | 9c05bdac85 | ||
|  | bd34c16c8f | ||
|  | 81fcb4452e | ||
|  | 4f1a5cd456 | ||
|  | 13109bb9b8 | ||
|  | 84f3b3720b | ||
|  | 858a66ccc8 | ||
|  | abb05eace6 | ||
|  | 62bd96a778 | ||
|  | 8cb736adfa | ||
|  | 0758c05186 | ||
|  | 62bc6f0457 | ||
|  | ea7e894139 | ||
|  | 21f0ac99e6 | ||
|  | b251866a29 | ||
|  | bf3db20a9d | ||
|  | bd55147847 | ||
|  | f4d64af39b | ||
|  | b7bda34645 | ||
|  | b13dea6df0 | ||
|  | 28a64c9318 | ||
|  | 74be618fff | ||
|  | 8bbe10bf50 | ||
|  | d275911624 | ||
|  | c26382301c | ||
|  | ae2d3d7e61 | ||
|  | 58ae0908e3 | ||
|  | e12bc07041 | ||
|  | 20416369ac | ||
|  | 2be91e9b2e | ||
|  | e91caeaade | ||
|  | dc1b8d9e80 | ||
|  | bf0a814514 | ||
|  | b14267d40f | ||
|  | 195a4115d8 | ||
|  | e1da8eb841 | ||
|  | bd694c60e1 | ||
|  | 14738f037f | ||
|  | a437943516 | ||
|  | 900ee57de8 | ||
|  | 947f4e1c57 | ||
|  | d9f17a65dd | ||
|  | f71def19ae | ||
|  | e452e85cae | ||
|  | 5059fe90b0 | ||
|  | b90da731d6 | ||
|  | d2012519ba | ||
|  | 1b7f26091c | ||
|  | 548e4f1845 | ||
|  | 625bed8fca | ||
|  | db15367775 | ||
|  | 309d14a955 | ||
|  | 5ff16e1195 | ||
|  | cf43aa9111 | ||
|  | 138c1e6024 | ||
|  | 382870a881 | ||
|  | 31921838cd | ||
|  | a707587182 | ||
|  | bc482af999 | ||
|  | 6818744dae | ||
|  | 607185ac61 | ||
|  | 81b7a412c3 | ||
|  | 09b9a8b441 | ||
|  | 85479cc2de | ||
|  | 3ad4eb2b59 | ||
|  | 878fe95ec3 | ||
|  | 3d23d1be69 | ||
|  | 701e720ab8 | ||
|  | e709ce7d56 | ||
|  | 32c89a5405 | ||
|  | 1735982a73 | ||
|  | 625e0aa1af | ||
|  | 00e1a3f8fd | ||
|  | 539256b08e | ||
|  | ff791f5a39 | ||
|  | de4d48b0fe | ||
|  | b5c49f6d1c | ||
|  | 03cb7d6ffb | ||
|  | 304fc344a1 | ||
|  | 33c42638e9 | ||
|  | 9d940755e7 | ||
|  | bc04232f87 | ||
|  | e17ebec098 | ||
|  | a7cba23526 | ||
|  | 7cd23036a7 | ||
|  | 44c5413abf | ||
|  | 50ab58e91f | ||
|  | 1fd0732390 | ||
|  | ed1b9ee899 | ||
|  | d3c04d6310 | ||
|  | f66ffe305f | ||
|  | 2a9ff0083c | ||
|  | c1cf7ea825 | ||
|  | 67f7268a55 | ||
|  | a55ee7eb09 | ||
|  | 203f6d1944 | ||
|  | 42c68f21d1 | ||
|  | 7e8be1293e | ||
|  | 09c234ec26 | ||
|  | 65a26c3e73 | ||
|  | 98f35aefdc | ||
|  | 38a3714514 | ||
|  | 491700f925 | ||
|  | 4d033e7e83 | ||
|  | efc3638065 | ||
|  | b7685ab317 | ||
|  | 83c5f6a004 | ||
|  | aa5a94cc3e | ||
|  | a5b6331ab5 | ||
|  | 2164b28c64 | ||
|  | 0fb824b345 | ||
|  | 29ee094d66 | ||
|  | 4a7ae50ec8 | ||
|  | 398439a937 | ||
|  | a3bc3a7615 | ||
|  | 7989fbd613 | ||
|  | c389c79be9 | ||
|  | 1fd2f921fd | ||
|  | ed851849db | ||
|  | cfb9f6f0a4 | ||
|  | 3d5a0da62e | ||
|  | 4e15369f9a | ||
|  | 5b3152d99d | ||
|  | a6955f4edb | ||
|  | 280ef7d1bd | ||
|  | 8d2ea90a5b | ||
|  | 4bf7abd73d | ||
|  | 8f251e6756 | ||
|  | 4cd35c1f33 | ||
|  | 78fda33707 | ||
|  | 5c6a98f479 | ||
|  | efbcb942c3 | ||
|  | f3da1bc3b1 | ||
|  | 72a6186f08 | ||
|  | 8cde6d2e8f | ||
|  | 4f2c7fdc3c | ||
|  | 5a830504a4 | ||
|  | 086fb09038 | ||
|  | 5544a041ce | ||
|  | 6447333368 | ||
|  | 1d6a42f0eb | ||
|  | de14b75517 | ||
|  | 0f302713da | ||
|  | a66d064d4a | ||
|  | 4fefe2020f | ||
|  | 72fab07a14 | ||
|  | adbf4f6b17 | ||
|  | cfcf4ca915 | ||
|  | c427fba87f | ||
|  | ab14bcab03 | ||
|  | 78de3fb959 | ||
|  | b9eda90ddd | ||
|  | 66b346c8fb | ||
|  | 8215b225d9 | ||
|  | 41da8c6352 | ||
|  | 04f4b05412 | ||
|  | b7dad4df5e | ||
|  | 1a98ccbf5f | ||
|  | 8d16a3365e | ||
|  | 67bf48fafc | ||
|  | 9a3c9a8c19 | ||
|  | 6a192dae63 | ||
|  | f5895216a8 | ||
|  | 09a33f8daa | ||
|  | 185db0e8d5 | ||
|  | 85efbde3f7 | ||
|  | 93d7aa3d07 | ||
|  | e96096f786 | ||
|  | 0a850eeddd | ||
|  | 42658ffd61 | ||
|  | 24fc2842d2 | ||
|  | ac2723abe3 | ||
|  | 0d0e219532 | ||
|  | cf35807709 | ||
|  | c2b53db96d | ||
|  | 8e6efc3a7d | ||
|  | 4b6f05b4d1 | ||
|  | 7aad5f93e4 | ||
|  | 9b6a7622d2 | ||
|  | 6c666075b5 | ||
|  | 6d26bf5c82 | ||
|  | 6d5da4c9ec | ||
|  | 51dde1f6a4 | ||
|  | 13c9259d23 | ||
|  | a22c2d678b | ||
|  | 5c36f8df85 | ||
|  | 37781cb58e | ||
|  | dcc598442b | ||
|  | 91877056fb | ||
|  | 868e9df434 | ||
|  | c3642ba7ed | ||
|  | 56f128af66 | ||
|  | c1e560b901 | ||
|  | 92bc1cdcdf | ||
|  | 9fde0ec447 | ||
|  | 297ef6195d | ||
|  | 9873157076 | ||
|  | 675c1f3c0b | ||
|  | fee7a34ddc | ||
|  | a148d52aed | ||
|  | 5da8831aff | ||
|  | e9ff0f4998 | ||
|  | 658bf98b4c | ||
|  | 452cfd32d7 | ||
|  | 3f1dc71cc2 | ||
|  | 256157cd42 | ||
|  | 843279ff1d | ||
|  | 8118546ac7 | ||
|  | 15c05c723e | ||
|  | d0d40c0d2e | ||
|  | f494972d04 | ||
|  | 1c4def7320 | ||
|  | 6e22b946bd | ||
|  | 0a54df3a12 | ||
|  | 20af70cd90 | ||
|  | a2f721d4ef | ||
|  | 03a1a733f6 | ||
|  | 4a76088b43 | ||
|  | 5a1dab8073 | ||
|  | 86a97610bd | ||
|  | 87bfe3657a | ||
|  | 3802e31b90 | ||
|  | 4eff60e4b1 | ||
|  | f103306e91 | ||
|  | 8b878784a4 | ||
|  | 44a0d19ac0 | ||
|  | 3023516796 | ||
|  | 6038a06c43 | ||
|  | 20735a4cdd | ||
|  | df3b1a983e | ||
|  | 84e43d7d3f | ||
|  | 7e81a9e50b | ||
|  | 28acee8e33 | ||
|  | 80184f1e1d | ||
|  | d893259e75 | ||
|  | d3f37f5013 | ||
|  | 0e6a46abfc | ||
|  | 49e27387b7 | ||
|  | c2495c27d3 | ||
|  | f0a3acd735 | ||
|  | 29d2930de8 | ||
|  | 2d82071103 | ||
|  | f4a3636371 | ||
|  | d8f96441da | ||
|  | cf5646d45a | ||
|  | 5c3d32cafd | ||
|  | ea45db38e9 | ||
|  | a978c4eb34 | ||
|  | 65302dbec7 | ||
|  | 3c82131863 | ||
|  | 00873da7a6 | ||
|  | a17f7d1cb2 | ||
|  | 9f850db126 | ||
|  | e513ac628a | ||
|  | 3dc11186a1 | ||
|  | 2fbca98e7f | ||
|  | 7ad411fbaa | ||
|  | 4e4e77bc9a | ||
|  | a7afdaa677 | ||
|  | dd24b54a31 | ||
|  | 833e409bd8 | ||
|  | c2a376fbc9 | ||
|  | c21707b8b1 | ||
|  | c04f4519a7 | ||
|  | fd7db27b48 | ||
|  | cab85f3de3 | ||
|  | 34893650eb | ||
|  | bb58840c1c | ||
|  | cbcbb969d5 | ||
|  | 3c21f8db51 | ||
|  | 6c3f8a7787 | ||
|  | 915a11f2b6 | ||
|  | 55ce1e8b93 | ||
|  | ccce5475bf | ||
|  | cb844a1913 | ||
|  | 9d569c8bd5 | ||
|  | 26fbc45baf | ||
|  | 9ae0bdbb43 | ||
|  | a3aaa1ec4d | ||
|  | ee3c9bcdbd | ||
|  | dc1b0e3c48 | ||
|  | 869cf8ba11 | ||
|  | a2690b7dac | ||
|  | e2b1fe3641 | ||
|  | 0eebd42d72 | ||
|  | aa78060e41 | ||
|  | 89795ebd1f | ||
|  | 5fb6f34d8a | ||
|  | 3ecc1f883c | ||
|  | edf19a0941 | ||
|  | dfeaaaa17e | ||
|  | bcefa61fe0 | ||
|  | 7c1716aa1e | 
| @@ -1,12 +1,11 @@ | |||||||
| before_install:  | before_install:  | ||||||
|  |   - git fetch origin master:master | ||||||
|  |   - git fetch origin v2.0.0:v2.0.0 | ||||||
|   - sudo apt-get install libicu-dev -y |   - sudo apt-get install libicu-dev -y | ||||||
|   - gem update --system 2.1.11 |   - gem update --system 2.1.11 | ||||||
| rvm: | rvm: | ||||||
|   - 1.8.7 |  | ||||||
|   - 1.9.2 |  | ||||||
|   - 1.9.3 |   - 1.9.3 | ||||||
|   - 2.0.0 |   - 2.0.0 | ||||||
|   - 2.1.1 |   - 2.1.1 | ||||||
|   - ree |  | ||||||
| notifications: | notifications: | ||||||
|   disabled: true |   disabled: true | ||||||
|   | |||||||
							
								
								
									
										5
									
								
								Gemfile
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								Gemfile
									
									
									
									
									
								
							| @@ -1,7 +1,2 @@ | |||||||
| source 'https://rubygems.org' | source 'https://rubygems.org' | ||||||
| gemspec | gemspec | ||||||
|  |  | ||||||
| if RUBY_VERSION < "1.9.3" |  | ||||||
|   # escape_utils 1.0.0 requires 1.9.3 and above |  | ||||||
|   gem "escape_utils", "0.3.2" |  | ||||||
| end |  | ||||||
|   | |||||||
							
								
								
									
										42
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								README.md
									
									
									
									
									
								
							| @@ -106,8 +106,50 @@ To update the `samples.json` after adding new files to [`samples/`](https://gith | |||||||
|  |  | ||||||
|     bundle exec rake 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 | ### 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: [](http://travis-ci.org/github/linguist) | Here's our current build status, which is hopefully green: [](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-3.0.0.gem` | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ | |||||||
|  |  | ||||||
| require 'linguist/file_blob' | require 'linguist/file_blob' | ||||||
| require 'linguist/repository' | require 'linguist/repository' | ||||||
|  | require 'rugged' | ||||||
|  |  | ||||||
| path = ARGV[0] || Dir.pwd | path = ARGV[0] || Dir.pwd | ||||||
|  |  | ||||||
| @@ -18,7 +19,8 @@ ARGV.shift | |||||||
| breakdown = true if ARGV[0] == "--breakdown" | breakdown = true if ARGV[0] == "--breakdown" | ||||||
|  |  | ||||||
| if File.directory?(path) | if File.directory?(path) | ||||||
|   repo = Linguist::Repository.from_directory(path) |   rugged = Rugged::Repository.new(path) | ||||||
|  |   repo = Linguist::Repository.new(rugged, rugged.head.target_id) | ||||||
|   repo.languages.sort_by { |_, size| size }.reverse.each do |language, size| |   repo.languages.sort_by { |_, size| size }.reverse.each do |language, size| | ||||||
|     percentage = ((size / repo.size.to_f) * 100) |     percentage = ((size / repo.size.to_f) * 100) | ||||||
|     percentage = sprintf '%.2f' % percentage |     percentage = sprintf '%.2f' % percentage | ||||||
|   | |||||||
| @@ -1,6 +1,8 @@ | |||||||
|  | require File.expand_path('../lib/linguist/version', __FILE__) | ||||||
|  |  | ||||||
| Gem::Specification.new do |s| | Gem::Specification.new do |s| | ||||||
|   s.name    = 'github-linguist' |   s.name    = 'github-linguist' | ||||||
|   s.version = '2.10.13' |   s.version = Linguist::VERSION | ||||||
|   s.summary = "GitHub Language detection" |   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.description = 'We use this library at GitHub to detect blob languages, highlight code, ignore binary files, suppress generated files in diffs, and generate language breakdown graphs.' | ||||||
|  |  | ||||||
| @@ -11,10 +13,11 @@ Gem::Specification.new do |s| | |||||||
|   s.files = Dir['lib/**/*'] |   s.files = Dir['lib/**/*'] | ||||||
|   s.executables << 'linguist' |   s.executables << 'linguist' | ||||||
|  |  | ||||||
|   s.add_dependency 'charlock_holmes', '~> 0.6.6' |   s.add_dependency 'charlock_holmes', '~> 0.7.3' | ||||||
|   s.add_dependency 'escape_utils',    '>= 0.3.1' |   s.add_dependency 'escape_utils',    '~> 1.0.1' | ||||||
|   s.add_dependency 'mime-types',      '~> 1.19' |   s.add_dependency 'mime-types',      '~> 1.19' | ||||||
|   s.add_dependency 'pygments.rb',     '~> 0.5.4' |   s.add_dependency 'pygments.rb',     '~> 0.6.0' | ||||||
|  |   s.add_dependency 'rugged',          '~> 0.21.0' | ||||||
|  |  | ||||||
|   s.add_development_dependency 'json' |   s.add_development_dependency 'json' | ||||||
|   s.add_development_dependency 'mocha' |   s.add_development_dependency 'mocha' | ||||||
|   | |||||||
| @@ -4,3 +4,4 @@ require 'linguist/heuristics' | |||||||
| require 'linguist/language' | require 'linguist/language' | ||||||
| require 'linguist/repository' | require 'linguist/repository' | ||||||
| require 'linguist/samples' | require 'linguist/samples' | ||||||
|  | require 'linguist/version' | ||||||
|   | |||||||
| @@ -1,5 +1,4 @@ | |||||||
| require 'linguist/generated' | require 'linguist/generated' | ||||||
| require 'linguist/language' |  | ||||||
|  |  | ||||||
| require 'charlock_holmes' | require 'charlock_holmes' | ||||||
| require 'escape_utils' | require 'escape_utils' | ||||||
| @@ -112,6 +111,12 @@ module Linguist | |||||||
|       end |       end | ||||||
|     end |     end | ||||||
|  |  | ||||||
|  |     def ruby_encoding | ||||||
|  |       if hash = detect_encoding | ||||||
|  |         hash[:ruby_encoding] | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  |  | ||||||
|     # Try to guess the encoding |     # Try to guess the encoding | ||||||
|     # |     # | ||||||
|     # Returns: a Hash, with :encoding, :confidence, :type |     # Returns: a Hash, with :encoding, :confidence, :type | ||||||
| @@ -241,7 +246,31 @@ module Linguist | |||||||
|     def lines |     def lines | ||||||
|       @lines ||= |       @lines ||= | ||||||
|         if viewable? && data |         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 |         else | ||||||
|           [] |           [] | ||||||
|         end |         end | ||||||
| @@ -283,15 +312,7 @@ module Linguist | |||||||
|     # |     # | ||||||
|     # Returns a Language or nil if none is detected |     # Returns a Language or nil if none is detected | ||||||
|     def language |     def language | ||||||
|       return @language if defined? @language |       @language ||= Language.detect(self) | ||||||
|  |  | ||||||
|       if defined?(@data) && @data.is_a?(String) |  | ||||||
|         data = @data |  | ||||||
|       else |  | ||||||
|         data = lambda { (binary_mime_type? || binary?) ? "" : self.data } |  | ||||||
|       end |  | ||||||
|  |  | ||||||
|       @language = Language.detect(name.to_s, data, mode) |  | ||||||
|     end |     end | ||||||
|  |  | ||||||
|     # Internal: Get the lexer of the blob. |     # Internal: Get the lexer of the blob. | ||||||
|   | |||||||
| @@ -52,5 +52,20 @@ module Linguist | |||||||
|     def size |     def size | ||||||
|       File.size(@path) |       File.size(@path) | ||||||
|     end |     end | ||||||
|  |  | ||||||
|  |     # Public: Get file extension. | ||||||
|  |     # | ||||||
|  |     # Returns a String. | ||||||
|  |     def extension | ||||||
|  |       # File.extname returns nil if the filename is an extension. | ||||||
|  |       extension = File.extname(name) | ||||||
|  |       basename = File.basename(name) | ||||||
|  |       # Checks if the filename is an extension. | ||||||
|  |       if extension.empty? && basename[0] == "." | ||||||
|  |         basename | ||||||
|  |       else | ||||||
|  |         extension | ||||||
|  |       end | ||||||
|  |     end | ||||||
|   end |   end | ||||||
| end | end | ||||||
|   | |||||||
| @@ -54,7 +54,7 @@ module Linguist | |||||||
|       name == 'Gemfile.lock' || |       name == 'Gemfile.lock' || | ||||||
|         minified_files? || |         minified_files? || | ||||||
|         compiled_coffeescript? || |         compiled_coffeescript? || | ||||||
|         xcode_project_file? || |         xcode_file? || | ||||||
|         generated_parser? || |         generated_parser? || | ||||||
|         generated_net_docfile? || |         generated_net_docfile? || | ||||||
|         generated_net_designer_file? || |         generated_net_designer_file? || | ||||||
| @@ -63,17 +63,18 @@ module Linguist | |||||||
|         generated_jni_header? || |         generated_jni_header? || | ||||||
|         composer_lock? || |         composer_lock? || | ||||||
|         node_modules? || |         node_modules? || | ||||||
|         vcr_cassette? |         vcr_cassette? || | ||||||
|  |         generated_by_zephir? | ||||||
|     end |     end | ||||||
|  |  | ||||||
|     # Internal: Is the blob an XCode project file? |     # Internal: Is the blob an Xcode file? | ||||||
|     # |     # | ||||||
|     # Generated if the file extension is an XCode project |     # Generated if the file extension is an Xcode  | ||||||
|     # file extension. |     # file extension. | ||||||
|     # |     # | ||||||
|     # Returns true of false. |     # Returns true of false. | ||||||
|     def xcode_project_file? |     def xcode_file? | ||||||
|       ['.xib', '.nib', '.storyboard', '.pbxproj', '.xcworkspacedata', '.xcuserstate'].include?(extname) |       ['.nib', '.xcworkspacedata', '.xcuserstate'].include?(extname) | ||||||
|     end |     end | ||||||
|  |  | ||||||
|     # Internal: Is the blob minified files? |     # Internal: Is the blob minified files? | ||||||
| @@ -237,6 +238,13 @@ module Linguist | |||||||
|       !!name.match(/composer.lock/) |       !!name.match(/composer.lock/) | ||||||
|     end |     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? |     # Is the blob a VCR Cassette file? | ||||||
|     # |     # | ||||||
|     # Returns true or false |     # Returns true or false | ||||||
| @@ -248,3 +256,4 @@ module Linguist | |||||||
|     end |     end | ||||||
|   end |   end | ||||||
| end | end | ||||||
|  |  | ||||||
|   | |||||||
| @@ -9,6 +9,8 @@ end | |||||||
| require 'linguist/classifier' | require 'linguist/classifier' | ||||||
| require 'linguist/heuristics' | require 'linguist/heuristics' | ||||||
| require 'linguist/samples' | require 'linguist/samples' | ||||||
|  | require 'linguist/file_blob' | ||||||
|  | require 'linguist/blob_helper' | ||||||
|  |  | ||||||
| module Linguist | module Linguist | ||||||
|   # Language names that are recognizable by GitHub. Defined languages |   # Language names that are recognizable by GitHub. Defined languages | ||||||
| @@ -24,7 +26,6 @@ module Linguist | |||||||
|     @extension_index          = Hash.new { |h,k| h[k] = [] } |     @extension_index          = Hash.new { |h,k| h[k] = [] } | ||||||
|     @interpreter_index        = Hash.new { |h,k| h[k] = [] } |     @interpreter_index        = Hash.new { |h,k| h[k] = [] } | ||||||
|     @filename_index           = Hash.new { |h,k| h[k] = [] } |     @filename_index           = Hash.new { |h,k| h[k] = [] } | ||||||
|     @primary_extension_index  = {} |  | ||||||
|  |  | ||||||
|     # Valid Languages types |     # Valid Languages types | ||||||
|     TYPES = [:data, :markup, :programming, :prose] |     TYPES = [:data, :markup, :programming, :prose] | ||||||
| @@ -80,12 +81,6 @@ module Linguist | |||||||
|         @extension_index[extension] << language |         @extension_index[extension] << language | ||||||
|       end |       end | ||||||
|  |  | ||||||
|       if @primary_extension_index.key?(language.primary_extension) |  | ||||||
|         raise ArgumentError, "Duplicate primary extension: #{language.primary_extension}" |  | ||||||
|       end |  | ||||||
|  |  | ||||||
|       @primary_extension_index[language.primary_extension] = language |  | ||||||
|  |  | ||||||
|       language.interpreters.each do |interpreter| |       language.interpreters.each do |interpreter| | ||||||
|         @interpreter_index[interpreter] << language |         @interpreter_index[interpreter] << language | ||||||
|       end |       end | ||||||
| @@ -99,18 +94,25 @@ module Linguist | |||||||
|  |  | ||||||
|     # Public: Detects the Language of the blob. |     # Public: Detects the Language of the blob. | ||||||
|     # |     # | ||||||
|     # name - String filename |     # blob - an object that includes the Linguist `BlobHelper` interface; | ||||||
|     # data - String blob data. A block also maybe passed in for lazy |     #       see Linguist::LazyBlob and Linguist::FileBlob for examples | ||||||
|     #        loading. This behavior is deprecated and you should always |  | ||||||
|     #        pass in a String. |  | ||||||
|     # mode - Optional String mode (defaults to nil) |  | ||||||
|     # |     # | ||||||
|     # Returns Language or nil. |     # Returns Language or nil. | ||||||
|     def self.detect(name, data, mode = nil) |     def self.detect(blob) | ||||||
|  |       name = blob.name.to_s | ||||||
|  |  | ||||||
|  |       # Check if the blob is possibly binary and bail early; this is a cheap | ||||||
|  |       # test that uses the extension name to guess a binary binary mime type. | ||||||
|  |       # | ||||||
|  |       # We'll perform a more comprehensive test later which actually involves | ||||||
|  |       # looking for binary characters in the blob | ||||||
|  |       return nil if blob.likely_binary? || blob.binary? | ||||||
|  |  | ||||||
|       # A bit of an elegant hack. If the file is executable but extensionless, |       # A bit of an elegant hack. If the file is executable but extensionless, | ||||||
|       # append a "magic" extension so it can be classified with other |       # append a "magic" extension so it can be classified with other | ||||||
|       # languages that have shebang scripts. |       # languages that have shebang scripts. | ||||||
|       if File.extname(name).empty? && mode && (mode.to_i(8) & 05) == 05 |       extension = FileBlob.new(name).extension | ||||||
|  |       if extension.empty? && blob.mode && (blob.mode.to_i(8) & 05) == 05 | ||||||
|         name += ".script!" |         name += ".script!" | ||||||
|       end |       end | ||||||
|  |  | ||||||
| @@ -121,10 +123,10 @@ module Linguist | |||||||
|       # extension at all, in the case of extensionless scripts), we need to continue |       # extension at all, in the case of extensionless scripts), we need to continue | ||||||
|       # our detection work |       # our detection work | ||||||
|       if possible_languages.length > 1 |       if possible_languages.length > 1 | ||||||
|         data = data.call() if data.respond_to?(:call) |         data = blob.data | ||||||
|         possible_language_names = possible_languages.map(&:name) |         possible_language_names = possible_languages.map(&:name) | ||||||
|  |  | ||||||
|         # Don't bother with emptiness |         # Don't bother with binary contents or an empty file | ||||||
|         if data.nil? || data == "" |         if data.nil? || data == "" | ||||||
|           nil |           nil | ||||||
|         # Check if there's a shebang line and use that as authoritative |         # Check if there's a shebang line and use that as authoritative | ||||||
| @@ -190,9 +192,9 @@ module Linguist | |||||||
|     # |     # | ||||||
|     # Returns all matching Languages or [] if none were found. |     # Returns all matching Languages or [] if none were found. | ||||||
|     def self.find_by_filename(filename) |     def self.find_by_filename(filename) | ||||||
|       basename, extname = File.basename(filename), File.extname(filename) |       basename = File.basename(filename) | ||||||
|       langs = [@primary_extension_index[extname]] + |       extname = FileBlob.new(filename).extension | ||||||
|               @filename_index[basename] + |       langs = @filename_index[basename] + | ||||||
|               @extension_index[extname] |               @extension_index[extname] | ||||||
|       langs.compact.uniq |       langs.compact.uniq | ||||||
|     end |     end | ||||||
| @@ -299,15 +301,6 @@ module Linguist | |||||||
|       @interpreters = attributes[:interpreters]   || [] |       @interpreters = attributes[:interpreters]   || [] | ||||||
|       @filenames  = attributes[:filenames]  || [] |       @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 |       # Set popular, and searchable flags | ||||||
|       @popular    = attributes.key?(:popular)    ? attributes[:popular]    : false |       @popular    = attributes.key?(:popular)    ? attributes[:popular]    : false | ||||||
|       @searchable = attributes.key?(:searchable) ? attributes[:searchable] : true |       @searchable = attributes.key?(:searchable) ? attributes[:searchable] : true | ||||||
| @@ -395,20 +388,6 @@ module Linguist | |||||||
|     # Returns the extensions Array |     # Returns the extensions Array | ||||||
|     attr_reader :extensions |     attr_reader :extensions | ||||||
|  |  | ||||||
|     # Deprecated: Get primary extension |  | ||||||
|     # |  | ||||||
|     # Defaults to the first extension but can be overridden |  | ||||||
|     # in the languages.yml. |  | ||||||
|     # |  | ||||||
|     # The primary extension can not be nil. Tests should verify this. |  | ||||||
|     # |  | ||||||
|     # This attribute is only used by app/helpers/gists_helper.rb for |  | ||||||
|     # creating the language dropdown. It really should be using `name` |  | ||||||
|     # instead. Would like to drop primary extension. |  | ||||||
|     # |  | ||||||
|     # Returns the extension String. |  | ||||||
|     attr_reader :primary_extension |  | ||||||
|  |  | ||||||
|     # Public: Get interpreters |     # Public: Get interpreters | ||||||
|     # |     # | ||||||
|     # Examples |     # Examples | ||||||
| @@ -432,6 +411,22 @@ module Linguist | |||||||
|       (extensions + [primary_extension]).uniq |       (extensions + [primary_extension]).uniq | ||||||
|     end |     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. |     # Public: Get URL escaped name. | ||||||
|     # |     # | ||||||
|     # Examples |     # Examples | ||||||
| @@ -573,9 +568,8 @@ module Linguist | |||||||
|       :group_name        => options['group'], |       :group_name        => options['group'], | ||||||
|       :searchable        => options.key?('searchable') ? options['searchable'] : true, |       :searchable        => options.key?('searchable') ? options['searchable'] : true, | ||||||
|       :search_term       => options['search_term'], |       :search_term       => options['search_term'], | ||||||
|       :extensions        => options['extensions'].sort, |       :extensions        => [options['extensions'].first] + options['extensions'][1..-1].sort, | ||||||
|       :interpreters      => options['interpreters'].sort, |       :interpreters      => options['interpreters'].sort, | ||||||
|       :primary_extension => options['primary_extension'], |  | ||||||
|       :filenames         => options['filenames'], |       :filenames         => options['filenames'], | ||||||
|       :popular           => popular.include?(name) |       :popular           => popular.include?(name) | ||||||
|     ) |     ) | ||||||
|   | |||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										37
									
								
								lib/linguist/lazy_blob.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								lib/linguist/lazy_blob.rb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | |||||||
|  | require 'linguist/blob_helper' | ||||||
|  | require 'rugged' | ||||||
|  |  | ||||||
|  | module Linguist | ||||||
|  |   class LazyBlob | ||||||
|  |     include BlobHelper | ||||||
|  |  | ||||||
|  |     MAX_SIZE = 128 * 1024 | ||||||
|  |  | ||||||
|  |     attr_reader :repository | ||||||
|  |     attr_reader :oid | ||||||
|  |     attr_reader :name | ||||||
|  |     attr_reader :mode | ||||||
|  |  | ||||||
|  |     def initialize(repo, oid, name, mode = nil) | ||||||
|  |       @repository = repo | ||||||
|  |       @oid = oid | ||||||
|  |       @name = name | ||||||
|  |       @mode = mode | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def data | ||||||
|  |       load_blob! | ||||||
|  |       @data | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def size | ||||||
|  |       load_blob! | ||||||
|  |       @size | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     protected | ||||||
|  |     def load_blob! | ||||||
|  |       @data, @size = Rugged::Blob.to_buffer(repository, oid, MAX_SIZE) if @data.nil? | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | end | ||||||
| @@ -1,4 +1,5 @@ | |||||||
| require 'linguist/file_blob' | require 'linguist/lazy_blob' | ||||||
|  | require 'rugged' | ||||||
|  |  | ||||||
| module Linguist | module Linguist | ||||||
|   # A Repository is an abstraction of a Grit::Repo or a basic file |   # A Repository is an abstraction of a Grit::Repo or a basic file | ||||||
| @@ -7,100 +8,146 @@ module Linguist | |||||||
|   # Its primary purpose is for gathering language statistics across |   # Its primary purpose is for gathering language statistics across | ||||||
|   # the entire project. |   # the entire project. | ||||||
|   class Repository |   class Repository | ||||||
|     # Public: Initialize a new Repository from a File directory |     attr_reader :repository | ||||||
|     # |  | ||||||
|     # base_path - A path String |     # Public: Create a new Repository based on the stats of | ||||||
|     # |     # an existing one | ||||||
|     # Returns a Repository |     def self.incremental(repo, commit_oid, old_commit_oid, old_stats) | ||||||
|     def self.from_directory(base_path) |       repo = self.new(repo, commit_oid) | ||||||
|       new Dir["#{base_path}/**/*"]. |       repo.load_existing_stats(old_commit_oid, old_stats) | ||||||
|         select { |f| File.file?(f) }. |       repo | ||||||
|         map { |path| FileBlob.new(path, base_path) } |  | ||||||
|     end |     end | ||||||
|  |  | ||||||
|     # Public: Initialize a new Repository |     # Public: Initialize a new Repository to be analyzed for language | ||||||
|  |     # data | ||||||
|     # |     # | ||||||
|     # enum - Enumerator that responds to `each` and |     # repo - a Rugged::Repository object | ||||||
|     #        yields Blob objects |     # commit_oid - the sha1 of the commit that will be analyzed; | ||||||
|  |     #              this is usually the master branch | ||||||
|     # |     # | ||||||
|     # Returns a Repository |     # Returns a Repository | ||||||
|     def initialize(enum) |     def initialize(repo, commit_oid) | ||||||
|       @enum = enum |       @repository = repo | ||||||
|       @computed_stats = false |       @commit_oid = commit_oid | ||||||
|       @language = @size = nil |  | ||||||
|       @sizes = Hash.new { 0 } |       raise TypeError, 'commit_oid must be a commit SHA1' unless commit_oid.is_a?(String) | ||||||
|       @file_breakdown = Hash.new { |h,k| h[k] = Array.new } |     end | ||||||
|  |  | ||||||
|  |     # Public: Load the results of a previous analysis on this repository | ||||||
|  |     # to speed up the new scan. | ||||||
|  |     # | ||||||
|  |     # The new analysis will be performed incrementally as to only take | ||||||
|  |     # into account the file changes since the last time the repository | ||||||
|  |     # was scanned | ||||||
|  |     # | ||||||
|  |     # old_commit_oid - the sha1 of the commit that was previously analyzed | ||||||
|  |     # old_stats - the result of the previous analysis, obtained by calling | ||||||
|  |     #             Repository#cache on the old repository | ||||||
|  |     # | ||||||
|  |     # Returns nothing | ||||||
|  |     def load_existing_stats(old_commit_oid, old_stats) | ||||||
|  |       @old_commit_oid = old_commit_oid | ||||||
|  |       @old_stats = old_stats | ||||||
|  |       nil | ||||||
|     end |     end | ||||||
|  |  | ||||||
|     # Public: Returns a breakdown of language stats. |     # Public: Returns a breakdown of language stats. | ||||||
|     # |     # | ||||||
|     # Examples |     # Examples | ||||||
|     # |     # | ||||||
|     #   # => { Language['Ruby'] => 46319, |     #   # => { 'Ruby' => 46319, | ||||||
|     #          Language['JavaScript'] => 258 } |     #          'JavaScript' => 258 } | ||||||
|     # |     # | ||||||
|     # Returns a Hash of Language keys and Integer size values. |     # Returns a Hash of language names and Integer size values. | ||||||
|     def languages |     def languages | ||||||
|       compute_stats |       @sizes ||= begin | ||||||
|       @sizes |         sizes = Hash.new { 0 } | ||||||
|  |         cache.each do |_, (language, size)| | ||||||
|  |           sizes[language] += size | ||||||
|  |         end | ||||||
|  |         sizes | ||||||
|  |       end | ||||||
|     end |     end | ||||||
|  |  | ||||||
|     # Public: Get primary Language of repository. |     # Public: Get primary Language of repository. | ||||||
|     # |     # | ||||||
|     # Returns a Language |     # Returns a language name | ||||||
|     def language |     def language | ||||||
|       compute_stats |       @language ||= begin | ||||||
|       @language |         primary = languages.max_by { |(_, size)| size } | ||||||
|  |         primary && primary[0] | ||||||
|  |       end | ||||||
|     end |     end | ||||||
|  |  | ||||||
|     # Public: Get the total size of the repository. |     # Public: Get the total size of the repository. | ||||||
|     # |     # | ||||||
|     # Returns a byte size Integer |     # Returns a byte size Integer | ||||||
|     def size |     def size | ||||||
|       compute_stats |       @size ||= languages.inject(0) { |s,(_,v)| s + v } | ||||||
|       @size |  | ||||||
|     end |     end | ||||||
|  |  | ||||||
|     # Public: Return the language breakdown of this repository by file |     # Public: Return the language breakdown of this repository by file | ||||||
|  |     # | ||||||
|  |     # Returns a map of language names => [filenames...] | ||||||
|     def breakdown_by_file |     def breakdown_by_file | ||||||
|       compute_stats |       @file_breakdown ||= begin | ||||||
|       @file_breakdown |         breakdown = Hash.new { |h,k| h[k] = Array.new } | ||||||
|  |         cache.each do |filename, (language, _)| | ||||||
|  |           breakdown[language] << filename | ||||||
|  |         end | ||||||
|  |         breakdown | ||||||
|  |       end | ||||||
|     end |     end | ||||||
|  |  | ||||||
|     # Internal: Compute language breakdown for each blob in the Repository. |     # Public: Return the cached results of the analysis | ||||||
|     # |     # | ||||||
|     # Returns nothing |     # This is a per-file breakdown that can be passed to other instances | ||||||
|     def compute_stats |     # of Linguist::Repository to perform incremental scans | ||||||
|       return if @computed_stats |     # | ||||||
|  |     # Returns a map of filename => [language, size] | ||||||
|  |     def cache | ||||||
|  |       @cache ||= begin | ||||||
|  |         if @old_commit_oid == @commit_oid | ||||||
|  |           @old_stats | ||||||
|  |         else | ||||||
|  |           compute_stats(@old_commit_oid, @commit_oid, @old_stats) | ||||||
|  |         end | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  |  | ||||||
|       @enum.each do |blob| |     protected | ||||||
|         # Skip files that are likely binary |     def compute_stats(old_commit_oid, commit_oid, cache = nil) | ||||||
|         next if blob.likely_binary? |       file_map = cache ? cache.dup : {} | ||||||
|  |       old_tree = old_commit_oid && Rugged::Commit.lookup(repository, old_commit_oid).tree | ||||||
|  |       new_tree = Rugged::Commit.lookup(repository, commit_oid).tree | ||||||
|  |  | ||||||
|         # Skip vendored or generated blobs |       diff = Rugged::Tree.diff(repository, old_tree, new_tree) | ||||||
|         next if blob.vendored? || blob.generated? || blob.language.nil? |  | ||||||
|  |  | ||||||
|         # Only include programming languages and acceptable markup languages |       diff.each_delta do |delta| | ||||||
|         if blob.language.type == :programming || Language.detectable_markup.include?(blob.language.name) |         old = delta.old_file[:path] | ||||||
|  |         new = delta.new_file[:path] | ||||||
|  |  | ||||||
|           # Build up the per-file breakdown stats |         file_map.delete(old) | ||||||
|           @file_breakdown[blob.language.group.name] << blob.name |         next if delta.binary | ||||||
|  |  | ||||||
|           @sizes[blob.language.group] += blob.size |         if [:added, :modified].include? delta.status | ||||||
|  |           # Skip submodules | ||||||
|  |           mode = delta.new_file[:mode] | ||||||
|  |           next if (mode & 040000) != 0 | ||||||
|  |  | ||||||
|  |           blob = Linguist::LazyBlob.new(repository, delta.new_file[:oid], new, mode.to_s(8)) | ||||||
|  |  | ||||||
|  |           # Skip vendored or generated blobs | ||||||
|  |           next if blob.vendored? || blob.generated? || blob.language.nil? | ||||||
|  |  | ||||||
|  |           # Only include programming languages and acceptable markup languages | ||||||
|  |           if blob.language.type == :programming || Language.detectable_markup.include?(blob.language.name) | ||||||
|  |             file_map[new] = [blob.language.group.name, blob.size] | ||||||
|  |           end | ||||||
|         end |         end | ||||||
|       end |       end | ||||||
|  |  | ||||||
|       # Compute total size |       file_map | ||||||
|       @size = @sizes.inject(0) { |s,(_,v)| s + v } |  | ||||||
|  |  | ||||||
|       # Get primary language |  | ||||||
|       if primary = @sizes.max_by { |(_, size)| size } |  | ||||||
|         @language = primary[0] |  | ||||||
|       end |  | ||||||
|  |  | ||||||
|       @computed_stats = true |  | ||||||
|  |  | ||||||
|       nil |  | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
| end | end | ||||||
|   | |||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -28,7 +28,7 @@ module Linguist | |||||||
|     # |     # | ||||||
|     # Returns nothing. |     # Returns nothing. | ||||||
|     def self.each(&block) |     def self.each(&block) | ||||||
|       Dir.entries(ROOT).each do |category| |       Dir.entries(ROOT).sort!.each do |category| | ||||||
|         next if category == '.' || category == '..' |         next if category == '.' || category == '..' | ||||||
|  |  | ||||||
|         # Skip text and binary for now |         # Skip text and binary for now | ||||||
|   | |||||||
| @@ -40,9 +40,13 @@ | |||||||
| - foundation.min.css | - foundation.min.css | ||||||
| - foundation.css | - foundation.css | ||||||
|  |  | ||||||
|  | # Normalize.css | ||||||
|  | - normalize.css | ||||||
|  |  | ||||||
| # Vendored dependencies | # Vendored dependencies | ||||||
| - thirdparty/ | - thirdparty/ | ||||||
| - vendors?/ | - vendors?/ | ||||||
|  | - extern(al)?/ | ||||||
|  |  | ||||||
| # Debian packaging | # Debian packaging | ||||||
| - ^debian/ | - ^debian/ | ||||||
| @@ -98,9 +102,16 @@ | |||||||
| # AngularJS | # AngularJS | ||||||
| - (^|/)angular([^.]*)(\.min)?\.js$ | - (^|/)angular([^.]*)(\.min)?\.js$ | ||||||
|  |  | ||||||
|  | # D3.js | ||||||
|  | - (^|\/)d3(\.v\d+)?([^.]*)(\.min)?\.js$ | ||||||
|  |  | ||||||
| # React | # React | ||||||
| - (^|/)react(-[^.]*)?(\.min)?\.js$ | - (^|/)react(-[^.]*)?(\.min)?\.js$ | ||||||
|  |  | ||||||
|  | # Modernizr | ||||||
|  | - (^|/)modernizr\-\d\.\d+(\.\d+)?(\.min)?\.js$ | ||||||
|  | - (^|/)modernizr\.custom\.\d+\.js$ | ||||||
|  |  | ||||||
| ## Python ## | ## Python ## | ||||||
|  |  | ||||||
| # django | # django | ||||||
| @@ -117,6 +128,9 @@ | |||||||
|  |  | ||||||
| ## Obj-C ## | ## Obj-C ## | ||||||
|  |  | ||||||
|  | # Cocoapods | ||||||
|  | - ^Pods/ | ||||||
|  |  | ||||||
| # Sparkle | # Sparkle | ||||||
| - (^|/)Sparkle/ | - (^|/)Sparkle/ | ||||||
|  |  | ||||||
| @@ -141,7 +155,7 @@ | |||||||
| - (^|/)[Mm]icrosoft([Mm]vc)?([Aa]jax|[Vv]alidation)(\.debug)?\.js$ | - (^|/)[Mm]icrosoft([Mm]vc)?([Aa]jax|[Vv]alidation)(\.debug)?\.js$ | ||||||
|  |  | ||||||
| # NuGet | # NuGet | ||||||
| - ^[Pp]ackages/ | - ^[Pp]ackages\/.+\.\d+\/ | ||||||
|  |  | ||||||
| # ExtJS | # ExtJS | ||||||
| - (^|/)extjs/.*?\.js$ | - (^|/)extjs/.*?\.js$ | ||||||
| @@ -161,6 +175,9 @@ | |||||||
| - (^|/)extjs/src/ | - (^|/)extjs/src/ | ||||||
| - (^|/)extjs/welcome/ | - (^|/)extjs/welcome/ | ||||||
|  |  | ||||||
|  | # Html5shiv | ||||||
|  | - (^|/)html5shiv(\.min)?\.js$ | ||||||
|  |  | ||||||
| # Samples folders | # Samples folders | ||||||
| - ^[Ss]amples/ | - ^[Ss]amples/ | ||||||
|  |  | ||||||
| @@ -189,3 +206,12 @@ | |||||||
|  |  | ||||||
| # Mercury --use-subdirs | # Mercury --use-subdirs | ||||||
| - Mercury/ | - Mercury/ | ||||||
|  |  | ||||||
|  | # R packages | ||||||
|  | - ^vignettes/ | ||||||
|  | - ^inst/extdata/ | ||||||
|  |  | ||||||
|  | # Octicons | ||||||
|  | - octicons.css | ||||||
|  | - octicons.min.css | ||||||
|  | - sprockets-octicons.scss | ||||||
|   | |||||||
							
								
								
									
										3
									
								
								lib/linguist/version.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								lib/linguist/version.rb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | module Linguist | ||||||
|  |   VERSION = "3.1.0" | ||||||
|  | end | ||||||
							
								
								
									
										350
									
								
								samples/Assembly/FASM.asm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										350
									
								
								samples/Assembly/FASM.asm
									
									
									
									
									
										Normal 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 | ||||||
							
								
								
									
										25
									
								
								samples/BlitzMax/sample.bmx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								samples/BlitzMax/sample.bmx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | |||||||
|  | SuperStrict | ||||||
|  |  | ||||||
|  | Framework Brl.StandardIO | ||||||
|  |  | ||||||
|  | Type TMyType | ||||||
|  | 	Field property:int | ||||||
|  |  | ||||||
|  | 	Function A:int(param:int) | ||||||
|  | 		'do nothing | ||||||
|  | 	End Function | ||||||
|  |  | ||||||
|  | 	Method B:int(param:int) | ||||||
|  | 		'do nothing | ||||||
|  | 	End Method | ||||||
|  | End Type | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Global my:TMyType = new TMyType | ||||||
|  | ?Win32 | ||||||
|  | 	my.A() | ||||||
|  | 	my.B() | ||||||
|  | ?Linux | ||||||
|  | 	my.B() | ||||||
|  | 	my.A() | ||||||
|  | ? | ||||||
							
								
								
									
										664
									
								
								samples/C++/epoll_reactor.ipp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										664
									
								
								samples/C++/epoll_reactor.ipp
									
									
									
									
									
										Normal 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 | ||||||
							
								
								
									
										130
									
								
								samples/Component Pascal/Example.cp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								samples/Component Pascal/Example.cp
									
									
									
									
									
										Normal 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. | ||||||
							
								
								
									
										71
									
								
								samples/Component Pascal/Example2.cps
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								samples/Component Pascal/Example2.cps
									
									
									
									
									
										Normal 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. | ||||||
							
								
								
									
										76
									
								
								samples/GAMS/transport.gms
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								samples/GAMS/transport.gms
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,76 @@ | |||||||
|  | *Basic example of transport model from GAMS model library | ||||||
|  |  | ||||||
|  | $Title  A Transportation Problem (TRNSPORT,SEQ=1) | ||||||
|  | $Ontext | ||||||
|  |  | ||||||
|  | This problem finds a least cost shipping schedule that meets | ||||||
|  | requirements at markets and supplies at factories. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Dantzig, G B, Chapter 3.3. In Linear Programming and Extensions. | ||||||
|  | Princeton University Press, Princeton, New Jersey, 1963. | ||||||
|  |  | ||||||
|  | This formulation is described in detail in: | ||||||
|  | Rosenthal, R E, Chapter 2: A GAMS Tutorial. In GAMS: A User's Guide. | ||||||
|  | The Scientific Press, Redwood City, California, 1988. | ||||||
|  |  | ||||||
|  | The line numbers will not match those in the book because of these | ||||||
|  | comments. | ||||||
|  |  | ||||||
|  | $Offtext | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   Sets | ||||||
|  |        i   canning plants   / seattle, san-diego / | ||||||
|  |        j   markets          / new-york, chicago, topeka / ; | ||||||
|  |   Parameters | ||||||
|  |        a(i)  capacity of plant i in cases | ||||||
|  |          /    seattle     350 | ||||||
|  |               san-diego   600  / | ||||||
|  |        b(j)  demand at market j in cases | ||||||
|  |          /    new-york    325 | ||||||
|  |               chicago     300 | ||||||
|  |               topeka      275  / ; | ||||||
|  |   Table d(i,j)  distance in thousands of miles | ||||||
|  |                     new-york       chicago      topeka | ||||||
|  |       seattle          2.5           1.7          1.8 | ||||||
|  |       san-diego        2.5           1.8          1.4  ; | ||||||
|  |   Scalar f  freight in dollars per case per thousand miles  /90/ ; | ||||||
|  |   Parameter c(i,j)  transport cost in thousands of dollars per case ; | ||||||
|  |             c(i,j) = f * d(i,j) / 1000 ; | ||||||
|  |   Variables | ||||||
|  |        x(i,j)  shipment quantities in cases | ||||||
|  |        z       total transportation costs in thousands of dollars ; | ||||||
|  |  | ||||||
|  |   Positive Variable x ; | ||||||
|  |  | ||||||
|  |   Equations | ||||||
|  |        cost        define objective function | ||||||
|  |        supply(i)   observe supply limit at plant i | ||||||
|  |        demand(j)   satisfy demand at market j ; | ||||||
|  |  | ||||||
|  |   cost ..        z  =e=  sum((i,j), c(i,j)*x(i,j)) ; | ||||||
|  |  | ||||||
|  |   supply(i) ..   sum(j, x(i,j))  =l=  a(i) ; | ||||||
|  |  | ||||||
|  |   demand(j) ..   sum(i, x(i,j))  =g=  b(j) ; | ||||||
|  |  | ||||||
|  |   Model transport /all/ ; | ||||||
|  |  | ||||||
|  |   Solve transport using lp minimizing z ; | ||||||
|  |  | ||||||
|  |   Display x.l, x.m ; | ||||||
|  |  | ||||||
|  | $ontext | ||||||
|  | #user model library stuff | ||||||
|  | Main topic Basic GAMS | ||||||
|  | Featured item 1 Trnsport model | ||||||
|  | Featured item 2 | ||||||
|  | Featured item 3 | ||||||
|  | Featured item 4 | ||||||
|  | Description | ||||||
|  | Basic example of transport model from GAMS model library | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | $offtext | ||||||
							
								
								
									
										9
									
								
								samples/GLSL/SimpleLighting.gl2.frag
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								samples/GLSL/SimpleLighting.gl2.frag
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | |||||||
|  | static const char* SimpleFragmentShader = STRINGIFY( | ||||||
|  |  | ||||||
|  | varying vec4 FrontColor; | ||||||
|  |  | ||||||
|  | void main(void) | ||||||
|  | { | ||||||
|  |     gl_FragColor = FrontColor; | ||||||
|  | } | ||||||
|  | ); | ||||||
							
								
								
									
										6
									
								
								samples/GLSL/myfragment.frg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								samples/GLSL/myfragment.frg
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | |||||||
|  | varying vec4 v_color; | ||||||
|  |  | ||||||
|  | void main() | ||||||
|  | { | ||||||
|  | 	gl_FragColor = v_color; | ||||||
|  | } | ||||||
							
								
								
									
										12
									
								
								samples/GLSL/myvertex.vrx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								samples/GLSL/myvertex.vrx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | |||||||
|  | uniform mat4 u_MVPMatrix; | ||||||
|  |  | ||||||
|  | attribute vec4 a_position; | ||||||
|  | attribute vec4 a_color; | ||||||
|  |  | ||||||
|  | varying vec4 v_color; | ||||||
|  |  | ||||||
|  | void main() | ||||||
|  | { | ||||||
|  | 	v_color = a_color; | ||||||
|  | 	gl_Position =  u_MVPMatrix * pos; | ||||||
|  | } | ||||||
							
								
								
									
										48
									
								
								samples/GLSL/recurse1.frag
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								samples/GLSL/recurse1.frag
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | |||||||
|  | #version 330 core | ||||||
|  |  | ||||||
|  | // cross-unit recursion | ||||||
|  |  | ||||||
|  | void main() {} | ||||||
|  |  | ||||||
|  | // two-level recursion | ||||||
|  |  | ||||||
|  | float cbar(int); | ||||||
|  |  | ||||||
|  | void cfoo(float) | ||||||
|  | { | ||||||
|  | 	cbar(2); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // four-level, out of order | ||||||
|  |  | ||||||
|  | void CB(); | ||||||
|  | void CD(); | ||||||
|  | void CA() { CB(); } | ||||||
|  | void CC() { CD(); } | ||||||
|  |  | ||||||
|  | // high degree | ||||||
|  |  | ||||||
|  | void CBT(); | ||||||
|  | void CDT(); | ||||||
|  | void CAT() { CBT(); CBT(); CBT(); } | ||||||
|  | void CCT() { CDT(); CDT(); CBT(); } | ||||||
|  |  | ||||||
|  | // not recursive | ||||||
|  |  | ||||||
|  | void norA() {} | ||||||
|  | void norB() { norA(); } | ||||||
|  | void norC() { norA(); } | ||||||
|  | void norD() { norA(); } | ||||||
|  | void norE() { norB(); } | ||||||
|  | void norF() { norB(); } | ||||||
|  | void norG() { norE(); } | ||||||
|  | void norH() { norE(); } | ||||||
|  | void norI() { norE(); } | ||||||
|  |  | ||||||
|  | // not recursive, but with a call leading into a cycle if ignoring direction | ||||||
|  |  | ||||||
|  | void norcA() { } | ||||||
|  | void norcB() { norcA(); } | ||||||
|  | void norcC() { norcB(); } | ||||||
|  | void norcD() { norcC(); norcB(); } // head of cycle | ||||||
|  | void norcE() { norcD(); } // lead into cycle | ||||||
							
								
								
									
										6
									
								
								samples/Grace/ackerman_function.grace
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								samples/Grace/ackerman_function.grace
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | |||||||
|  | method ack (m : Number, n : Number) -> Number { | ||||||
|  |   print "ack {m} {n}" | ||||||
|  |   if (m < = 0) then {n + 1} | ||||||
|  |    elseif {n <= 0} then {ack((m -1), 1)} | ||||||
|  |    else {ack(m -1, ack(m, n-1))} | ||||||
|  | } | ||||||
							
								
								
									
										554
									
								
								samples/Grace/grace_IDE.grace
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										554
									
								
								samples/Grace/grace_IDE.grace
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,554 @@ | |||||||
|  | import "gtk" as gtk | ||||||
|  | import "io" as io | ||||||
|  | import "mgcollections" as collections | ||||||
|  | import "button_factory" as button_factory | ||||||
|  | import "dialog_factory" as dialog_factory | ||||||
|  | import "syntax_highlighter" as highlighter | ||||||
|  | import "auto_completer" as aComp | ||||||
|  |  | ||||||
|  | //TODO | ||||||
|  |  | ||||||
|  | // Autocomplete typing | ||||||
|  |  | ||||||
|  | // FileChooser | ||||||
|  | // Themes | ||||||
|  |  | ||||||
|  | // Details for the Top Level Window | ||||||
|  | def window = gtk.window(gtk.GTK_WINDOW_TOPLEVEL) | ||||||
|  | window.title := "Grace" | ||||||
|  | window.set_default_size(700, 700) | ||||||
|  | // ------------- | ||||||
|  |  | ||||||
|  | // Placeholder for the console window that can be popped out | ||||||
|  | // of the main window | ||||||
|  | var popped := gtk.window(gtk.GTK_WINDOW_TOPLEVEL) | ||||||
|  |  | ||||||
|  | // Initialise the Boxes | ||||||
|  | def mBox = gtk.box(gtk.GTK_ORIENTATION_VERTICAL, 2) | ||||||
|  | def buttonBox = gtk.box(gtk.GTK_ORIENTATION_HORIZONTAL, 2) | ||||||
|  | var consoleButtons := gtk.box(gtk.GTK_ORIENTATION_HORIZONTAL, 3) | ||||||
|  | var consoleBox := gtk.box(gtk.GTK_ORIENTATION_VERTICAL, 2) | ||||||
|  | var editorBox := gtk.box(gtk.GTK_ORIENTATION_VERTICAL, 2) | ||||||
|  | var splitPane := gtk.paned(gtk.GTK_ORIENTATION_VERTICAL, 2) | ||||||
|  | def menuBox = gtk.box(gtk.GTK_ORIENTATION_HORIZONTAL, 4) | ||||||
|  | // ------------- | ||||||
|  |  | ||||||
|  | // Initialise the buttons | ||||||
|  | def runButton = button_factory.make("run") | ||||||
|  | var clearButton := button_factory.make("clear") | ||||||
|  | var outButton := button_factory.make("out") | ||||||
|  | var errorButton := button_factory.make("error") | ||||||
|  | var popButton := button_factory.make("pop") | ||||||
|  | def newButton = button_factory.make("new") | ||||||
|  | def openButton = button_factory.make("open") | ||||||
|  | def saveButton = button_factory.make("save") | ||||||
|  | def saveAsButton = button_factory.make("saveAs") | ||||||
|  | def closeButton = button_factory.make("close") | ||||||
|  | // ------------- | ||||||
|  |  | ||||||
|  | // Details for the default text editor and scrolled window | ||||||
|  | var tEdit := gtk.text_view | ||||||
|  | tEdit.set_size_request(700, 400) | ||||||
|  |  | ||||||
|  | var scrolled_main := gtk.scrolled_window | ||||||
|  | scrolled_main.set_size_request(700, 400) | ||||||
|  | scrolled_main.add(tEdit) | ||||||
|  | // ------------- | ||||||
|  |  | ||||||
|  | // Widget that allows multiple files to be edited (tabs) | ||||||
|  | var notebook := gtk.notebook | ||||||
|  | notebook.scrollable := true | ||||||
|  | // ------------- | ||||||
|  |  | ||||||
|  | // Maps for holding the text_views and scrolled_windows | ||||||
|  | var editor_map := collections.map.new | ||||||
|  | editor_map.put(0, tEdit) | ||||||
|  | var scrolled_map := collections.map.new | ||||||
|  | scrolled_map.put(0, scrolled_main) | ||||||
|  |  | ||||||
|  | // ------------- | ||||||
|  |  | ||||||
|  | // Class that manages the syntax highlighting (This needs to be passed around otherwise | ||||||
|  | // the text_tag table gets confused, ie there can only be one) | ||||||
|  | def lighter = highlighter.Syntax_Highlighter.new(notebook, editor_map) | ||||||
|  | tEdit.buffer.on "changed" do { | ||||||
|  |     lighter.highlightLine | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Class that manages any auto completion that is required | ||||||
|  | def completer =  aComp.Auto_Completer.new(window, notebook, editor_map) | ||||||
|  |  | ||||||
|  | // Utility methods | ||||||
|  | // ------------- | ||||||
|  |  | ||||||
|  | method deleteCompileFiles(page_num : Number) { | ||||||
|  |     def cur_scrolled = scrolled_map.get(page_num) | ||||||
|  |     var filename := notebook.get_tab_label_text(cur_scrolled) | ||||||
|  |     filename := filename.substringFrom(0)to(filename.size - 7) //Removes .grace extension | ||||||
|  |  | ||||||
|  |     io.system("rm -f files/" ++ filename) | ||||||
|  |     io.system("rm -f files/" ++ filename ++ ".c") | ||||||
|  |     io.system("rm -f files/" ++ filename ++ ".gcn") | ||||||
|  |     io.system("rm -f files/" ++ filename ++ ".gct") | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ------------- | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | var currentConsole := "output"      // Which console is being shown | ||||||
|  | var out := false | ||||||
|  |  | ||||||
|  |  | ||||||
|  | var outText := "" | ||||||
|  | var errorText := "" | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | // Give actions to the buttons | ||||||
|  | // ------------- | ||||||
|  |  | ||||||
|  | runButton.on "clicked" do { | ||||||
|  |     clearConsoles() | ||||||
|  |  | ||||||
|  |     // Get the details for the current page selected | ||||||
|  |     def cur_page_num = notebook.current_page | ||||||
|  |     def cur_page = editor_map.get(cur_page_num) | ||||||
|  |     def cur_scrolled = scrolled_map.get(cur_page_num) | ||||||
|  |     def cur_page_label = notebook.get_tab_label_text(cur_scrolled) | ||||||
|  |  | ||||||
|  |     // Initialise text iterators | ||||||
|  |     def sIter = gtk.text_iter | ||||||
|  |     def eIter = gtk.text_iter | ||||||
|  |  | ||||||
|  |     // Set one at the beggining and one at the end of the text | ||||||
|  |     cur_page.buffer.get_iter_at_offset(sIter, 0) | ||||||
|  |     cur_page.buffer.get_iter_at_offset(eIter, -1) | ||||||
|  |  | ||||||
|  |     // Get the text between the text iterators | ||||||
|  |     def text = cur_page.buffer.get_text(sIter, eIter, true) | ||||||
|  |  | ||||||
|  |     // Save the text to the file (in case the user hasn't already saved it) | ||||||
|  |     def file = io.open("files/" ++ cur_page_label, "w") | ||||||
|  |     file.write(text) | ||||||
|  |     file.close | ||||||
|  |  | ||||||
|  |     // Run the program and pipe the output and errors into files to be read | ||||||
|  |     io.system("../minigrace/minigrace " ++ "files/" ++ cur_page_label ++ " > output.txt 2> error.txt") | ||||||
|  |     def outputFile = io.open("output.txt", "r") | ||||||
|  |     def errorFile = io.open("error.txt", "r") | ||||||
|  |     outText := outputFile.read | ||||||
|  |     errorText := errorFile.read | ||||||
|  |  | ||||||
|  |     io.system("rm -f output.txt error.txt") | ||||||
|  |  | ||||||
|  |     var switched := false | ||||||
|  |  | ||||||
|  |     // Change the console to output if there is output text | ||||||
|  |     if((outText.size > 0) && (currentConsole != "output")) then { | ||||||
|  |         switch_to_output() | ||||||
|  |         switched := true | ||||||
|  |     } | ||||||
|  |     // Change the console to errors if there were errors | ||||||
|  |     if((errorText.size > 0) && (currentConsole != "errors")) then { | ||||||
|  |         switch_to_errors() | ||||||
|  |         switched := true | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Remember to populate the console if it wasn't switched | ||||||
|  |     if(!switched) then { | ||||||
|  |         populateConsoles | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | clearButton.on "clicked" do { | ||||||
|  |     clearConsoles() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | outButton.on "clicked" do { | ||||||
|  |     switch_to_output() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | errorButton.on "clicked" do { | ||||||
|  |     switch_to_errors() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | popButton.on "clicked" do { | ||||||
|  |     if(out) then { | ||||||
|  |         popIn() | ||||||
|  |     } else { | ||||||
|  |         popOut() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Gives a dialog to let the user create a new file to edit | ||||||
|  | newButton.on "clicked" do { | ||||||
|  |     def new_window_class = dialog_factory.new.new(notebook, editor_map, scrolled_map, lighter) | ||||||
|  |  | ||||||
|  |     def new_window = new_window_class.window() | ||||||
|  |     new_window.show_all | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Gives a dialog that lets the user open a file to edit | ||||||
|  | openButton.on "clicked" do { | ||||||
|  |     def open_window_class = dialog_factory.open.new(notebook, editor_map, scrolled_map, lighter) | ||||||
|  |  | ||||||
|  |     def open_window = open_window_class.window() | ||||||
|  |     open_window.show_all | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Saves the current file (if the name is Untitled.grace it will ask for a new name) | ||||||
|  | saveButton.on "clicked" do { | ||||||
|  |     def cur_page_num = notebook.current_page | ||||||
|  |     def cur_page = editor_map.get(cur_page_num) | ||||||
|  |     def cur_scrolled = scrolled_map.get(cur_page_num) | ||||||
|  |     def cur_page_label = notebook.get_tab_label_text(cur_scrolled) | ||||||
|  |  | ||||||
|  |     if(cur_page_label == "Untitled.grace") then { | ||||||
|  |         def saveAs_window_class = dialog_factory.save.new(notebook, editor_map, scrolled_map, true) | ||||||
|  |  | ||||||
|  |         def saveAs_window = saveAs_window_class.window() | ||||||
|  |         saveAs_window.show_all | ||||||
|  |     } else { | ||||||
|  |         // Initialise text iterators | ||||||
|  |         def sIter = gtk.text_iter | ||||||
|  |         def eIter = gtk.text_iter | ||||||
|  |  | ||||||
|  |         // Set one at the beggining and one at the end of the text | ||||||
|  |         cur_page.buffer.get_iter_at_offset(sIter, 0) | ||||||
|  |         cur_page.buffer.get_iter_at_offset(eIter, -1) | ||||||
|  |  | ||||||
|  |         // Get the text between the text iterators | ||||||
|  |         def text = cur_page.buffer.get_text(sIter, eIter, true) | ||||||
|  |  | ||||||
|  |         // Save the file | ||||||
|  |         def file = io.open("files/" ++ cur_page_label, "w") | ||||||
|  |         file.write(text) | ||||||
|  |         file.close | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Gives a dialog that lets the user save the file with a new name | ||||||
|  | saveAsButton.on "clicked" do { | ||||||
|  |     def saveAs_window_class = dialog_factory.save.new(notebook, editor_map, scrolled_map, false) | ||||||
|  |  | ||||||
|  |     def saveAs_window = saveAs_window_class.window() | ||||||
|  |     saveAs_window.show_all | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // This will close a tab on the notebook | ||||||
|  | // It also "removes" the page from the map, | ||||||
|  | // by creating a new temporary map and putting all but | ||||||
|  | // the removed page in. | ||||||
|  | closeButton.on "clicked" do { | ||||||
|  |     def page_num = notebook.current_page | ||||||
|  |     def num_pages = notebook.n_pages | ||||||
|  |  | ||||||
|  |     if(num_pages > 1) then { | ||||||
|  |         deleteCompileFiles(page_num) | ||||||
|  |  | ||||||
|  |         def e_map = collections.map.new | ||||||
|  |         def s_map = collections.map.new | ||||||
|  |  | ||||||
|  |         // Copy every page up to the current page into the new maps | ||||||
|  |         var x := 0 | ||||||
|  |         while {x < page_num} do { | ||||||
|  |             var eValue := editor_map.get(x) | ||||||
|  |             var sValue := scrolled_map.get(x) | ||||||
|  |             e_map.put(x, eValue) | ||||||
|  |             s_map.put(x, sValue) | ||||||
|  |  | ||||||
|  |             x := x + 1 | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Copy every page after the current page into the new map (shifted one down) | ||||||
|  |         x := page_num + 1 | ||||||
|  |         while {x < num_pages} do { | ||||||
|  |             var eValue := editor_map.get(x) | ||||||
|  |             var sValue := scrolled_map.get(x) | ||||||
|  |             e_map.put((x - 1), eValue) | ||||||
|  |             s_map.put((x - 1), sValue) | ||||||
|  |  | ||||||
|  |             x := x + 1 | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         editor_map := e_map | ||||||
|  |         scrolled_map := s_map | ||||||
|  |         notebook.remove_page(page_num) | ||||||
|  |  | ||||||
|  |         notebook.show_all | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
|  | // ------------- | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | // Consoles: | ||||||
|  | // ------------- | ||||||
|  |  | ||||||
|  | var outConsole := gtk.text_view | ||||||
|  | var outScroll := gtk.scrolled_window | ||||||
|  | var errorConsole := gtk.text_view | ||||||
|  | var errorScroll := gtk.scrolled_window | ||||||
|  | var errorTag := errorConsole.buffer.create_tag("fixed", "foreground", "red") | ||||||
|  |  | ||||||
|  |  | ||||||
|  | // Creates a new output console | ||||||
|  | method createOut { | ||||||
|  |     outConsole := gtk.text_view | ||||||
|  |     outScroll := gtk.scrolled_window | ||||||
|  |     outScroll.add(outConsole) | ||||||
|  |     if(out) then { | ||||||
|  |         outConsole.set_size_request(400, 400) | ||||||
|  |         outScroll.set_size_request(400, 400) | ||||||
|  |     } else { | ||||||
|  |         outConsole.set_size_request(700, 200) | ||||||
|  |         outScroll.set_size_request(700, 200) | ||||||
|  |     } | ||||||
|  |     outConsole.editable := false | ||||||
|  |     outConsole.buffer.set_text("[Output]:", -1) | ||||||
|  | } | ||||||
|  | createOut() | ||||||
|  |  | ||||||
|  | // Creates a new error console | ||||||
|  | method createError { | ||||||
|  |     errorConsole := gtk.text_view | ||||||
|  |     errorScroll := gtk.scrolled_window | ||||||
|  |     errorScroll.add(errorConsole) | ||||||
|  |     if(out) then { | ||||||
|  |         errorConsole.set_size_request(400, 400) | ||||||
|  |         errorScroll.set_size_request(400, 400) | ||||||
|  |     } else { | ||||||
|  |         errorConsole.set_size_request(700, 200) | ||||||
|  |         errorScroll.set_size_request(700, 200) | ||||||
|  |     } | ||||||
|  |     errorConsole.editable := false | ||||||
|  |     errorConsole.buffer.set_text("[Errors]:", -1) | ||||||
|  |     errorTag := errorConsole.buffer.create_tag("fixed", "foreground", "red") | ||||||
|  | } | ||||||
|  | createError() | ||||||
|  |  | ||||||
|  | // Switches the console being shown to be output. This requires | ||||||
|  | // the output console to be remade as it would have been destroyed when | ||||||
|  | // it was switched previously | ||||||
|  | method switch_to_output { | ||||||
|  |     if(currentConsole != "output") then { | ||||||
|  |         currentConsole := "output" | ||||||
|  |         consoleBox.remove(errorScroll)     // This destroys the errorConsole | ||||||
|  |  | ||||||
|  |         createOut() | ||||||
|  |  | ||||||
|  |         consoleBox.add(outScroll) | ||||||
|  |  | ||||||
|  |         populateConsoles() | ||||||
|  |         if(out) then { | ||||||
|  |             popped.show_all | ||||||
|  |         } else { | ||||||
|  |             window.show_all | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Switches the console being shown to be errors. This requires | ||||||
|  | // the error console to be remade as it would have been destroyed when | ||||||
|  | // it was switched previously | ||||||
|  | method switch_to_errors { | ||||||
|  |     if(currentConsole != "errors") then { | ||||||
|  |         currentConsole := "errors" | ||||||
|  |         consoleBox.remove(outScroll)       // This destroys the outConsole | ||||||
|  |  | ||||||
|  |         createError() | ||||||
|  |  | ||||||
|  |         consoleBox.add(errorScroll) | ||||||
|  |  | ||||||
|  |         populateConsoles() | ||||||
|  |         if(out) then { | ||||||
|  |             popped.show_all | ||||||
|  |         } else { | ||||||
|  |             window.show_all | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // If there is text to be put into the consoles this will add it | ||||||
|  | method populateConsoles { | ||||||
|  |     if((outText.size > 0) && (currentConsole == "output")) then { | ||||||
|  |         outConsole.buffer.set_text(outText, -1) | ||||||
|  |     } | ||||||
|  |     if((errorText.size > 0) && (currentConsole == "errors")) then { | ||||||
|  |         def sIter = gtk.text_iter | ||||||
|  |         def eIter = gtk.text_iter | ||||||
|  |  | ||||||
|  |         errorConsole.buffer.set_text(errorText, -1) | ||||||
|  |         errorConsole.buffer.get_iter_at_offset(sIter, 0) | ||||||
|  |         errorConsole.buffer.get_iter_at_offset(eIter, -1) | ||||||
|  |         errorConsole.buffer.apply_tag(errorTag, sIter, eIter) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | method clearConsoles { | ||||||
|  |     if(currentConsole == "output") then { | ||||||
|  |         outConsole.buffer.set_text("[Output]:", -1) | ||||||
|  |         outText := "" | ||||||
|  |     } | ||||||
|  |     if(currentConsole == "errors") then { | ||||||
|  |         errorConsole.buffer.set_text("[Errors]:", -1) | ||||||
|  |         errorText := "" | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | // Identical as the popIn method, but can be connected to the window's destroy button | ||||||
|  | def popInBlock = { | ||||||
|  |     consoleBox.reparent(splitPane) | ||||||
|  |     popButton.label := "Pop Out" | ||||||
|  |  | ||||||
|  |     if(currentConsole == "output") then { | ||||||
|  |         outConsole.set_size_request(700, 200) | ||||||
|  |         outScroll.set_size_request(700, 200) | ||||||
|  |     } | ||||||
|  |     if(currentConsole == "errors") then { | ||||||
|  |      errorConsole.set_size_request(700, 200) | ||||||
|  |      errorScroll.set_size_request(700, 200) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     def cur_page_num = notebook.current_page | ||||||
|  |     def cur_scrolled = scrolled_map.get(cur_page_num) | ||||||
|  |     def cur_page = editor_map.get(cur_page_num) | ||||||
|  |  | ||||||
|  |     cur_page.set_size_request(700, 400) | ||||||
|  |     cur_scrolled.set_size_request(700, 400) | ||||||
|  |  | ||||||
|  |     out := false | ||||||
|  |     popped.visible := false | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | // This pops the console out into a separate window | ||||||
|  | method popOut { | ||||||
|  |     popped := gtk.window(gtk.GTK_WINDOW_TOPLEVEL) | ||||||
|  |  | ||||||
|  |     consoleBox.reparent(popped) | ||||||
|  |     popButton.label := "Pop In" | ||||||
|  |  | ||||||
|  |     if(currentConsole == "output") then { | ||||||
|  |         outConsole.set_size_request(400, 400) | ||||||
|  |         outScroll.set_size_request(400, 400) | ||||||
|  |     } | ||||||
|  |     if(currentConsole == "errors") then { | ||||||
|  |         errorConsole.set_size_request(400, 400) | ||||||
|  |         errorScroll.set_size_request(400, 400) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     def cur_page_num = notebook.current_page | ||||||
|  |     def cur_scrolled = scrolled_map.get(cur_page_num) | ||||||
|  |     def cur_page = editor_map.get(cur_page_num) | ||||||
|  |  | ||||||
|  |     cur_page.set_size_request(700, 580) | ||||||
|  |     cur_scrolled.set_size_request(700, 580) | ||||||
|  |  | ||||||
|  |     out := true | ||||||
|  |     popped.visible := true | ||||||
|  |     popped.connect("destroy", popInBlock) | ||||||
|  |     popped.show_all | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Puts the console back into the main window | ||||||
|  | method popIn { | ||||||
|  |     consoleBox.reparent(splitPane) | ||||||
|  |     popButton.label := "Pop Out" | ||||||
|  |  | ||||||
|  |     if(currentConsole == "output") then { | ||||||
|  |         outConsole.set_size_request(700, 200) | ||||||
|  |         outScroll.set_size_request(700, 200) | ||||||
|  |     } | ||||||
|  |     if(currentConsole == "errors") then { | ||||||
|  |         errorConsole.set_size_request(700, 200) | ||||||
|  |         errorScroll.set_size_request(700, 200) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     def cur_page_num = notebook.current_page | ||||||
|  |     def cur_scrolled = scrolled_map.get(cur_page_num) | ||||||
|  |     def cur_page = editor_map.get(cur_page_num) | ||||||
|  |  | ||||||
|  |     cur_page.set_size_request(700, 400) | ||||||
|  |     cur_scrolled.set_size_request(700, 400) | ||||||
|  |  | ||||||
|  |     out := false | ||||||
|  |     popped.visible := false | ||||||
|  | } | ||||||
|  |  | ||||||
|  | clearConsoles() | ||||||
|  | // ------------- | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | // Patch everything together | ||||||
|  |  | ||||||
|  | var hSeparator1 := gtk.separator(gtk.GTK_ORIENTATION_HORIZONTAL) | ||||||
|  | var hSeparator2 := gtk.separator(gtk.GTK_ORIENTATION_HORIZONTAL) | ||||||
|  |  | ||||||
|  | menuBox.add(newButton) | ||||||
|  | menuBox.add(openButton) | ||||||
|  | menuBox.add(saveButton) | ||||||
|  | menuBox.add(saveAsButton) | ||||||
|  | buttonBox.add(runButton) | ||||||
|  | buttonBox.add(closeButton) | ||||||
|  |  | ||||||
|  | consoleButtons.add(outButton) | ||||||
|  | consoleButtons.add(errorButton) | ||||||
|  | consoleButtons.add(clearButton) | ||||||
|  | consoleButtons.add(popButton) | ||||||
|  |  | ||||||
|  | consoleBox.add(hSeparator1) | ||||||
|  | consoleBox.add(consoleButtons) | ||||||
|  | consoleBox.add(outScroll) | ||||||
|  |  | ||||||
|  | editorBox.add(hSeparator2) | ||||||
|  | notebook.add(scrolled_main) | ||||||
|  | notebook.set_tab_label_text(scrolled_main, "Untitled.grace") | ||||||
|  | editorBox.add(notebook) | ||||||
|  |  | ||||||
|  | splitPane.add1(editorBox) | ||||||
|  | splitPane.add2(consoleBox) | ||||||
|  |  | ||||||
|  | mBox.add(menuBox) | ||||||
|  | mBox.add(buttonBox) | ||||||
|  | mBox.add(splitPane) | ||||||
|  |  | ||||||
|  | window.add(mBox) | ||||||
|  |  | ||||||
|  | def exit = { | ||||||
|  |     var x := 0 | ||||||
|  |     while {x < notebook.n_pages} do { | ||||||
|  |         deleteCompileFiles(x) | ||||||
|  |  | ||||||
|  |         x := x + 1 | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Delete the compile files of the IDE | ||||||
|  |     io.system("rm -f Grace_IDE.gct Grace_IDE.c Grace_IDE.gcn") | ||||||
|  |     io.system("rm -f scanner.gct scanner.c scanner.gcn") | ||||||
|  |     io.system("rm -f syntax_highlighter.gct syntax_highlighter.c syntax_highlighter.gcn") | ||||||
|  |     io.system("rm -f syntax_colors.gct syntax_colors.c syntax_colors.gcn") | ||||||
|  |     io.system("rm -f button_factory.gct button_factory.c button_factory.gcn") | ||||||
|  |     io.system("rm -f dialog_factory.gct dialog_factory.c dialog_factory.gcn") | ||||||
|  |     io.system("rm -f auto_completer.gct auto_completer.c auto_completer.gcn") | ||||||
|  |  | ||||||
|  |     print "Grace IDE Closed Successfully" | ||||||
|  |     gtk.main_quit | ||||||
|  | } | ||||||
|  |  | ||||||
|  | window.connect("destroy", exit) | ||||||
|  | window.show_all | ||||||
|  |  | ||||||
|  | gtk.main | ||||||
							
								
								
									
										2
									
								
								samples/Groovy/script.gvy
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								samples/Groovy/script.gvy
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | #!/usr/bin/env groovy | ||||||
|  | println "Hello World" | ||||||
							
								
								
									
										9
									
								
								samples/Groovy/template.grt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								samples/Groovy/template.grt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | |||||||
|  | html { | ||||||
|  |   head { | ||||||
|  |     component "bootstrap" | ||||||
|  |     title "Bootstrap Template" | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   html { | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										9
									
								
								samples/Groovy/template.gtpl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								samples/Groovy/template.gtpl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | |||||||
|  | html { | ||||||
|  |   head { | ||||||
|  |     title "Example Template" | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   body { | ||||||
|  |     p "This is a quick template example" | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										60
									
								
								samples/HTML/ApiOverviewPage.st
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								samples/HTML/ApiOverviewPage.st
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,60 @@ | |||||||
|  | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd"> | ||||||
|  | <html> | ||||||
|  | <head> | ||||||
|  | $Common_meta()$ | ||||||
|  | <title> | ||||||
|  | Android API Differences Report | ||||||
|  | </title> | ||||||
|  | <body> | ||||||
|  | <div class="body"> | ||||||
|  |  | ||||||
|  | $Header()$ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | <div class="content"> | ||||||
|  | <h2>Android API Differences Report</h2> | ||||||
|  | <p>This document details the changes in the Android framework API. It shows  | ||||||
|  | additions, modifications, and removals for packages, classes, methods, and  | ||||||
|  | fields. Each reference to an API change includes a brief description of the  | ||||||
|  | API and an explanation of the change and suggested workaround, where available.</p> | ||||||
|  |  | ||||||
|  | <p>The differences described in this report are based a comparison of the APIs  | ||||||
|  | whose versions are specified in the upper-right corner of this page. It compares a  | ||||||
|  | newer "to" API to an older "from" version, noting any changes relative to the  | ||||||
|  | older API. So, for example, indicated API removals are no longer present in the "to"  | ||||||
|  | API.</p> | ||||||
|  | <p>For more information about the Android framework API and SDK,  | ||||||
|  | see the <a href="http://code.google.com/android/index.html" target="_top">Android product site</a>.</p> | ||||||
|  |  | ||||||
|  | $if(no_delta)$ | ||||||
|  | <h3>Congratulation!</h3> | ||||||
|  | No differences were detected between the two provided APIs. | ||||||
|  | $endif$ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | $if(removed_packages)$ | ||||||
|  | $Table(name="Removed Packages", rows=removed_packages:{$it.from:ModelElementRow()$})$ | ||||||
|  | <br/> | ||||||
|  | $endif$ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | $if(added_packages)$ | ||||||
|  | $Table(name="Added Packages", rows=added_packages:{$it.to:PackageAddedLink()$}:SimpleTableRow())$ | ||||||
|  | <br/> | ||||||
|  | $endif$ | ||||||
|  |  | ||||||
|  | $if(changed_packages)$ | ||||||
|  | $Table(name="Changed Packages", rows=changed_packages:{$it.to:PackageChangedLink()$}:SimpleTableRow())$ | ||||||
|  | <br/> | ||||||
|  | $endif$ | ||||||
|  | </div> | ||||||
|  |  | ||||||
|  |  | ||||||
|  | </div> | ||||||
|  | </body> | ||||||
|  | </html> | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
							
								
								
									
										31
									
								
								samples/HTML/pages.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								samples/HTML/pages.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | |||||||
|  | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | ||||||
|  | <html xmlns="http://www.w3.org/1999/xhtml"> | ||||||
|  | <head> | ||||||
|  | <meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> | ||||||
|  | <title>Related Pages</title> | ||||||
|  | <link href="qt.css" rel="stylesheet" type="text/css"/> | ||||||
|  | </head> | ||||||
|  | <body> | ||||||
|  | <div class=header> | ||||||
|  | <a class=headerLink  href="index.html">Main Page</a> · | ||||||
|  | <a class=headerLink  href="classoverview.html">Class Overview</a> · | ||||||
|  | <a class=headerLink  href="hierarchy.html">Hierarchy</a> · | ||||||
|  | <a class=headerLink  href="annotated.html">All Classes</a> | ||||||
|  | </div> | ||||||
|  | <!-- Generated by Doxygen 1.8.1.2 --> | ||||||
|  | </div><!-- top --> | ||||||
|  | <div class="header"> | ||||||
|  |   <div class="headertitle"> | ||||||
|  | <div class="title">Related Pages</div>  </div> | ||||||
|  | </div><!--header--> | ||||||
|  | <div class="contents"> | ||||||
|  | <div class="textblock">Here is a list of all related documentation pages:</div><div class="directory"> | ||||||
|  | <table class="directory"> | ||||||
|  | <tr id="row_0_" class="even"><td class="entry"><img src="ftv2node.png" alt="o" width="16" height="22" /><a class="el" href="classoverview.html" target="_self">Class Overview</a></td><td class="desc"></td></tr> | ||||||
|  | <tr id="row_1_"><td class="entry"><img src="ftv2lastnode.png" alt="\" width="16" height="22" /><a class="el" href="thelayoutsystem.html" target="_self">The Layout System</a></td><td class="desc"></td></tr> | ||||||
|  | </table> | ||||||
|  | </div><!-- directory --> | ||||||
|  | </div><!-- contents --> | ||||||
|  | <div class="footer" />Generated with <a href="http://www.doxygen.org/index.html">Doxygen</a> 1.8.1.2</div> | ||||||
|  | </body> | ||||||
|  | </html> | ||||||
							
								
								
									
										6
									
								
								samples/Haskell/Hello.hs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								samples/Haskell/Hello.hs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | |||||||
|  | import Data.Char | ||||||
|  |  | ||||||
|  | main :: IO () | ||||||
|  | main = do | ||||||
|  | 	let hello = "hello world" | ||||||
|  | 	putStrLn $ map toUpper hello | ||||||
							
								
								
									
										33
									
								
								samples/Haskell/Main.hs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								samples/Haskell/Main.hs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | |||||||
|  | module Main where | ||||||
|  |  | ||||||
|  | import Sudoku | ||||||
|  | import Data.Maybe | ||||||
|  |  | ||||||
|  |  | ||||||
|  | sudoku :: Sudoku | ||||||
|  | sudoku = [8, 0, 1, 3, 4, 0, 0, 0, 0, | ||||||
|  |           4, 3, 0, 8, 0, 0, 1, 0, 7, | ||||||
|  |           0, 0, 0, 0, 6, 0, 0, 0, 3, | ||||||
|  |           2, 0, 8, 0, 5, 0, 0, 0, 9, | ||||||
|  |           0, 0, 9, 0, 0, 0, 7, 0, 0, | ||||||
|  |           6, 0, 0, 0, 7, 0, 8, 0, 4, | ||||||
|  |           3, 0, 0, 0, 1, 0, 0, 0, 0, | ||||||
|  |           1, 0, 5, 0, 0, 6, 0, 4, 2, | ||||||
|  |           0, 0, 0, 0, 2, 4, 3, 0, 8] | ||||||
|  |  | ||||||
|  | {- | ||||||
|  | sudoku :: Sudoku | ||||||
|  | sudoku = [8, 6, 1, 3, 4, 7, 2, 9, 5, | ||||||
|  | 		  4, 3, 2, 8, 9, 5, 1, 6, 7, | ||||||
|  | 		  9, 5, 7, 1, 6, 2, 4, 8, 3, | ||||||
|  | 		  2, 7, 8, 4, 5, 1, 6, 3, 9, | ||||||
|  | 		  5, 4, 9, 6, 8, 3, 7, 2, 1, | ||||||
|  | 		  6, 1, 3, 2, 7, 9, 8, 5, 4, | ||||||
|  | 		  3, 2, 4, 9, 1, 8, 5, 7, 6, | ||||||
|  | 		  1, 8, 5, 7, 3, 6, 9, 4, 2, | ||||||
|  | 		  7, 9, 6, 5, 2, 4, 3, 1, 8] | ||||||
|  | -} | ||||||
|  | main :: IO () | ||||||
|  | main = do | ||||||
|  | 	putStrLn $ pPrint sudoku ++ "\n\n" | ||||||
|  | 	putStrLn $ pPrint $ fromMaybe [] $ solve sudoku | ||||||
							
								
								
									
										46
									
								
								samples/Haskell/Sudoku.hs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								samples/Haskell/Sudoku.hs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | |||||||
|  | module Sudoku | ||||||
|  | ( | ||||||
|  |   Sudoku, | ||||||
|  |   solve, | ||||||
|  |   isSolved, | ||||||
|  |   pPrint | ||||||
|  | ) where | ||||||
|  |  | ||||||
|  | import Data.Maybe | ||||||
|  | import Data.List | ||||||
|  | import Data.List.Split | ||||||
|  |  | ||||||
|  | type Sudoku = [Int] | ||||||
|  |  | ||||||
|  | solve :: Sudoku -> Maybe Sudoku | ||||||
|  | solve sudoku | ||||||
|  |   | isSolved sudoku = Just sudoku | ||||||
|  |   | otherwise = do | ||||||
|  |     index <- elemIndex 0 sudoku | ||||||
|  |     let sudokus = [nextTest sudoku index i | i <- [1..9], | ||||||
|  |                                   checkRow (nextTest sudoku index i) index, | ||||||
|  |                                   checkColumn (nextTest sudoku index i) index, | ||||||
|  |                                   checkBox (nextTest sudoku index i) index] | ||||||
|  |     listToMaybe $ mapMaybe solve sudokus | ||||||
|  |   where nextTest sudoku index i = take index sudoku ++ [i] ++ drop (index+1) sudoku | ||||||
|  |         checkRow sudoku index = (length $ getRow sudoku index) == (length $ nub $ getRow sudoku index) | ||||||
|  |         checkColumn sudoku index = (length $ getColumn sudoku index) == (length $ nub $ getColumn sudoku index) | ||||||
|  |         checkBox sudoku index = (length $ getBox sudoku index) == (length $ nub $ getBox sudoku index) | ||||||
|  |         getRow sudoku index = filter (/=0) $ (chunksOf 9 sudoku) !! (quot index 9) | ||||||
|  |         getColumn sudoku index = filter (/=0) $ (transpose $ chunksOf 9 sudoku) !! (mod index 9) | ||||||
|  |         getBox sudoku index = filter (/=0) $ (map concat $ concatMap transpose $ chunksOf 3 $ map (chunksOf 3) $ chunksOf 9 sudoku) | ||||||
|  |                                                                                 !! (3 * (quot index 27) + (quot (mod index 9) 3)) | ||||||
|  |  | ||||||
|  | isSolved :: Sudoku -> Bool | ||||||
|  | isSolved sudoku | ||||||
|  |   | product sudoku == 0 = False | ||||||
|  |   | map (length . nub) sudokuRows /= map length sudokuRows = False | ||||||
|  |   | map (length . nub) sudokuColumns /= map length sudokuColumns = False | ||||||
|  |   | map (length . nub) sudokuBoxes /= map length sudokuBoxes = False | ||||||
|  |   | otherwise = True | ||||||
|  |   where sudokuRows = chunksOf 9 sudoku | ||||||
|  |         sudokuColumns = transpose sudokuRows | ||||||
|  |         sudokuBoxes = map concat $ concatMap transpose $ chunksOf 3 $ map (chunksOf 3) $ chunksOf 9 sudoku | ||||||
|  |  | ||||||
|  | pPrint :: Sudoku -> String | ||||||
|  | pPrint sudoku = intercalate "\n" $ map (intercalate " " . map show) $ chunksOf 9 sudoku | ||||||
							
								
								
									
										46
									
								
								samples/Isabelle/HelloWorld.thy
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								samples/Isabelle/HelloWorld.thy
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | |||||||
|  | theory HelloWorld | ||||||
|  | imports Main | ||||||
|  | begin | ||||||
|  |  | ||||||
|  | section{*Playing around with Isabelle*} | ||||||
|  |  | ||||||
|  | text{* creating a lemma with the name hello_world*} | ||||||
|  | lemma hello_world: "True" by simp | ||||||
|  |  | ||||||
|  | (*inspecting it*) | ||||||
|  | thm hello_world | ||||||
|  |  | ||||||
|  | text{* defining a string constant HelloWorld *} | ||||||
|  |  | ||||||
|  | definition HelloWorld :: "string" where | ||||||
|  |   "HelloWorld \<equiv> ''Hello World!''" | ||||||
|  |  | ||||||
|  | (*reversing HelloWorld twice yilds HelloWorld again*) | ||||||
|  | theorem "rev (rev HelloWorld) = HelloWorld" | ||||||
|  |   by (fact List.rev_rev_ident) | ||||||
|  |  | ||||||
|  | text{*now we delete the already proven List.rev_rev_ident lema and show it by hand*} | ||||||
|  | declare List.rev_rev_ident[simp del] | ||||||
|  | hide_fact List.rev_rev_ident | ||||||
|  |  | ||||||
|  | (*It's trivial since we can just 'execute' it*) | ||||||
|  | corollary "rev (rev HelloWorld) = HelloWorld" | ||||||
|  |   apply(simp add: HelloWorld_def) | ||||||
|  |   done | ||||||
|  |  | ||||||
|  | text{*does it hold in general?*} | ||||||
|  | theorem rev_rev_ident:"rev (rev l) = l" | ||||||
|  |   proof(induction l) | ||||||
|  |   case Nil thus ?case by simp | ||||||
|  |   next | ||||||
|  |   case (Cons l ls) | ||||||
|  |     assume IH: "rev (rev ls) = ls" | ||||||
|  |     have "rev (l#ls) = (rev ls) @ [l]" by simp | ||||||
|  |     hence "rev (rev (l#ls)) = rev ((rev ls) @ [l])" by simp | ||||||
|  |     also have "\<dots> = [l] @ rev (rev ls)" by simp | ||||||
|  |     finally show "rev (rev (l#ls)) = l#ls" using IH by simp | ||||||
|  |   qed | ||||||
|  |  | ||||||
|  | corollary "\<forall>(l::string). rev (rev l) = l" by(fastforce intro: rev_rev_ident) | ||||||
|  |  | ||||||
|  | end | ||||||
							
								
								
									
										24
									
								
								samples/JavaScript/helloHanaEndpoint.xsjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								samples/JavaScript/helloHanaEndpoint.xsjs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | |||||||
|  | /* | ||||||
|  |  invoke endpoint by calling in a browser: | ||||||
|  |  http://<hanaserveradress>:<xsengineport(usually 8000)>/<path>/<to>/<endpoint>/helloHanaMath.xsjslib?x=4&y=2 | ||||||
|  |  e.g.: | ||||||
|  |  http://192.168.178.20:8000/geekflyer/linguist/helloHanaEndpoint.xsjs?x=4&y=2 | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | var hanaMath = $.import("./helloHanaMath.xsjslib"); | ||||||
|  |  | ||||||
|  | var x = parseFloat($.request.parameters.get("x")); | ||||||
|  | var y = parseFloat($.request.parameters.get("y")); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | var result = hanaMath.multiply(x, y); | ||||||
|  |  | ||||||
|  | var output = { | ||||||
|  |     title: "Hello HANA XS - do some simple math", | ||||||
|  |     input: {x: x, y: y}, | ||||||
|  |     result: result | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | $.response.contentType = "application/json"; | ||||||
|  | $.response.statusCode = $.net.http.OK; | ||||||
|  | $.response.setBody(JSON.stringify(output)); | ||||||
							
								
								
									
										9
									
								
								samples/JavaScript/helloHanaMath.xsjslib
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								samples/JavaScript/helloHanaMath.xsjslib
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | |||||||
|  | /* simple hana xs demo library, which can be used by multiple endpoints */ | ||||||
|  |  | ||||||
|  | function multiply(x, y) { | ||||||
|  |     return x * y; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function add(x, y) { | ||||||
|  |     return x + y; | ||||||
|  | } | ||||||
							
								
								
									
										7
									
								
								samples/JavaScript/intro.js.frag
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								samples/JavaScript/intro.js.frag
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | (function(window, angular) { | ||||||
|  |  | ||||||
|  | Array.prototype.last = function() { | ||||||
|  |     return this[this.length-1]; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | var app = angular.module('ConwayGameOfLife', []); | ||||||
							
								
								
									
										3
									
								
								samples/JavaScript/outro.js.frag
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								samples/JavaScript/outro.js.frag
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  |  | ||||||
|  | })(window, window.angular); | ||||||
|  |  | ||||||
							
								
								
									
										104
									
								
								samples/Liquid/layout.liquid
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								samples/Liquid/layout.liquid
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,104 @@ | |||||||
|  | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | ||||||
|  |   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | ||||||
|  |  | ||||||
|  | <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> | ||||||
|  | <head> | ||||||
|  |   <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> | ||||||
|  |   <title>{{shop.name}} - {{page_title}}</title> | ||||||
|  |  | ||||||
|  |   {{ 'textile.css'  | global_asset_url | stylesheet_tag }} | ||||||
|  |   {{ 'lightbox/v204/lightbox.css' | global_asset_url | stylesheet_tag }} | ||||||
|  |  | ||||||
|  |   {{ 'prototype/1.6/prototype.js' | global_asset_url  | script_tag }} | ||||||
|  |   {{ 'scriptaculous/1.8.2/scriptaculous.js' | global_asset_url  | script_tag }} | ||||||
|  |   {{ 'lightbox/v204/lightbox.js'  | global_asset_url  | script_tag }} | ||||||
|  |   {{ 'option_selection.js'        | shopify_asset_url | script_tag }} | ||||||
|  |  | ||||||
|  |   {{ 'layout.css'   | asset_url | stylesheet_tag }} | ||||||
|  |   {{ 'shop.js'      | asset_url | script_tag }} | ||||||
|  |  | ||||||
|  |   {{ content_for_header }} | ||||||
|  | </head> | ||||||
|  |  | ||||||
|  | <body id="page-{{template}}"> | ||||||
|  |  | ||||||
|  |   <p class="hide"><a href="#rightsiders">Skip to navigation.</a></p> | ||||||
|  |     <!-- mini cart --> | ||||||
|  |         {% if cart.item_count > 0 %} | ||||||
|  |       <div id="minicart" style="display:none;"><div id="minicart-inner"> | ||||||
|  |       <div id="minicart-items"> | ||||||
|  |       <h2>There {{ cart.item_count | pluralize: 'is', 'are' }} {{ cart.item_count }} {{ cart.item_count | pluralize: 'item', 'items' }} in <a href="/cart" title="View your cart">your cart</a>!</h2><h4 style="font-size: 16px; margin: 0 0 10px 0; padding: 0;">Your subtotal is {{ cart.total_price | money }}.</h4> | ||||||
|  |         {% for item in cart.items %} | ||||||
|  |         <div class="thumb"> | ||||||
|  |           <div class="prodimage"><a href="{{item.product.url}}" onMouseover="tooltip('{{ item.quantity }} x {{ item.title }} ({{ item.variant.title }})', 200)"; onMouseout="hidetooltip()"><img src="{{ item.product.featured_image | product_img_url: 'thumb' }}" /></a></div> | ||||||
|  |         </div> | ||||||
|  |         {% endfor %} | ||||||
|  |         </div> | ||||||
|  |        <br style="clear:both;" /> | ||||||
|  |       </div></div> | ||||||
|  |         {% endif %} | ||||||
|  |  | ||||||
|  |   <div id="container"> | ||||||
|  |     <div id="header"> | ||||||
|  |       <!-- Begin Header --> | ||||||
|  |         <h1 id="logo"><a href="/" title="Go Home">{{shop.name}}</a></h1> | ||||||
|  |       <div id="cartlinks"> | ||||||
|  |         {% if cart.item_count > 0 %} | ||||||
|  |           <h2 id="cartcount"><a href="/cart" onMouseover="tooltip('There {{ cart.item_count | pluralize: 'is', 'are' }} {{ cart.item_count }} {{ cart.item_count | pluralize: 'item', 'items' }} in your cart!', 200)"; onMouseout="hidetooltip()">{{ cart.item_count }} {{ cart.item_count | pluralize: 'thing', 'things' }}!</a></h2> | ||||||
|  |       <a href="/cart" id="minicartswitch" onclick="superSwitch(this, 'minicart', 'Close Mini Cart'); return false;" id="cartswitch">View Mini Cart ({{ cart.total_price | money }})</a> | ||||||
|  |         {% endif %} | ||||||
|  |       </div> | ||||||
|  |       <!-- End Header --> | ||||||
|  |  | ||||||
|  |     </div> | ||||||
|  |   <hr /> | ||||||
|  | <div id="main"> | ||||||
|  |  | ||||||
|  |     <div id="content"> | ||||||
|  |     <div id="innercontent"> | ||||||
|  |       {{ content_for_layout }} | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |  | ||||||
|  |   <hr /> | ||||||
|  |     <div id="rightsiders"> | ||||||
|  |  | ||||||
|  |       <ul class="rightlinks"> | ||||||
|  |         {% for link in linklists.main-menu.links %} | ||||||
|  |            <li>{{ link.title | link_to: link.url }}</li> | ||||||
|  |         {% endfor %} | ||||||
|  |       </ul> | ||||||
|  |  | ||||||
|  |         {% if tags %} | ||||||
|  |         <ul class="rightlinks"> | ||||||
|  |           {% for tag in collection.tags %} | ||||||
|  |             <li><span class="add-link">{{ '+' | link_to_add_tag: tag }}</span>{{ tag | highlight_active_tag | link_to_tag: tag }}</li> | ||||||
|  |           {% endfor %} | ||||||
|  |         </ul> | ||||||
|  |         {% endif %} | ||||||
|  |  | ||||||
|  |       <ul class="rightlinks"> | ||||||
|  |         {% for link in linklists.footer.links %} | ||||||
|  |            <li>{{ link.title | link_to: link.url }}</li> | ||||||
|  |         {% endfor %} | ||||||
|  |       </ul> | ||||||
|  |  | ||||||
|  |     </div> | ||||||
|  |  | ||||||
|  |   <hr /><br style="clear:both;" /> | ||||||
|  |  | ||||||
|  |     <div id="footer"> | ||||||
|  |       <div class="footerinner"> | ||||||
|  |       All prices are in {{ shop.currency }}. | ||||||
|  |       Powered by <a href="http://www.shopify.com" title="Shopify, Hosted E-Commerce">Shopify</a>. | ||||||
|  |     </div> | ||||||
|  |     </div> | ||||||
|  |  | ||||||
|  |   </div> | ||||||
|  | </div> | ||||||
|  |  | ||||||
|  | <div id="tooltip"></div> | ||||||
|  | <img id="pointer" src="{{ 'arrow2.gif' | asset_url }}" /> | ||||||
|  |  | ||||||
|  | </body> | ||||||
|  | </html> | ||||||
							
								
								
									
										70
									
								
								samples/Liquid/template.liquid
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								samples/Liquid/template.liquid
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,70 @@ | |||||||
|  | <h3>We have wonderful products!</h3> | ||||||
|  | <ul id="products"> | ||||||
|  |   <div id="productpage"> | ||||||
|  |     <div id="productimages"><div id="productimages-top"><div id="productimages-bottom"> | ||||||
|  |       {% for image in product.images %} | ||||||
|  |         {% if forloop.first %} | ||||||
|  |           <a href="{{ image | product_img_url: 'large' }}" class="productimage" rel="lightbox"> | ||||||
|  |             <img src="{{ image | product_img_url: 'medium'}}" alt="{{product.title | escape }}" /> | ||||||
|  |           </a> | ||||||
|  |         {% else %} | ||||||
|  |           <a href="{{ image | product_img_url: 'large' }}" class="productimage-small" rel="lightbox"> | ||||||
|  |             <img src="{{ image | product_img_url: 'small'}}" alt="{{product.title | escape }}" /> | ||||||
|  |           </a> | ||||||
|  |         {% endif %} | ||||||
|  |       {% endfor %} | ||||||
|  |     </div></div></div> | ||||||
|  |  | ||||||
|  |     <h2>{{ product.title }}</h2> | ||||||
|  |  | ||||||
|  |     <ul id="details" class="hlist"> | ||||||
|  |       <li>Vendor: {{ product.vendor | link_to_vendor }}</li> | ||||||
|  |       <li>Type: {{ product.type | link_to_type }}</li> | ||||||
|  |     </ul> | ||||||
|  |  | ||||||
|  |     <small>{{ product.price_min | money }}{% if product.price_varies %} - {{ product.price_max | money }}{% endif %}</small> | ||||||
|  |  | ||||||
|  |     <div id="variant-add"> | ||||||
|  |       <form action="/cart/add" method="post"> | ||||||
|  |  | ||||||
|  |         <select id="variant-select" name="id" class="product-info-options"> | ||||||
|  |           {% for variant in product.variants %} | ||||||
|  |             <option value="{{ variant.id }}">{{ variant.title }} - {{ variant.price | money }}</option> | ||||||
|  |           {% endfor %} | ||||||
|  |         </select> | ||||||
|  |  | ||||||
|  |         <div id="price-field" class="price"></div> | ||||||
|  |  | ||||||
|  |       <div style="text-align:center;"><input type="image" name="add" value="Add to Cart" id="add" src="{{ 'addtocart.gif' | asset_url }}" /></div> | ||||||
|  |       </form> | ||||||
|  |     </div> | ||||||
|  |  | ||||||
|  |     <div class="description textile"> | ||||||
|  |       {{ product.description }} | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  |  | ||||||
|  |   <script type="text/javascript"> | ||||||
|  |   <!-- | ||||||
|  |     // prototype callback for multi variants dropdown selector | ||||||
|  |     var selectCallback = function(variant, selector) { | ||||||
|  |       if (variant && variant.available == true) { | ||||||
|  |         // selected a valid variant | ||||||
|  |         $('add').removeClassName('disabled'); // remove unavailable class from add-to-cart button | ||||||
|  |         $('add').disabled = false;           // reenable add-to-cart button | ||||||
|  |         $('price-field').innerHTML = Shopify.formatMoney(variant.price, "{{shop.money_with_currency_format}}");  // update price field | ||||||
|  |       } else { | ||||||
|  |         // variant doesn't exist | ||||||
|  |         $('add').addClassName('disabled');      // set add-to-cart button to unavailable class | ||||||
|  |         $('add').disabled = true;              // disable add-to-cart button | ||||||
|  |         $('price-field').innerHTML = (variant) ? "Sold Out" : "Unavailable"; // update price-field message | ||||||
|  |       } | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     // initialize multi selector for product | ||||||
|  |     Event.observe(document, 'dom:loaded', function() { | ||||||
|  |       new Shopify.OptionSelectors("variant-select", { product: {{ product | json }}, onVariantSelected: selectCallback }); | ||||||
|  |     }); | ||||||
|  |   --> | ||||||
|  |   </script> | ||||||
|  | </ul> | ||||||
							
								
								
									
										232
									
								
								samples/Mathematica/MiscCalculations.nb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										232
									
								
								samples/Mathematica/MiscCalculations.nb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,232 @@ | |||||||
|  | (* Content-type: application/vnd.wolfram.mathematica *) | ||||||
|  |  | ||||||
|  | (*** Wolfram Notebook File ***) | ||||||
|  | (* http://www.wolfram.com/nb *) | ||||||
|  |  | ||||||
|  | (* CreatedBy='Mathematica 9.0' *) | ||||||
|  |  | ||||||
|  | (*CacheID: 234*) | ||||||
|  | (* Internal cache information: | ||||||
|  | NotebookFileLineBreakTest | ||||||
|  | NotebookFileLineBreakTest | ||||||
|  | NotebookDataPosition[       157,          7] | ||||||
|  | NotebookDataLength[      7164,        223] | ||||||
|  | NotebookOptionsPosition[      6163,        182] | ||||||
|  | NotebookOutlinePosition[      6508,        197] | ||||||
|  | CellTagsIndexPosition[      6465,        194] | ||||||
|  | WindowFrame->Normal*) | ||||||
|  |  | ||||||
|  | (* Beginning of Notebook Content *) | ||||||
|  | Notebook[{ | ||||||
|  |  | ||||||
|  | Cell[CellGroupData[{ | ||||||
|  | Cell[BoxData[ | ||||||
|  |  RowBox[{ | ||||||
|  |   RowBox[{"Solve", "[",  | ||||||
|  |    RowBox[{ | ||||||
|  |     RowBox[{"y", "'"}], "\[Equal]", " ", "xy"}], "]"}],  | ||||||
|  |   "\[IndentingNewLine]"}]], "Input", | ||||||
|  |  CellChangeTimes->{{3.6112716342092056`*^9, 3.6112716549793935`*^9}}], | ||||||
|  |  | ||||||
|  | Cell[BoxData[ | ||||||
|  |  RowBox[{"{",  | ||||||
|  |   RowBox[{"{",  | ||||||
|  |    RowBox[{"xy", "\[Rule]",  | ||||||
|  |     SuperscriptBox["y", "\[Prime]", | ||||||
|  |      MultilineFunction->None]}], "}"}], "}"}]], "Output", | ||||||
|  |  CellChangeTimes->{3.6112716579295626`*^9}] | ||||||
|  | }, Open  ]], | ||||||
|  |  | ||||||
|  | Cell[CellGroupData[{ | ||||||
|  |  | ||||||
|  | Cell[BoxData[ | ||||||
|  |  RowBox[{"Log", "[",  | ||||||
|  |   RowBox[{"Sin", "[", "38", "]"}], "]"}]], "Input", | ||||||
|  |  CellChangeTimes->{{3.611271663920905*^9, 3.6112716759275913`*^9}}], | ||||||
|  |  | ||||||
|  | Cell[BoxData[ | ||||||
|  |  RowBox[{"Log", "[",  | ||||||
|  |   RowBox[{"Sin", "[", "38", "]"}], "]"}]], "Output", | ||||||
|  |  CellChangeTimes->{3.611271678256725*^9}] | ||||||
|  | }, Open  ]], | ||||||
|  |  | ||||||
|  | Cell[CellGroupData[{ | ||||||
|  |  | ||||||
|  | Cell[BoxData[ | ||||||
|  |  RowBox[{"N", "[",  | ||||||
|  |   RowBox[{"Log", "[",  | ||||||
|  |    RowBox[{"Sin", "[", "38", "]"}], "]"}], "]"}]], "Input", | ||||||
|  |  NumberMarks->False], | ||||||
|  |  | ||||||
|  | Cell[BoxData[ | ||||||
|  |  RowBox[{"-", "1.2161514009320473`"}]], "Output", | ||||||
|  |  CellChangeTimes->{3.611271682061942*^9}] | ||||||
|  | }, Open  ]], | ||||||
|  |  | ||||||
|  | Cell[CellGroupData[{ | ||||||
|  |  | ||||||
|  | Cell[BoxData[ | ||||||
|  |  RowBox[{"Abs", "[",  | ||||||
|  |   RowBox[{"-", "1.2161514009320473`"}], "]"}]], "Input", | ||||||
|  |  NumberMarks->False], | ||||||
|  |  | ||||||
|  | Cell[BoxData["1.2161514009320473`"], "Output", | ||||||
|  |  CellChangeTimes->{3.6112716842780695`*^9}] | ||||||
|  | }, Open  ]], | ||||||
|  |  | ||||||
|  | Cell[CellGroupData[{ | ||||||
|  |  | ||||||
|  | Cell[BoxData[ | ||||||
|  |  RowBox[{"RealDigits", "[", "1.2161514009320473`", "]"}]], "Input", | ||||||
|  |  NumberMarks->False], | ||||||
|  |  | ||||||
|  | Cell[BoxData[ | ||||||
|  |  RowBox[{"{",  | ||||||
|  |   RowBox[{ | ||||||
|  |    RowBox[{"{",  | ||||||
|  |     RowBox[{ | ||||||
|  |     "1", ",", "2", ",", "1", ",", "6", ",", "1", ",", "5", ",", "1", ",", "4", | ||||||
|  |       ",", "0", ",", "0", ",", "9", ",", "3", ",", "2", ",", "0", ",", "4",  | ||||||
|  |      ",", "7"}], "}"}], ",", "1"}], "}"}]], "Output", | ||||||
|  |  CellChangeTimes->{3.611271685319129*^9}] | ||||||
|  | }, Open  ]], | ||||||
|  |  | ||||||
|  | Cell[CellGroupData[{ | ||||||
|  |  | ||||||
|  | Cell[BoxData[ | ||||||
|  |  RowBox[{ | ||||||
|  |   RowBox[{"Graph", "[",  | ||||||
|  |    RowBox[{"Log", "[", "x", "]"}], "]"}], "\[IndentingNewLine]"}]], "Input", | ||||||
|  |  CellChangeTimes->{{3.611271689258354*^9, 3.611271702038085*^9}}], | ||||||
|  |  | ||||||
|  | Cell[BoxData[ | ||||||
|  |  RowBox[{"Graph", "[",  | ||||||
|  |   RowBox[{"Log", "[", "x", "]"}], "]"}]], "Output", | ||||||
|  |  CellChangeTimes->{3.611271704295214*^9}] | ||||||
|  | }, Open  ]], | ||||||
|  |  | ||||||
|  | Cell[BoxData[""], "Input", | ||||||
|  |  CellChangeTimes->{{3.611271712769699*^9, 3.6112717423153887`*^9}}], | ||||||
|  |  | ||||||
|  | Cell[CellGroupData[{ | ||||||
|  |  | ||||||
|  | Cell[BoxData[ | ||||||
|  |  RowBox[{ | ||||||
|  |   RowBox[{"Plot", "[",  | ||||||
|  |    RowBox[{ | ||||||
|  |     RowBox[{"Log", "[", "x", "]"}], ",", " ",  | ||||||
|  |     RowBox[{"{",  | ||||||
|  |      RowBox[{"x", ",", " ", "0", ",", " ", "10"}], "}"}]}], "]"}],  | ||||||
|  |   "\[IndentingNewLine]"}]], "Input", | ||||||
|  |  CellChangeTimes->{{3.6112717573482485`*^9, 3.6112717747822456`*^9}}], | ||||||
|  |  | ||||||
|  | Cell[BoxData[ | ||||||
|  |  GraphicsBox[{{}, {},  | ||||||
|  |    {Hue[0.67, 0.6, 0.6], LineBox[CompressedData[" | ||||||
|  | 1:eJwVzXs81Pkex/GZH7XlsutSQprwqxTSZVfJGp9P6UYqlyxHUhTaLrq4JpVK | ||||||
|  | 0SHRisGWjYiEbHSvb+Q27rllmYwaY6JpwxgZTI7zx/vxejz/eht4H3PyoRgM | ||||||
|  | Rsj0/t+1MEPjP1Zc8O6L0tCYkJERTokxP5YLLR+MQy2qZWSzX62gWcaFn9s7 | ||||||
|  | 5sVFyohY4ZvLs5Ya6AheLQxnyIgFe4fllag6yH4zayhMcYw0FU5SRl8bweS/ | ||||||
|  | wyVFa0aJBsz2VDVrAl8V299DGKPk1yWJllEHmqD42vuI4RopiRvJlYS9bYLZ | ||||||
|  | a2c4j3pJyS8JbT7eeW/By6ht44vkEXKuxtRu1d4WOB5QmStjSUhO0eMleTda | ||||||
|  | 4EZtHmU5PEyaORsUFte1QFHRg6WjFcNkkZ/bC+11rVC0s8n9nf8wqVGINGNo | ||||||
|  | tkFRzD3HsYohosXu0misbAdxXml1VdQgKSi80nXErBNo/oP47aliMqAxEGvn | ||||||
|  | 1QlVgoRvezzExCjYznppYifkn+K6CVli8peV8m2BrBNM20LljlmfyXVurK97 | ||||||
|  | RRfcVCpPCXg8QIIF14a2eLyHn6Y4909//UTSlWsvqm/qge1fVjduzhISa/Zp | ||||||
|  | jwjPHvCM6ZD7BQgJz9/E/GtIDyRsSj3Svl5ItJtj+uru9cBdE2PXZH4vSeDY | ||||||
|  | 20arfYAT6Z3e8axecnFxw49TXR/gU5X5vDu5H4kfvE0RnxSAsqvDMcduPmFk | ||||||
|  | jD7rihGA7RmZ5qlYPuEo6vFq7gigR67QPetXPqnm+rJy2wUA0hVVHindZOmu | ||||||
|  | yQwfy17Y4OU185n7e/LpoNH9bqYQPPrPvwn+2kkOXT/zqim+DzJ72WEzdrcT | ||||||
|  | SprBJ7l9UD/Fag2c005SXasZhWV9kH51Z/aqhjZSo6dpc3WkD4L1tqolbGgj | ||||||
|  | JndzqmzdRPD67PLxVrNWIn7e0lS28BMs6Ba9FM1pJv7CZYLign6IeWFYmrqk | ||||||
|  | jvR4/jOrlNsPoqNsieZftcS5I9qsvrcf8tnmIzq6tcSiVnRKqDsALqbKTVU/ | ||||||
|  | 1RCFoiw1ragBULG3LYphVhNOuIF1yN7PkFMpYVXI35BSTZ2UdWpfgMls07e/ | ||||||
|  | 84QoGUQa8S0GgVn/55MIdixUWyWsOLtpEAIiTazYlglw2e3W2gVOg5BMOVFO | ||||||
|  | zolAxT/ZsvvwIJAvj7SczqbC+Hex37ubgxD8udJ0tkcmfOa55DRSQ8DwsFzc | ||||||
|  | 6lkIdRyjZa/rhsAywLBSze45xKnVGt/eJwFLB1UN7sVq8O7aRRTqRsFbq7Mr | ||||||
|  | JqcdTlREeh8zGoeOsKZ1bgF8KDqu4qxtK4c/T0q26boJ4PbpwwMrXRn4N9vd | ||||||
|  | qamzDy6kTzqOiJmo6OOuteZtPzBaevBFmALy6nNqfwkTw5JA39BdxjPwSH3B | ||||||
|  | vlWGX6FXmvyb8suZeCtkhRV5NAh2wkNnrp+YhaOXrkQMdg/Bjt54ExZLCdti | ||||||
|  | v+y2+XcYBt54R1TnKyOH4R+txpOAmXr7Apu9quiaByGbG0dACaRePMmPmLmw | ||||||
|  | vX84Swpbvrh/M3RRQziRFnP5wih0lB1gupuqY0FCbZyewzcoiS731JeqY4Zj | ||||||
|  | 3+qZP4yB74ygnoYGDcz5GOJ8uXwM9p88XaKSqonn9R26+EdlsMLPpMHeaw4K | ||||||
|  | rc1neaqOQ6OGqXLQurmYKexKyno4Ds8LLqSZKmhhhvxW6cjWCTjNNHaoe6+F | ||||||
|  | pidKHHi9E6DEC9vqXzwPGaH7eO6hkyDMNkhMD9fGsUD+Knv5JCQu1VF86qKD | ||||||
|  | h3vll15HyyE+1bfKS18XbTje/KqZ38E9cU+DikgXNYxUk++f/Q5jG7Nk6a/m | ||||||
|  | 49yHih6fJ7+DQLghtCxKD9We/pFtf2wKMtir5td7LcDHFdUyrmgK8i8Fqfst | ||||||
|  | Z2H5rdC2ZGMGRrns36YgZWHfc/sj7Z4MNOfdzo2qX4jaWiITpSQGcpal5ddv | ||||||
|  | 08c4nrYPVjPw3OurnG1P9ZGdfship5yB2+e7ZNUsMsAzD/MLtFcycb1/1W71 | ||||||
|  | Kwb4qn7LsIcnE9P1vBfVSQ1QUbd5z75rTFz05m7Sjt2GeHJ9UIrOCybGLy8z | ||||||
|  | bn5liLETFcsURUz0lSi+5RrTGL/GlX1jDoXeRcP6V67R6DRvQNHcmsIjF5wn | ||||||
|  | 7RJoPPVD0ph42kHOxe9U/qDR/97LrjtAYbQ0KC4+iUa6N+b4nPUUFqyTTSTf | ||||||
|  | pDFTFtw6bEOhrHSqPTuPRo1786Pv21IY36xytbyKxo0v5z7UdKEwNfPowctc | ||||||
|  | GuUeojTutDMDG2y21tIYpHQ98NxvFD7Sih+vbaBRfeZZ6YArhTx3zYMtbTRC | ||||||
|  | CmNNqTuFRgIdm48CGveGmxUf2kfhyuIw1h0hjasPiNIWelFoealL5iOiMZKf | ||||||
|  | HdA6bXujmw/6B2gk7zZK2PspPHlYnzU0RGN40raf1XwpDLc6L/tbMv0vikor | ||||||
|  | n/Yl1Y+tgVIayzZ/kIT6UcgpzIwZG6Px0d7RwA8HKcyIUPR7Nk7j8sLHN2/8 | ||||||
|  | TmGeo8+G8Ekab1ncfmR7iMJiw8oF1t9pnF9RQuTTfiVZIpuaonFCb+xJ0WEK | ||||||
|  | /wc13qzo | ||||||
|  |      "]]}}, | ||||||
|  |   AspectRatio->NCache[GoldenRatio^(-1), 0.6180339887498948], | ||||||
|  |   Axes->True, | ||||||
|  |   AxesLabel->{None, None}, | ||||||
|  |   AxesOrigin->{0, 0}, | ||||||
|  |   Method->{}, | ||||||
|  |   PlotRange->{{0, 10}, {-1.623796532045525, 2.3025850725858823`}}, | ||||||
|  |   PlotRangeClipping->True, | ||||||
|  |   PlotRangePadding->{ | ||||||
|  |     Scaled[0.02],  | ||||||
|  |     Scaled[0.02]}]], "Output", | ||||||
|  |  CellChangeTimes->{3.6112717778594217`*^9}] | ||||||
|  | }, Open  ]] | ||||||
|  | }, | ||||||
|  | WindowSize->{716, 833}, | ||||||
|  | WindowMargins->{{Automatic, 214}, {Automatic, 26}}, | ||||||
|  | FrontEndVersion->"9.0 for Microsoft Windows (64-bit) (January 25, 2013)", | ||||||
|  | StyleDefinitions->"Default.nb" | ||||||
|  | ] | ||||||
|  | (* End of Notebook Content *) | ||||||
|  |  | ||||||
|  | (* Internal cache information *) | ||||||
|  | (*CellTagsOutline | ||||||
|  | CellTagsIndex->{} | ||||||
|  | *) | ||||||
|  | (*CellTagsIndex | ||||||
|  | CellTagsIndex->{} | ||||||
|  | *) | ||||||
|  | (*NotebookFileOutline | ||||||
|  | Notebook[{ | ||||||
|  | Cell[CellGroupData[{ | ||||||
|  | Cell[579, 22, 224, 6, 52, "Input"], | ||||||
|  | Cell[806, 30, 211, 6, 31, "Output"] | ||||||
|  | }, Open  ]], | ||||||
|  | Cell[CellGroupData[{ | ||||||
|  | Cell[1054, 41, 155, 3, 31, "Input"], | ||||||
|  | Cell[1212, 46, 130, 3, 31, "Output"] | ||||||
|  | }, Open  ]], | ||||||
|  | Cell[CellGroupData[{ | ||||||
|  | Cell[1379, 54, 137, 4, 31, "Input"], | ||||||
|  | Cell[1519, 60, 105, 2, 31, "Output"] | ||||||
|  | }, Open  ]], | ||||||
|  | Cell[CellGroupData[{ | ||||||
|  | Cell[1661, 67, 113, 3, 31, "Input"], | ||||||
|  | Cell[1777, 72, 90, 1, 31, "Output"] | ||||||
|  | }, Open  ]], | ||||||
|  | Cell[CellGroupData[{ | ||||||
|  | Cell[1904, 78, 102, 2, 31, "Input"], | ||||||
|  | Cell[2009, 82, 321, 8, 31, "Output"] | ||||||
|  | }, Open  ]], | ||||||
|  | Cell[CellGroupData[{ | ||||||
|  | Cell[2367, 95, 191, 4, 52, "Input"], | ||||||
|  | Cell[2561, 101, 131, 3, 31, "Output"] | ||||||
|  | }, Open  ]], | ||||||
|  | Cell[2707, 107, 94, 1, 31, "Input"], | ||||||
|  | Cell[CellGroupData[{ | ||||||
|  | Cell[2826, 112, 299, 8, 52, "Input"], | ||||||
|  | Cell[3128, 122, 3019, 57, 265, "Output"] | ||||||
|  | }, Open  ]] | ||||||
|  | } | ||||||
|  | ] | ||||||
|  | *) | ||||||
|  |  | ||||||
|  | (* End of internal cache information *) | ||||||
							
								
								
									
										3666
									
								
								samples/Mathematica/MiscCalculations2.nb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3666
									
								
								samples/Mathematica/MiscCalculations2.nb
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										8
									
								
								samples/Mathematica/Problem12.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								samples/Mathematica/Problem12.m
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  | (* ::Package:: *) | ||||||
|  |  | ||||||
|  | (* Problem12.m *) | ||||||
|  | (* Author: William Woodruff *) | ||||||
|  | (* Problem: What is the value of the first triangle number to have over five hundred divisors? *) | ||||||
|  |  | ||||||
|  | Do[If[Length[Divisors[Binomial[i + 1, 2]]] > 500,  | ||||||
|  |   Print[Binomial[i + 1, 2]]; Break[]], {i, 1000000}] | ||||||
							
								
								
									
										272
									
								
								samples/Nit/calculator.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										272
									
								
								samples/Nit/calculator.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,272 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # Copyright 2013 Alexis Laferrière <alexis.laf@xymus.net> | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | import gtk | ||||||
|  |  | ||||||
|  | class CalculatorContext | ||||||
|  | 	var result : nullable Float = null | ||||||
|  |  | ||||||
|  | 	var last_op : nullable Char = null | ||||||
|  |  | ||||||
|  | 	var current : nullable Float = null | ||||||
|  | 	var after_point : nullable Int = null | ||||||
|  |  | ||||||
|  | 	fun push_op( op : Char ) | ||||||
|  | 	do | ||||||
|  | 		apply_last_op_if_any | ||||||
|  | 		if op == 'C' then | ||||||
|  | 			self.result = 0.0 | ||||||
|  | 			last_op = null | ||||||
|  | 		else | ||||||
|  | 			last_op = op # store for next push_op | ||||||
|  | 		end | ||||||
|  |  | ||||||
|  | 		# prepare next current | ||||||
|  | 		after_point = null | ||||||
|  | 		current = null | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	fun push_digit( digit : Int ) | ||||||
|  | 	do | ||||||
|  | 		var current = current | ||||||
|  | 		if current == null then current = 0.0 | ||||||
|  |  | ||||||
|  | 		var after_point = after_point | ||||||
|  | 		if after_point == null then | ||||||
|  | 			current = current * 10.0 + digit.to_f | ||||||
|  | 		else | ||||||
|  | 			current = current + digit.to_f * 10.0.pow(after_point.to_f) | ||||||
|  | 			self.after_point -= 1 | ||||||
|  | 		end | ||||||
|  |  | ||||||
|  | 		self.current = current | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	fun switch_to_decimals | ||||||
|  | 	do | ||||||
|  | 		if self.current == null then current = 0.0 | ||||||
|  | 		if after_point != null then return | ||||||
|  |  | ||||||
|  | 		after_point = -1 | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	fun apply_last_op_if_any | ||||||
|  | 	do | ||||||
|  | 		var op = last_op | ||||||
|  |  | ||||||
|  | 		var result = result | ||||||
|  | 		if result == null then result = 0.0 | ||||||
|  |  | ||||||
|  | 		var current = current | ||||||
|  | 		if current == null then current = 0.0 | ||||||
|  |  | ||||||
|  | 		if op == null then | ||||||
|  | 			result = current | ||||||
|  | 		else if op == '+' then | ||||||
|  | 			result = result + current | ||||||
|  | 		else if op == '-' then | ||||||
|  | 			result = result - current | ||||||
|  | 		else if op == '/' then | ||||||
|  | 			result = result / current | ||||||
|  | 		else if op == '*' then | ||||||
|  | 			result = result * current | ||||||
|  | 		end | ||||||
|  | 		self.result = result | ||||||
|  | 		self.current = null | ||||||
|  | 	end | ||||||
|  | end | ||||||
|  |  | ||||||
|  | class CalculatorGui | ||||||
|  | 	super GtkCallable | ||||||
|  |  | ||||||
|  | 	var win : GtkWindow | ||||||
|  | 	var container : GtkGrid | ||||||
|  |  | ||||||
|  | 	var lbl_disp : GtkLabel | ||||||
|  | 	var but_eq : GtkButton | ||||||
|  | 	var but_dot : GtkButton | ||||||
|  |  | ||||||
|  | 	var context = new CalculatorContext | ||||||
|  |  | ||||||
|  | 	redef fun signal( sender, user_data ) | ||||||
|  | 	do | ||||||
|  | 		var after_point = context.after_point | ||||||
|  | 		if after_point == null then  | ||||||
|  | 		    after_point = 0 | ||||||
|  | 		else | ||||||
|  | 		    after_point = (after_point.abs) | ||||||
|  | 		end | ||||||
|  | 		 | ||||||
|  | 		if user_data isa Char then # is an operation | ||||||
|  | 			var c = user_data | ||||||
|  | 			if c == '.' then | ||||||
|  | 				but_dot.sensitive= false | ||||||
|  | 				context.switch_to_decimals | ||||||
|  | 				lbl_disp.text = "{context.current.to_i}." | ||||||
|  | 			else | ||||||
|  | 				but_dot.sensitive= true | ||||||
|  | 				context.push_op( c ) | ||||||
|  | 				 | ||||||
|  | 				var s = context.result.to_precision_native(6) | ||||||
|  | 				var index : nullable Int = null | ||||||
|  | 				for i in s.length.times do | ||||||
|  | 				    var chiffre = s.chars[i] | ||||||
|  | 				    if chiffre == '0' and index == null then | ||||||
|  | 					index = i | ||||||
|  | 				    else if chiffre != '0' then | ||||||
|  | 					index = null | ||||||
|  | 				    end | ||||||
|  | 				end | ||||||
|  | 				if index != null then | ||||||
|  | 					s = s.substring(0, index) | ||||||
|  | 					if s.chars[s.length-1] == ',' then s = s.substring(0, s.length-1) | ||||||
|  | 				end | ||||||
|  | 				lbl_disp.text = s | ||||||
|  | 			end | ||||||
|  | 		else if user_data isa Int then # is a number | ||||||
|  | 			var n = user_data | ||||||
|  | 			context.push_digit( n ) | ||||||
|  | 			lbl_disp.text = context.current.to_precision_native(after_point) | ||||||
|  | 		end | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	init | ||||||
|  | 	do | ||||||
|  | 		init_gtk | ||||||
|  |  | ||||||
|  | 		win = new GtkWindow( 0 ) | ||||||
|  |  | ||||||
|  | 		container = new GtkGrid(5,5,true) | ||||||
|  | 		win.add( container ) | ||||||
|  |  | ||||||
|  | 		lbl_disp = new GtkLabel( "_" ) | ||||||
|  | 		container.attach( lbl_disp, 0, 0, 5, 1 ) | ||||||
|  |  | ||||||
|  | 		# digits | ||||||
|  | 		for n in [0..9] do | ||||||
|  | 			var but = new GtkButton.with_label( n.to_s ) | ||||||
|  | 			but.request_size( 64, 64 ) | ||||||
|  | 			but.signal_connect( "clicked", self, n ) | ||||||
|  | 			if n == 0 then | ||||||
|  | 				container.attach( but, 0, 4, 1, 1 ) | ||||||
|  | 			else container.attach( but, (n-1)%3, 3-(n-1)/3, 1, 1 ) | ||||||
|  | 		end | ||||||
|  |  | ||||||
|  | 		# operators | ||||||
|  | 		var r = 1 | ||||||
|  | 		for op in ['+', '-', '*', '/' ] do | ||||||
|  | 			var but = new GtkButton.with_label( op.to_s ) | ||||||
|  | 			but.request_size( 64, 64 ) | ||||||
|  | 			but.signal_connect( "clicked", self, op ) | ||||||
|  | 			container.attach( but, 3, r, 1, 1 ) | ||||||
|  | 			r+=1 | ||||||
|  | 		end | ||||||
|  |  | ||||||
|  | 		# = | ||||||
|  | 		but_eq = new GtkButton.with_label( "=" ) | ||||||
|  | 		but_eq.request_size( 64, 64 ) | ||||||
|  | 		but_eq.signal_connect( "clicked", self, '=' ) | ||||||
|  | 		container.attach( but_eq, 4, 3, 1, 2 ) | ||||||
|  |  | ||||||
|  | 		# . | ||||||
|  | 		but_dot = new GtkButton.with_label( "." ) | ||||||
|  | 		but_dot.request_size( 64, 64 ) | ||||||
|  | 		but_dot.signal_connect( "clicked", self, '.' ) | ||||||
|  | 		container.attach( but_dot, 1, 4, 1, 1 ) | ||||||
|  |  | ||||||
|  | 		#C | ||||||
|  | 		var but_c =  new GtkButton.with_label( "C" ) | ||||||
|  | 		but_c.request_size( 64, 64 ) | ||||||
|  | 		but_c.signal_connect("clicked", self, 'C') | ||||||
|  | 		container.attach( but_c, 2, 4, 1, 1 ) | ||||||
|  |  | ||||||
|  | 		win.show_all | ||||||
|  | 	end | ||||||
|  | end | ||||||
|  |  | ||||||
|  | # context tests | ||||||
|  | var context = new CalculatorContext | ||||||
|  | context.push_digit( 1 ) | ||||||
|  | context.push_digit( 2 ) | ||||||
|  | context.push_op( '+' ) | ||||||
|  | context.push_digit( 3 ) | ||||||
|  | context.push_op( '*' ) | ||||||
|  | context.push_digit( 2 ) | ||||||
|  | context.push_op( '=' ) | ||||||
|  | var r = context.result.to_precision( 2 ) | ||||||
|  | assert r == "30.00" else print r | ||||||
|  |  | ||||||
|  | context = new CalculatorContext | ||||||
|  | context.push_digit( 1 ) | ||||||
|  | context.push_digit( 4 ) | ||||||
|  | context.switch_to_decimals | ||||||
|  | context.push_digit( 1 ) | ||||||
|  | context.push_op( '*' ) | ||||||
|  | context.push_digit( 3 ) | ||||||
|  | context.push_op( '=' ) | ||||||
|  | r = context.result.to_precision( 2 ) | ||||||
|  | assert r == "42.30" else print r | ||||||
|  |  | ||||||
|  | context.push_op( '+' ) | ||||||
|  | context.push_digit( 1 ) | ||||||
|  | context.push_digit( 1 ) | ||||||
|  | context.push_op( '=' ) | ||||||
|  | r = context.result.to_precision( 2 ) | ||||||
|  | assert r == "53.30" else print r | ||||||
|  |  | ||||||
|  | context = new CalculatorContext | ||||||
|  | context.push_digit( 4 ) | ||||||
|  | context.push_digit( 2 ) | ||||||
|  | context.switch_to_decimals | ||||||
|  | context.push_digit( 3 ) | ||||||
|  | context.push_op( '/' ) | ||||||
|  | context.push_digit( 3 ) | ||||||
|  | context.push_op( '=' ) | ||||||
|  | r = context.result.to_precision( 2 ) | ||||||
|  | assert r == "14.10" else print r | ||||||
|  |  | ||||||
|  | #test multiple decimals | ||||||
|  | context = new CalculatorContext | ||||||
|  | context.push_digit( 5 ) | ||||||
|  | context.push_digit( 0 ) | ||||||
|  | context.switch_to_decimals | ||||||
|  | context.push_digit( 1 ) | ||||||
|  | context.push_digit( 2 ) | ||||||
|  | context.push_digit( 3 ) | ||||||
|  | context.push_op( '+' ) | ||||||
|  | context.push_digit( 1 ) | ||||||
|  | context.push_op( '=' ) | ||||||
|  | r = context.result.to_precision( 3 ) | ||||||
|  | assert r == "51.123" else print r | ||||||
|  |  | ||||||
|  | #test 'C' button | ||||||
|  | context = new CalculatorContext | ||||||
|  | context.push_digit( 1 ) | ||||||
|  | context.push_digit( 0 ) | ||||||
|  | context.push_op( '+' ) | ||||||
|  | context.push_digit( 1 ) | ||||||
|  | context.push_digit( 0 ) | ||||||
|  | context.push_op( '=' ) | ||||||
|  | context.push_op( 'C' ) | ||||||
|  | r = context.result.to_precision( 1 ) | ||||||
|  | assert r == "0.0" else print r | ||||||
|  |  | ||||||
|  | # graphical application | ||||||
|  |  | ||||||
|  | if "NIT_TESTING".environ != "true" then | ||||||
|  | 	var app = new CalculatorGui | ||||||
|  | 	run_gtk | ||||||
|  | end | ||||||
							
								
								
									
										45
									
								
								samples/Nit/callback_chimpanze.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								samples/Nit/callback_chimpanze.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # Copyright 2013 Matthieu Lucas <lucasmatthieu@gmail.com> | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | # This sample has been implemented to show you how simple is it to play  | ||||||
|  | # with native callbacks (C) through an high level with NIT program. | ||||||
|  |  | ||||||
|  | module callback_chimpanze | ||||||
|  | import callback_monkey | ||||||
|  |  | ||||||
|  | class Chimpanze | ||||||
|  | 	super MonkeyActionCallable | ||||||
|  |  | ||||||
|  | 	fun create | ||||||
|  | 	do | ||||||
|  | 		var monkey = new Monkey | ||||||
|  | 		print "Hum, I'm sleeping ..." | ||||||
|  | 		# Invoking method which will take some time to compute, and  | ||||||
|  | 		# will be back in wokeUp method with information. | ||||||
|  | 		# - Callback method defined in MonkeyActionCallable Interface | ||||||
|  | 		monkey.wokeUpAction(self, "Hey, I'm awake.") | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	# Inherit callback method, defined by MonkeyActionCallable interface | ||||||
|  | 	# - Back of wokeUpAction method  | ||||||
|  | 	redef fun wokeUp( sender:Monkey, message:Object ) | ||||||
|  | 	do | ||||||
|  | 		print message | ||||||
|  | 	end | ||||||
|  | end | ||||||
|  |  | ||||||
|  | var m = new Chimpanze | ||||||
|  | m.create | ||||||
							
								
								
									
										92
									
								
								samples/Nit/callback_monkey.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								samples/Nit/callback_monkey.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,92 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # Copyright 2013 Matthieu Lucas <lucasmatthieu@gmail.com> | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | # This sample has been implemented to show you how simple is it to play  | ||||||
|  | # with native callbacks (C) through an high level with NIT program. | ||||||
|  |  | ||||||
|  | module callback_monkey | ||||||
|  |  | ||||||
|  | in "C header" `{ | ||||||
|  | 	#include <stdio.h> | ||||||
|  | 	#include <stdlib.h> | ||||||
|  |  | ||||||
|  | 	typedef struct {  | ||||||
|  | 		int id; | ||||||
|  | 		int age; | ||||||
|  | 	} CMonkey; | ||||||
|  |  | ||||||
|  | 	typedef struct { | ||||||
|  | 		MonkeyActionCallable toCall; | ||||||
|  | 		Object message; | ||||||
|  | 	} MonkeyAction; | ||||||
|  | `} | ||||||
|  |  | ||||||
|  | in "C body" `{ | ||||||
|  | 	// Method which reproduce a callback answer | ||||||
|  | 	// Please note that a function pointer is only used to reproduce the callback | ||||||
|  | 	void cbMonkey(CMonkey *mkey, void callbackFunc(CMonkey*, MonkeyAction*), MonkeyAction *data) | ||||||
|  | 	{ | ||||||
|  | 		sleep(2); | ||||||
|  | 		callbackFunc( mkey, data ); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Back of background treatment, will be redirected to callback function | ||||||
|  | 	void nit_monkey_callback_func( CMonkey *mkey, MonkeyAction *data ) | ||||||
|  | 	{ | ||||||
|  | 		// To call a your method, the signature must be written like this : | ||||||
|  | 		// <Interface Name>_<Method>... | ||||||
|  | 		MonkeyActionCallable_wokeUp( data->toCall, mkey, data->message ); | ||||||
|  | 	} | ||||||
|  | `} | ||||||
|  |  | ||||||
|  | # Implementable interface to get callback in defined methods | ||||||
|  | interface MonkeyActionCallable | ||||||
|  | 	fun wokeUp( sender:Monkey, message: Object) is abstract | ||||||
|  | end | ||||||
|  |  | ||||||
|  | # Defining my object type Monkey, which is, in a low level, a pointer to a C struct (CMonkey) | ||||||
|  | extern class Monkey `{ CMonkey * `} | ||||||
|  | 	 | ||||||
|  | 	new `{ | ||||||
|  | 		CMonkey *monkey = malloc( sizeof(CMonkey) ); | ||||||
|  | 		monkey->age = 10; | ||||||
|  | 		monkey->id = 1; | ||||||
|  | 		return monkey; | ||||||
|  | 	`} | ||||||
|  | 	 | ||||||
|  | 	# Object method which will get a callback in wokeUp method, defined in MonkeyActionCallable interface | ||||||
|  | 	# Must be defined as Nit/C method because of C call inside | ||||||
|  | 	fun wokeUpAction( toCall: MonkeyActionCallable, message: Object ) is extern import MonkeyActionCallable.wokeUp `{ | ||||||
|  |  | ||||||
|  | 		// Allocating memory to keep reference of received parameters : | ||||||
|  | 		// - Object receiver | ||||||
|  | 		// - Message  | ||||||
|  | 		MonkeyAction *data = malloc( sizeof(MonkeyAction) ); | ||||||
|  |  | ||||||
|  | 		// Incrementing reference counter to prevent from releasing | ||||||
|  | 		MonkeyActionCallable_incr_ref( toCall ); | ||||||
|  | 		Object_incr_ref( message ); | ||||||
|  | 		 | ||||||
|  | 		data->toCall = toCall; | ||||||
|  | 		data->message = message; | ||||||
|  | 		 | ||||||
|  | 		// Calling method which reproduce a callback by passing : | ||||||
|  | 		// - Receiver | ||||||
|  | 		// - Function pointer to object return method | ||||||
|  | 		// - Datas | ||||||
|  | 		cbMonkey( recv, &nit_monkey_callback_func, data ); | ||||||
|  | 	`} | ||||||
|  | end | ||||||
							
								
								
									
										167
									
								
								samples/Nit/circular_list.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										167
									
								
								samples/Nit/circular_list.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,167 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | # Implementation of circular lists | ||||||
|  | # This example shows the usage of generics and somewhat a specialisation of collections. | ||||||
|  | module circular_list | ||||||
|  |  | ||||||
|  | # Sequences of elements implemented with a double-linked circular list | ||||||
|  | class CircularList[E] | ||||||
|  | 	# Like standard Array or LinkedList, CircularList is a Sequence. | ||||||
|  | 	super Sequence[E] | ||||||
|  |  | ||||||
|  | 	# The first node of the list if any | ||||||
|  | 	# The special case of an empty list is handled by a null node | ||||||
|  | 	private var node: nullable CLNode[E] = null | ||||||
|  |  | ||||||
|  | 	redef fun iterator do return new CircularListIterator[E](self) | ||||||
|  |  | ||||||
|  | 	redef fun first do return self.node.item | ||||||
|  |  | ||||||
|  | 	redef fun push(e) | ||||||
|  | 	do | ||||||
|  | 		var new_node = new CLNode[E](e) | ||||||
|  | 		var n = self.node | ||||||
|  | 		if n == null then | ||||||
|  | 			# the first node | ||||||
|  | 			self.node = new_node | ||||||
|  | 		else | ||||||
|  | 			# not the first one, so attach nodes correctly. | ||||||
|  | 			var old_last_node = n.prev | ||||||
|  | 			new_node.next = n | ||||||
|  | 			new_node.prev = old_last_node | ||||||
|  | 			old_last_node.next = new_node | ||||||
|  | 			n.prev = new_node | ||||||
|  | 		end | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	redef fun pop | ||||||
|  | 	do | ||||||
|  | 		var n = self.node | ||||||
|  | 		assert n != null | ||||||
|  | 		var prev = n.prev | ||||||
|  | 		if prev == n then | ||||||
|  | 			# the only node | ||||||
|  | 			self.node = null | ||||||
|  | 			return n.item | ||||||
|  | 		end | ||||||
|  | 		# not the only one do detach nodes correctly. | ||||||
|  | 		var prev_prev = prev.prev | ||||||
|  | 		n.prev = prev_prev | ||||||
|  | 		prev_prev.next = n | ||||||
|  | 		return prev.item | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	redef fun unshift(e) | ||||||
|  | 	do | ||||||
|  | 		# Circularity has benefits. | ||||||
|  | 		push(e) | ||||||
|  | 		self.node = self.node.prev | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	redef fun shift | ||||||
|  | 	do | ||||||
|  | 		# Circularity has benefits. | ||||||
|  | 		self.node = self.node.next | ||||||
|  | 		return self.pop | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	# Move the first at the last position, the second at the first, etc. | ||||||
|  | 	fun rotate | ||||||
|  | 	do | ||||||
|  | 		var n = self.node | ||||||
|  | 		if n == null then return | ||||||
|  | 		self.node = n.next | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	# Sort the list using the Josephus algorithm. | ||||||
|  | 	fun josephus(step: Int) | ||||||
|  | 	do | ||||||
|  | 		var res = new CircularList[E] | ||||||
|  | 		while not self.is_empty do | ||||||
|  | 			# count 'step' | ||||||
|  | 			for i in [1..step[ do self.rotate | ||||||
|  | 			# kill | ||||||
|  | 			var x = self.shift | ||||||
|  | 			res.add(x) | ||||||
|  | 		end | ||||||
|  | 		self.node = res.node | ||||||
|  | 	end | ||||||
|  | end | ||||||
|  |  | ||||||
|  | # Nodes of a CircularList | ||||||
|  | private class CLNode[E] | ||||||
|  | 	# The current item | ||||||
|  | 	var item: E | ||||||
|  |  | ||||||
|  | 	# The next item in the circular list. | ||||||
|  | 	# Because of circularity, there is always a next; | ||||||
|  | 	# so by default let it be self | ||||||
|  | 	var next: CLNode[E] = self | ||||||
|  |  | ||||||
|  | 	# The previous item in the circular list. | ||||||
|  | 	# Coherence between next and previous nodes has to be maintained by the | ||||||
|  | 	# circular list. | ||||||
|  | 	var prev: CLNode[E] = self | ||||||
|  | end | ||||||
|  |  | ||||||
|  | # An iterator of a CircularList. | ||||||
|  | private class CircularListIterator[E] | ||||||
|  | 	super IndexedIterator[E] | ||||||
|  |  | ||||||
|  | 	redef var index: Int | ||||||
|  |  | ||||||
|  | 	# The current node pointed. | ||||||
|  | 	# Is null if the list is empty. | ||||||
|  | 	var node: nullable CLNode[E] | ||||||
|  |  | ||||||
|  | 	# The list iterated. | ||||||
|  | 	var list: CircularList[E] | ||||||
|  |  | ||||||
|  | 	redef fun is_ok | ||||||
|  | 	do | ||||||
|  | 		# Empty lists are not OK. | ||||||
|  | 		# Pointing again the first node is not OK. | ||||||
|  | 		return self.node != null and (self.index == 0 or self.node != self.list.node) | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	redef fun next | ||||||
|  | 	do | ||||||
|  | 		self.node = self.node.next | ||||||
|  | 		self.index += 1 | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	redef fun item do return self.node.item | ||||||
|  |  | ||||||
|  | 	init(list: CircularList[E]) | ||||||
|  | 	do | ||||||
|  | 		self.node = list.node | ||||||
|  | 		self.list = list | ||||||
|  | 		self.index = 0 | ||||||
|  | 	end | ||||||
|  | end | ||||||
|  |  | ||||||
|  | var i = new CircularList[Int] | ||||||
|  | i.add_all([1, 2, 3, 4, 5, 6, 7]) | ||||||
|  | print i.first | ||||||
|  | print i.join(":") | ||||||
|  |  | ||||||
|  | i.push(8) | ||||||
|  | print i.shift | ||||||
|  | print i.pop | ||||||
|  | i.unshift(0) | ||||||
|  | print i.join(":") | ||||||
|  |  | ||||||
|  | i.josephus(3) | ||||||
|  | print i.join(":") | ||||||
							
								
								
									
										78
									
								
								samples/Nit/clock.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								samples/Nit/clock.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,78 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | # This module provide a simple wall clock. | ||||||
|  | # It is an example of getters and setters. | ||||||
|  | # A beefed-up module is available in clock_more | ||||||
|  | module clock | ||||||
|  |  | ||||||
|  | # A simple wall clock with 60 minutes and 12 hours. | ||||||
|  | class Clock | ||||||
|  | 	# total number of minutes from 0 to 719 | ||||||
|  | 	var total_minutes: Int | ||||||
|  | 	# Note: only the read acces is public, the write access is private. | ||||||
|  |  | ||||||
|  | 	# number of minutes in the current hour (from 0 to 59) | ||||||
|  | 	fun minutes: Int do return self.total_minutes % 60 | ||||||
|  | 	 | ||||||
|  | 	# set the number of minutes in the current hour. | ||||||
|  | 	# if m < 0 or m >= 60, the hour will be changed accordinlgy | ||||||
|  | 	fun minutes=(m: Int) do self.total_minutes = self.hours * 60 + m | ||||||
|  |  | ||||||
|  | 	# number of hours (from 0 to 11) | ||||||
|  | 	fun hours: Int do return self.total_minutes / 60 | ||||||
|  |  | ||||||
|  | 	# set the number of hours | ||||||
|  | 	# the minutes will not be updated | ||||||
|  | 	fun hours=(h: Int) do self.total_minutes = h * 60 + minutes | ||||||
|  |  | ||||||
|  | 	# the position of the hour arrow in the [0..60[ interval | ||||||
|  | 	fun hour_pos: Int do return total_minutes / 12 | ||||||
|  |  | ||||||
|  | 	# replace the arrow of hours (from 0 to 59). | ||||||
|  | 	# the hours and the minutes will be updated. | ||||||
|  | 	fun hour_pos=(h: Int) do self.total_minutes = h * 12 | ||||||
|  |  | ||||||
|  | 	redef fun to_s do return "{hours}:{minutes}" | ||||||
|  |  | ||||||
|  | 	fun reset(hours, minutes: Int) do self.total_minutes = hours*60 + minutes | ||||||
|  |  | ||||||
|  | 	init(hours, minutes: Int) do self.reset(hours, minutes) | ||||||
|  |  | ||||||
|  | 	redef fun ==(o) | ||||||
|  | 	do | ||||||
|  | 		# Note: o is a nullable Object, a type test is required | ||||||
|  | 		# Thanks to adaptive typing, there is no downcast | ||||||
|  | 		# i.e. the code is safe! | ||||||
|  | 		return o isa Clock and self.total_minutes == o.total_minutes | ||||||
|  | 	end | ||||||
|  | end | ||||||
|  |  | ||||||
|  | var c = new Clock(10,50) | ||||||
|  | print "It's {c} o'clock." | ||||||
|  |  | ||||||
|  | c.minutes += 22 | ||||||
|  | print "Now it's {c} o'clock." | ||||||
|  |  | ||||||
|  | print "The short arrow in on the {c.hour_pos/5} and the long arrow in on the {c.minutes/5}." | ||||||
|  |  | ||||||
|  | c.hours -= 2 | ||||||
|  | print "Now it's {c} o'clock." | ||||||
|  |  | ||||||
|  | var c2 = new Clock(9, 11) | ||||||
|  | print "It's {c2} on the second clock." | ||||||
|  | print "The two clocks are synchronized: {c == c2}." | ||||||
|  | c2.minutes += 1 | ||||||
|  | print "It's now {c2} on the second clock." | ||||||
|  | print "The two clocks are synchronized: {c == c2}." | ||||||
							
								
								
									
										60
									
								
								samples/Nit/clock_more.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								samples/Nit/clock_more.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,60 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | # This module beef up the clock module by allowing a clock to be comparable. | ||||||
|  | # It show the usage of class refinement | ||||||
|  | module clock_more | ||||||
|  |  | ||||||
|  | import clock | ||||||
|  |  | ||||||
|  | redef class Clock | ||||||
|  | 	# Clock are now comparable | ||||||
|  | 	super Comparable | ||||||
|  |  | ||||||
|  | 	# Comparaison of a clock make only sense with an other clock | ||||||
|  | 	redef type OTHER: Clock | ||||||
|  |  | ||||||
|  | 	redef fun <(o) | ||||||
|  | 	do | ||||||
|  | 		# Note: < is the only abstract method of Comparable. | ||||||
|  | 		#       All other operators and methods rely on < and ==. | ||||||
|  | 		return self.total_minutes < o.total_minutes | ||||||
|  | 	end | ||||||
|  | end | ||||||
|  |  | ||||||
|  | var c1 = new Clock(8, 12) | ||||||
|  | var c2 = new Clock(8, 13) | ||||||
|  | var c3 = new Clock(9, 13) | ||||||
|  |  | ||||||
|  | print "{c1}<{c2}? {c1<c2}" | ||||||
|  | print "{c1}<={c2}? {c1<=c2}" | ||||||
|  | print "{c1}>{c2}? {c1>c2}" | ||||||
|  | print "{c1}>={c2}? {c1>=c2}" | ||||||
|  | print "{c1}<=>{c2}? {c1<=>c2}" | ||||||
|  | print "{c1},{c2}? max={c1.max(c2)} min={c1.min(c2)}" | ||||||
|  | print "{c1}.is_between({c2}, {c3})? {c1.is_between(c2, c3)}" | ||||||
|  | print "{c2}.is_between({c1}, {c3})? {c2.is_between(c1, c3)}" | ||||||
|  |  | ||||||
|  | print "-" | ||||||
|  |  | ||||||
|  | c1.minutes += 1 | ||||||
|  |  | ||||||
|  | print "{c1}<{c2}? {c1<c2}" | ||||||
|  | print "{c1}<={c2}? {c1<=c2}" | ||||||
|  | print "{c1}>{c2}? {c1>c2}" | ||||||
|  | print "{c1}>={c2}? {c1>=c2}" | ||||||
|  | print "{c1}<=>{c2}? {c1<=>c2}" | ||||||
|  | print "{c1},{c2}? max={c1.max(c2)} min={c1.min(c2)}" | ||||||
|  | print "{c1}.is_between({c2}, {c3})? {c1.is_between(c2, c3)}" | ||||||
|  | print "{c2}.is_between({c1}, {c3})? {c2.is_between(c1, c3)}" | ||||||
							
								
								
									
										113
									
								
								samples/Nit/curl_http.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								samples/Nit/curl_http.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,113 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # Copyright 2013 Matthieu Lucas <lucasmatthieu@gmail.com> | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | # Sample of the Curl module. | ||||||
|  | module curl_http | ||||||
|  |  | ||||||
|  | import curl | ||||||
|  |  | ||||||
|  | # Small class to represent an Http Fetcher | ||||||
|  | class MyHttpFetcher | ||||||
|  | 	super CurlCallbacks | ||||||
|  |  | ||||||
|  | 	var curl: Curl | ||||||
|  | 	var our_body: String = "" | ||||||
|  |  | ||||||
|  | 	init(curl: Curl) do self.curl = curl | ||||||
|  |  | ||||||
|  | 	# Release curl object | ||||||
|  | 	fun destroy do self.curl.destroy | ||||||
|  |  | ||||||
|  | 	# Header callback | ||||||
|  | 	redef fun header_callback(line: String) do | ||||||
|  | 		# We keep this callback silent for testing purposes | ||||||
|  | 		#if not line.has_prefix("Date:") then print "Header_callback : {line}" | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	# Body callback | ||||||
|  | 	redef fun body_callback(line: String) do self.our_body = "{self.our_body}{line}" | ||||||
|  |  | ||||||
|  | 	# Stream callback - Cf : No one is registered | ||||||
|  | 	redef fun stream_callback(buffer: String, size: Int, count: Int) do print "Stream_callback : {buffer} - {size} - {count}" | ||||||
|  | end | ||||||
|  |  | ||||||
|  |  | ||||||
|  | # Program | ||||||
|  | if args.length < 2 then | ||||||
|  | 	print "Usage: curl_http <method wished [POST, GET, GET_FILE]> <target url>" | ||||||
|  | else | ||||||
|  | 	var curl = new Curl | ||||||
|  | 	var url = args[1] | ||||||
|  | 	var request = new CurlHTTPRequest(url, curl) | ||||||
|  |  | ||||||
|  | 	# HTTP Get Request | ||||||
|  | 	if args[0] == "GET" then | ||||||
|  | 		request.verbose = false | ||||||
|  | 		var getResponse = request.execute | ||||||
|  |  | ||||||
|  | 		if getResponse isa CurlResponseSuccess then | ||||||
|  | 			print "Status code : {getResponse.status_code}" | ||||||
|  | 			print "Body : {getResponse.body_str}" | ||||||
|  | 		else if getResponse isa CurlResponseFailed then | ||||||
|  | 			print "Error code : {getResponse.error_code}" | ||||||
|  | 			print "Error msg : {getResponse.error_msg}" | ||||||
|  | 		end | ||||||
|  |  | ||||||
|  | 	# HTTP Post Request | ||||||
|  | 	else if args[0] == "POST" then | ||||||
|  | 		var myHttpFetcher = new MyHttpFetcher(curl) | ||||||
|  | 		request.delegate = myHttpFetcher | ||||||
|  |  | ||||||
|  | 		var postDatas = new HeaderMap | ||||||
|  | 		postDatas["Bugs Bunny"] = "Daffy Duck" | ||||||
|  | 		postDatas["Batman"] = "Robin likes special characters @#ùà!è§'(\"é&://,;<>∞~*" | ||||||
|  | 		postDatas["Batman"] = "Yes you can set multiple identical keys, but APACHE will consider only once, the last one" | ||||||
|  | 		request.datas = postDatas | ||||||
|  | 		request.verbose = false | ||||||
|  | 		var postResponse = request.execute | ||||||
|  |  | ||||||
|  | 		print "Our body from the callback : {myHttpFetcher.our_body}" | ||||||
|  |  | ||||||
|  | 		if postResponse isa CurlResponseSuccess then | ||||||
|  | 			print "*** Answer ***" | ||||||
|  | 			print "Status code : {postResponse.status_code}" | ||||||
|  | 			print "Body should be empty, because we decided to manage callbacks : {postResponse.body_str.length}" | ||||||
|  | 		else if postResponse isa CurlResponseFailed then | ||||||
|  | 			print "Error code : {postResponse.error_code}" | ||||||
|  | 			print "Error msg : {postResponse.error_msg}" | ||||||
|  | 		end | ||||||
|  |  | ||||||
|  | 	# HTTP Get to file Request | ||||||
|  | 	else if args[0] == "GET_FILE" then | ||||||
|  | 		var headers = new HeaderMap | ||||||
|  | 		headers["Accept"] = "Moo" | ||||||
|  | 		request.headers = headers | ||||||
|  | 		request.verbose = false | ||||||
|  | 		var downloadResponse = request.download_to_file(null) | ||||||
|  |  | ||||||
|  | 		if downloadResponse isa CurlFileResponseSuccess then | ||||||
|  | 			print "*** Answer ***" | ||||||
|  | 			print "Status code : {downloadResponse.status_code}" | ||||||
|  | 			print "Size downloaded : {downloadResponse.size_download}" | ||||||
|  | 		else if downloadResponse isa CurlResponseFailed then | ||||||
|  | 			print "Error code : {downloadResponse.error_code}" | ||||||
|  | 			print "Error msg : {downloadResponse.error_msg}" | ||||||
|  | 		end | ||||||
|  | 	# Program logic | ||||||
|  | 	else | ||||||
|  | 		print "Usage : Method[POST, GET, GET_FILE]" | ||||||
|  | 	end | ||||||
|  | end | ||||||
							
								
								
									
										59
									
								
								samples/Nit/curl_mail.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								samples/Nit/curl_mail.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,59 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # Copyright 2013 Matthieu Lucas <lucasmatthieu@gmail.com> | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | # Mail sender sample using the Curl module | ||||||
|  | module curl_mail | ||||||
|  |  | ||||||
|  | import curl | ||||||
|  |  | ||||||
|  | var curl = new Curl | ||||||
|  | var mail_request = new CurlMailRequest(curl) | ||||||
|  |  | ||||||
|  | # Networks | ||||||
|  | var response = mail_request.set_outgoing_server("smtps://smtp.example.org:465", "user@example.org", "mypassword") | ||||||
|  | if response isa CurlResponseFailed then | ||||||
|  | 	print "Error code : {response.error_code}" | ||||||
|  | 	print "Error msg : {response.error_msg}" | ||||||
|  | end | ||||||
|  |  | ||||||
|  | # Headers | ||||||
|  | mail_request.from = "Billy Bob" | ||||||
|  | mail_request.to = ["user@example.org"] | ||||||
|  | mail_request.cc = ["bob@example.org"] | ||||||
|  | mail_request.bcc = null | ||||||
|  |  | ||||||
|  | var headers_body = new HeaderMap | ||||||
|  | headers_body["Content-Type:"] = "text/html; charset=\"UTF-8\"" | ||||||
|  | headers_body["Content-Transfer-Encoding:"] = "quoted-printable" | ||||||
|  | mail_request.headers_body = headers_body | ||||||
|  |  | ||||||
|  | # Content | ||||||
|  | mail_request.body = "<h1>Here you can write HTML stuff.</h1>" | ||||||
|  | mail_request.subject = "Hello From My Nit Program" | ||||||
|  |  | ||||||
|  | # Others | ||||||
|  | mail_request.verbose = false | ||||||
|  |  | ||||||
|  | # Send mail | ||||||
|  | response = mail_request.execute | ||||||
|  | if response isa CurlResponseFailed then | ||||||
|  | 	print "Error code : {response.error_code}" | ||||||
|  | 	print "Error msg : {response.error_msg}" | ||||||
|  | else if response isa CurlMailResponseSuccess then | ||||||
|  | 	print "Mail Sent" | ||||||
|  | else | ||||||
|  | 	print "Unknown Curl Response type" | ||||||
|  | end | ||||||
							
								
								
									
										243
									
								
								samples/Nit/draw_operation.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										243
									
								
								samples/Nit/draw_operation.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,243 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # Copyright 2012-2013 Alexis Laferrière <alexis.laf@xymus.net> | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | # Draws an arithmetic operation to the terminal | ||||||
|  | module draw_operation | ||||||
|  |  | ||||||
|  | redef enum Int | ||||||
|  | 	fun n_chars: Int `{ | ||||||
|  | 		int c; | ||||||
|  | 		if ( abs(recv) >= 10 ) | ||||||
|  | 			c = 1+(int)log10f( (float)abs(recv) ); | ||||||
|  | 		else | ||||||
|  | 			c = 1; | ||||||
|  | 		if ( recv < 0 ) c ++; | ||||||
|  | 		return c; | ||||||
|  | 	`} | ||||||
|  | end | ||||||
|  |  | ||||||
|  | redef enum Char | ||||||
|  | 	fun as_operator(a, b: Int): Int | ||||||
|  | 	do | ||||||
|  | 		if self == '+' then return a + b | ||||||
|  | 		if self == '-' then return a - b | ||||||
|  | 		if self == '*' then return a * b | ||||||
|  | 		if self == '/' then return a / b | ||||||
|  | 		if self == '%' then return a % b | ||||||
|  | 		abort | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	fun override_dispc: Bool | ||||||
|  | 	do | ||||||
|  | 		return self == '+' or self == '-' or self == '*' or self == '/' or self == '%' | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	fun lines(s: Int): Array[Line] | ||||||
|  | 	do | ||||||
|  | 		if self == '+' then | ||||||
|  | 			return [new Line(new P(0,s/2),1,0,s), new Line(new P(s/2,1),0,1,s-2)] | ||||||
|  | 		else if self == '-' then | ||||||
|  | 			return [new Line(new P(0,s/2),1,0,s)] | ||||||
|  | 		else if self == '*' then | ||||||
|  | 			var lines = new Array[Line] | ||||||
|  | 			for y in [1..s-1[ do | ||||||
|  | 				lines.add( new Line(new P(1,y), 1,0,s-2) ) | ||||||
|  | 			end | ||||||
|  | 			return lines | ||||||
|  | 		else if self == '/' then | ||||||
|  | 			return [new Line(new P(s-1,0), -1,1, s )] | ||||||
|  | 		else if self == '%' then | ||||||
|  | 			var q4 = s/4 | ||||||
|  | 			var lines = [new Line(new P(s-1,0),-1,1,s)] | ||||||
|  | 			for l in [0..q4[ do | ||||||
|  | 				lines.append([ new Line( new P(0,l), 1,0,q4), new Line( new P(s-1,s-1-l), -1,0,q4) ]) | ||||||
|  | 			end | ||||||
|  | 			return lines | ||||||
|  | 		else if self == '1' then | ||||||
|  | 			return [new Line(new P(s/2,0), 0,1,s),new Line(new P(0,s-1),1,0,s), | ||||||
|  | 				new Line( new P(s/2,0),-1,1,s/2)] | ||||||
|  | 		else if self == '2' then | ||||||
|  | 			return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,0),0,1,s/2), | ||||||
|  | 				new Line( new P(0,s-1),1,0,s), new Line( new P(0,s/2), 0,1,s/2), | ||||||
|  | 				new Line( new P(0,s/2), 1,0,s)] | ||||||
|  | 		else if self == '3' then | ||||||
|  | 			return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,0),0,1,s), | ||||||
|  | 				new Line( new P(0,s-1),1,0,s), new Line( new P(0,s/2), 1,0,s)] | ||||||
|  | 		else if self == '4' then | ||||||
|  | 			return [new Line(new P(s-1,0),0,1,s), new Line( new P(0,0), 0,1,s/2), | ||||||
|  | 				new Line( new P(0,s/2), 1,0,s)] | ||||||
|  | 		else if self == '5' then | ||||||
|  | 			return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,s/2),0,1,s/2), | ||||||
|  | 				new Line( new P(0,s-1),1,0,s), new Line( new P(0,0), 0,1,s/2), | ||||||
|  | 				new Line( new P(0,s/2), 1,0,s)] | ||||||
|  | 		else if self == '6' then | ||||||
|  | 			return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,s/2),0,1,s/2), | ||||||
|  | 				new Line( new P(0,s-1),1,0,s), new Line( new P(0,0), 0,1,s), | ||||||
|  | 				new Line( new P(0,s/2), 1,0,s)] | ||||||
|  | 		else if self == '7' then | ||||||
|  | 			var tl = new P(0,0) | ||||||
|  | 			var tr = new P(s-1,0) | ||||||
|  | 			return [new Line(tl, 1,0,s), new Line(tr,-1,1,s)] | ||||||
|  | 		else if self == '8' then | ||||||
|  | 			return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,0),0,1,s), | ||||||
|  | 				new Line( new P(0,s-1),1,0,s), new Line( new P(0,0), 0,1,s), | ||||||
|  | 				new Line( new P(0,s/2), 1,0,s)] | ||||||
|  | 		else if self == '9' then | ||||||
|  | 			return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,0),0,1,s), | ||||||
|  | 				new Line( new P(0,s-1),1,0,s), new Line( new P(0,0), 0,1,s/2), | ||||||
|  | 				new Line( new P(0,s/2), 1,0,s)] | ||||||
|  | 		else if self == '0' then | ||||||
|  | 			return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,0),0,1,s), | ||||||
|  | 				new Line( new P(0,s-1),1,0,s), new Line( new P(0,0), 0,1,s)] | ||||||
|  | 		end | ||||||
|  | 		return new Array[Line] | ||||||
|  | 	end | ||||||
|  | end | ||||||
|  |  | ||||||
|  | class P | ||||||
|  | 	var x : Int | ||||||
|  | 	var y : Int | ||||||
|  | end | ||||||
|  |  | ||||||
|  | redef class String | ||||||
|  | 	# hack is to support a bug in the evaluation software | ||||||
|  | 	fun draw(dispc: Char, size, gap: Int, hack: Bool) | ||||||
|  | 	do | ||||||
|  | 		var w = size * length +(length-1)*gap | ||||||
|  | 		var h = size | ||||||
|  | 		var map = new Array[Array[Char]] | ||||||
|  | 		for x in [0..w[ do | ||||||
|  | 			map[x] = new Array[Char].filled_with( ' ',  h ) | ||||||
|  | 		end | ||||||
|  |  | ||||||
|  | 		var ci = 0 | ||||||
|  | 		for c in self.chars do | ||||||
|  | 			var local_dispc | ||||||
|  | 			if c.override_dispc then | ||||||
|  | 				local_dispc = c | ||||||
|  | 			else | ||||||
|  | 				local_dispc = dispc | ||||||
|  | 			end | ||||||
|  |  | ||||||
|  | 			var lines = c.lines( size ) | ||||||
|  | 			for line in lines do | ||||||
|  | 				var x = line.o.x+ci*size | ||||||
|  | 					x += ci*gap | ||||||
|  | 				var y = line.o.y | ||||||
|  | 				for s in [0..line.len[ do | ||||||
|  | 					assert map.length > x and map[x].length > y else print "setting {x},{y} as {local_dispc}" | ||||||
|  | 					map[x][y] = local_dispc | ||||||
|  | 					x += line.step_x | ||||||
|  | 					y += line.step_y | ||||||
|  | 				end | ||||||
|  | 			end | ||||||
|  |  | ||||||
|  | 			ci += 1 | ||||||
|  | 		end | ||||||
|  |  | ||||||
|  | 		if hack then | ||||||
|  | 			for c in [0..size[ do | ||||||
|  | 				map[c][0] = map[map.length-size+c][0] | ||||||
|  | 				map[map.length-size+c][0] = ' ' | ||||||
|  | 			end | ||||||
|  | 		end | ||||||
|  |  | ||||||
|  | 		for y in [0..h[ do | ||||||
|  | 			for x in [0..w[ do | ||||||
|  | 				printn map[x][y] | ||||||
|  | 			end | ||||||
|  | 			print "" | ||||||
|  | 		end | ||||||
|  | 	end | ||||||
|  | end | ||||||
|  |  | ||||||
|  | class Line | ||||||
|  | 	var o : P | ||||||
|  | 	var step_x : Int | ||||||
|  | 	var step_y : Int | ||||||
|  | 	var len : Int | ||||||
|  | end | ||||||
|  |  | ||||||
|  | var a | ||||||
|  | var b | ||||||
|  | var op_char | ||||||
|  | var disp_char | ||||||
|  | var disp_size | ||||||
|  | var disp_gap | ||||||
|  |  | ||||||
|  | if "NIT_TESTING".environ == "true" then | ||||||
|  | 	a = 567 | ||||||
|  | 	b = 13 | ||||||
|  | 	op_char = '*' | ||||||
|  | 	disp_char = 'O' | ||||||
|  | 	disp_size = 8 | ||||||
|  | 	disp_gap = 1 | ||||||
|  | else | ||||||
|  | 	printn "Left operand: " | ||||||
|  | 	a = gets.to_i | ||||||
|  |  | ||||||
|  | 	printn "Right operand: " | ||||||
|  | 	b = gets.to_i | ||||||
|  |  | ||||||
|  | 	printn "Operator (+, -, *, /, %): " | ||||||
|  | 	op_char = gets.chars[0] | ||||||
|  |  | ||||||
|  | 	printn "Char to display: " | ||||||
|  | 	disp_char = gets.chars[0] | ||||||
|  |  | ||||||
|  | 	printn "Size of text: " | ||||||
|  | 	disp_size = gets.to_i | ||||||
|  |  | ||||||
|  | 	printn "Space between digits: " | ||||||
|  | 	disp_gap = gets.to_i | ||||||
|  | end | ||||||
|  |  | ||||||
|  | var result = op_char.as_operator( a, b ) | ||||||
|  |  | ||||||
|  | var len_a = a.n_chars | ||||||
|  | var len_b = b.n_chars | ||||||
|  | var len_res = result.n_chars | ||||||
|  | var max_len = len_a.max( len_b.max( len_res ) ) + 1 | ||||||
|  |  | ||||||
|  | # draw first line | ||||||
|  | var d = max_len - len_a | ||||||
|  | var line_a = "" | ||||||
|  | for i in [0..d[ do line_a += " " | ||||||
|  | line_a += a.to_s | ||||||
|  | line_a.draw( disp_char, disp_size, disp_gap, false ) | ||||||
|  |  | ||||||
|  | print "" | ||||||
|  | # draw second line | ||||||
|  | d = max_len - len_b-1 | ||||||
|  | var line_b = op_char.to_s | ||||||
|  | for i in [0..d[ do line_b += " " | ||||||
|  | line_b += b.to_s | ||||||
|  | line_b.draw( disp_char, disp_size, disp_gap, false ) | ||||||
|  |  | ||||||
|  | # draw ----- | ||||||
|  | print "" | ||||||
|  | for i in [0..disp_size*max_len+(max_len-1)*disp_gap] do | ||||||
|  | 	printn "_" | ||||||
|  | end | ||||||
|  | print "" | ||||||
|  | print "" | ||||||
|  |  | ||||||
|  | # draw result | ||||||
|  | d = max_len - len_res | ||||||
|  | var line_res = "" | ||||||
|  | for i in [0..d[ do line_res += " " | ||||||
|  | line_res += result.to_s | ||||||
|  | line_res.draw( disp_char, disp_size, disp_gap, false ) | ||||||
							
								
								
									
										46
									
								
								samples/Nit/drop_privileges.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								samples/Nit/drop_privileges.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # Copyright 2013 Alexis Laferrière <alexis.laf@xymus.net> | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | # Example using the privileges module to drop privileges from root | ||||||
|  | module drop_privileges | ||||||
|  |  | ||||||
|  | import privileges | ||||||
|  |  | ||||||
|  | # basic command line options | ||||||
|  | var opts = new OptionContext | ||||||
|  | var opt_ug = new OptionUserAndGroup.for_dropping_privileges | ||||||
|  | opt_ug.mandatory = true | ||||||
|  | opts.add_option(opt_ug) | ||||||
|  |  | ||||||
|  | # parse and check command line options | ||||||
|  | opts.parse(args) | ||||||
|  | if not opts.errors.is_empty then | ||||||
|  | 	print opts.errors | ||||||
|  | 	print "Usage: drop_privileges [options]" | ||||||
|  | 	opts.usage | ||||||
|  | 	exit 1 | ||||||
|  | end | ||||||
|  |  | ||||||
|  | # original user | ||||||
|  | print "before {sys.uid}:{sys.gid}" | ||||||
|  |  | ||||||
|  | # make the switch | ||||||
|  | var user_group = opt_ug.value | ||||||
|  | assert user_group != null | ||||||
|  | user_group.drop_privileges | ||||||
|  |  | ||||||
|  | # final user | ||||||
|  | print "after {sys.uid}:{sys.egid}" | ||||||
							
								
								
									
										69
									
								
								samples/Nit/extern_methods.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								samples/Nit/extern_methods.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,69 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # Copyright 2012-2013 Alexis Laferrière <alexis.laf@xymus.net> | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | # This module illustrates some uses of the FFI, specifically | ||||||
|  | # how to use extern methods. Which means to implement a Nit method in C. | ||||||
|  | module extern_methods | ||||||
|  |  | ||||||
|  | redef enum Int | ||||||
|  | 	# Returns self'th fibonnaci number | ||||||
|  | 	# implemented here in C for optimization purposes | ||||||
|  | 	fun fib : Int import fib `{ | ||||||
|  | 		if ( recv < 2 ) | ||||||
|  | 			return recv; | ||||||
|  | 		else | ||||||
|  | 			return Int_fib( recv-1 ) + Int_fib( recv-2 ); | ||||||
|  | 	`} | ||||||
|  |  | ||||||
|  | 	# System call to sleep for "self" seconds | ||||||
|  | 	fun sleep `{ | ||||||
|  | 		sleep( recv ); | ||||||
|  | 	`} | ||||||
|  |  | ||||||
|  | 	# Return atan2l( self, x ) from libmath | ||||||
|  | 	fun atan_with( x : Int ) : Float `{ | ||||||
|  | 		return atan2( recv, x ); | ||||||
|  | 	`} | ||||||
|  |  | ||||||
|  | 	# This method callback to Nit methods from C code | ||||||
|  | 	# It will use from C code: | ||||||
|  | 	# * the local fib method | ||||||
|  | 	# * the + operator, a method of Int | ||||||
|  | 	# * to_s, a method of all objects | ||||||
|  | 	# * String.to_cstring, a method of String to return an equivalent char* | ||||||
|  | 	fun foo import fib, +, to_s, String.to_cstring `{ | ||||||
|  | 		long recv_fib = Int_fib( recv ); | ||||||
|  | 		long recv_plus_fib = Int__plus( recv, recv_fib ); | ||||||
|  |  | ||||||
|  | 		String nit_string = Int_to_s( recv_plus_fib ); | ||||||
|  | 		char *c_string = String_to_cstring( nit_string ); | ||||||
|  |  | ||||||
|  | 		printf( "from C: self + fib(self) = %s\n", c_string ); | ||||||
|  | 	`} | ||||||
|  |  | ||||||
|  | 	# Equivalent to foo but written in pure Nit | ||||||
|  | 	fun bar do print "from Nit: self + fib(self) = {self+self.fib}" | ||||||
|  | end | ||||||
|  |  | ||||||
|  | print 12.fib | ||||||
|  |  | ||||||
|  | print "sleeping 1 second..." | ||||||
|  | 1.sleep | ||||||
|  |  | ||||||
|  | print 100.atan_with( 200 ) | ||||||
|  | 8.foo | ||||||
|  | 8.bar | ||||||
|  |  | ||||||
							
								
								
									
										43
									
								
								samples/Nit/fibonacci.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								samples/Nit/fibonacci.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # Copyright 2004-2008 Jean Privat <jean@pryen.org> | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | # A simple exemple of refinement where a method is added to the integer class. | ||||||
|  | module fibonacci | ||||||
|  |  | ||||||
|  | redef class Int | ||||||
|  | 	# Calculate the self-th element of the fibonacci sequence. | ||||||
|  | 	fun fibonacci: Int | ||||||
|  | 	do | ||||||
|  | 		if self < 2 then | ||||||
|  | 			return 1 | ||||||
|  | 		else | ||||||
|  | 			return (self-2).fibonacci + (self-1).fibonacci | ||||||
|  | 		end | ||||||
|  | 	end  | ||||||
|  | end | ||||||
|  |  | ||||||
|  | # Print usage and exit. | ||||||
|  | fun usage | ||||||
|  | do | ||||||
|  | 	print "Usage: fibonnaci <integer>"  | ||||||
|  | 	exit 0  | ||||||
|  | end | ||||||
|  |  | ||||||
|  | # Main part | ||||||
|  | if args.length != 1 then | ||||||
|  | 	usage | ||||||
|  | end | ||||||
|  | print args.first.to_i.fibonacci | ||||||
							
								
								
									
										1
									
								
								samples/Nit/hello_world.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								samples/Nit/hello_world.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | print "hello world" | ||||||
							
								
								
									
										105
									
								
								samples/Nit/html_page.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								samples/Nit/html_page.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,105 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | import html | ||||||
|  |  | ||||||
|  | class NitHomepage | ||||||
|  | 	super HTMLPage | ||||||
|  |  | ||||||
|  | 	redef fun head do | ||||||
|  | 		add("meta").attr("charset", "utf-8") | ||||||
|  | 		add("title").text("Nit") | ||||||
|  | 		add("link").attr("rel", "icon").attr("href", "http://nitlanguage.org/favicon.ico").attr("type", "image/x-icon") | ||||||
|  | 		add("link").attr("rel", "stylesheet").attr("href", "http://nitlanguage.org/style.css").attr("type", "text/css") | ||||||
|  | 		add("link").attr("rel", "stylesheet").attr("href", "http://nitlanguage.org/local.css").attr("type", "text/css") | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	redef fun body do | ||||||
|  | 		open("article").add_class("page") | ||||||
|  | 			open("section").add_class("pageheader") | ||||||
|  | 				add_html("<a id='toptitle_first' class='toptitle'>the</a><a id='toptitle_second' class='toptitle' href=''>Nit</a><a id='toptitle_third' class='toptitle' href=''>Programming Language</a>") | ||||||
|  | 				open("header").add_class("header") | ||||||
|  | 					open("div").add_class("topsubtitle") | ||||||
|  | 						add("p").text("A Fun Language for Serious Programming") | ||||||
|  | 					close("div") | ||||||
|  | 				close("header") | ||||||
|  | 			close("section") | ||||||
|  |  | ||||||
|  | 			open("div").attr("id", "pagebody") | ||||||
|  | 				open("section").attr("id", "content") | ||||||
|  | 					add("h1").text("# What is Nit?") | ||||||
|  | 					add("p").text("Nit is an object-oriented programming language. The goal of Nit is to propose a robust statically typed programming language where structure is not a pain.") | ||||||
|  | 					add("p").text("So, what does the famous hello world program look like, in Nit?") | ||||||
|  | 					add_html("<pre><tt><span class='normal'>print </span><span class='string'>'Hello, World!'</span></tt></pre>") | ||||||
|  |  | ||||||
|  | 					add("h1").text("# Feature Highlights") | ||||||
|  | 					add("h2").text("Usability") | ||||||
|  | 					add("p").text("Nit's goal is to be usable by real programmers for real projects") | ||||||
|  |  | ||||||
|  | 					open("ul") | ||||||
|  | 						open("li") | ||||||
|  | 						add("a").attr("href", "http://en.wikipedia.org/wiki/KISS_principle").text("KISS principle") | ||||||
|  | 						close("li") | ||||||
|  | 						add("li").text("Script-like language without verbosity nor cryptic statements") | ||||||
|  | 						add("li").text("Painless static types: static typing should help programmers") | ||||||
|  | 						add("li").text("Efficient development, efficient execution, efficient evolution.") | ||||||
|  | 					close("ul") | ||||||
|  |  | ||||||
|  | 					add("h2").text("Robustness") | ||||||
|  | 					add("p").text("Nit will help you to write bug-free programs") | ||||||
|  |  | ||||||
|  | 					open("ul") | ||||||
|  | 						add("li").text("Strong static typing") | ||||||
|  | 						add("li").text("No more NullPointerException") | ||||||
|  | 					close("ul") | ||||||
|  |  | ||||||
|  | 					add("h2").text("Object-Oriented") | ||||||
|  | 					add("p").text("Nit's guideline is to follow the most powerful OO principles") | ||||||
|  |  | ||||||
|  | 					open("ul") | ||||||
|  | 						open("li") | ||||||
|  | 						add("a").attr("href", "./everything_is_an_object/").text("Everything is an object") | ||||||
|  | 						close("li") | ||||||
|  | 						open("li") | ||||||
|  | 						add("a").attr("href", "./multiple_inheritance/").text("Multiple inheritance") | ||||||
|  | 						close("li") | ||||||
|  | 						open("li") | ||||||
|  | 						add("a").attr("href", "./refinement/").text("Open classes") | ||||||
|  | 						close("li") | ||||||
|  | 						open("li") | ||||||
|  | 						add("a").attr("href", "./virtual_types/").text("Virtual types") | ||||||
|  | 						close("li") | ||||||
|  | 					close("ul") | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 					add("h1").text("# Getting Started") | ||||||
|  | 					add("p").text("Get Nit from its Git repository:") | ||||||
|  |  | ||||||
|  | 					add_html("<pre><code>$ git clone http://nitlanguage.org/nit.git</code></pre>") | ||||||
|  | 					add("p").text("Build the compiler (may be long):") | ||||||
|  | 					add_html("<pre><code>$ cd nit\n") | ||||||
|  | 					add_html("$ make</code></pre>") | ||||||
|  | 					add("p").text("Compile a program:") | ||||||
|  | 					add_html("<pre><code>$ bin/nitc examples/hello_world.nit</code></pre>") | ||||||
|  | 					add("p").text("Execute the program:") | ||||||
|  | 					add_html("<pre><code>$ ./hello_world</code></pre>") | ||||||
|  | 				close("section") | ||||||
|  | 			close("div") | ||||||
|  | 		close("article") | ||||||
|  | 	end | ||||||
|  | end | ||||||
|  |  | ||||||
|  | var page = new NitHomepage | ||||||
|  | page.write_to stdout | ||||||
|  | page.write_to_file("nit.html") | ||||||
							
								
								
									
										100
									
								
								samples/Nit/int_stack.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								samples/Nit/int_stack.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,100 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | # An example that defines and uses stacks of integers. | ||||||
|  | # The implementation is done with a simple linked list. | ||||||
|  | # It features: free constructors, nullable types and some adaptive typing. | ||||||
|  | module int_stack | ||||||
|  |  | ||||||
|  | # A stack of integer implemented by a simple linked list. | ||||||
|  | # Note that this is only a toy class since a real linked list will gain to use | ||||||
|  | # generics and extends interfaces, like Collection, from the standard library. | ||||||
|  | class IntStack | ||||||
|  | 	# The head node of the list. | ||||||
|  | 	# Null means that the stack is empty. | ||||||
|  | 	private var head: nullable ISNode = null | ||||||
|  |  | ||||||
|  | 	# Add a new integer in the stack. | ||||||
|  | 	fun push(val: Int) | ||||||
|  | 	do | ||||||
|  | 		self.head = new ISNode(val, self.head) | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	# Remove and return the last pushed integer. | ||||||
|  | 	# Return null if the stack is empty. | ||||||
|  | 	fun pop: nullable Int | ||||||
|  | 	do | ||||||
|  | 		var head = self.head | ||||||
|  | 		if head == null then return null | ||||||
|  | 		# Note: the followings are statically safe because of the | ||||||
|  | 		# previous 'if'. | ||||||
|  | 		var val = head.val | ||||||
|  | 		self.head = head.next | ||||||
|  | 		return val | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	# Return the sum of all integers of the stack. | ||||||
|  | 	# Return 0 if the stack is empty. | ||||||
|  | 	fun sumall: Int | ||||||
|  | 	do | ||||||
|  | 		var sum = 0 | ||||||
|  | 		var cur = self.head | ||||||
|  | 		while cur != null do | ||||||
|  | 			# Note: the followings are statically safe because of | ||||||
|  | 			# the condition of the 'while'. | ||||||
|  | 			sum += cur.val | ||||||
|  | 			cur = cur.next | ||||||
|  | 		end | ||||||
|  | 		return sum | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	# Note: Because all attributes have a default value, a free constructor | ||||||
|  | 	# "init()" is implicitly defined. | ||||||
|  | end | ||||||
|  |  | ||||||
|  | # A node of a IntStack | ||||||
|  | private class ISNode | ||||||
|  | 	# The integer value stored in the node. | ||||||
|  | 	var val: Int | ||||||
|  |  | ||||||
|  | 	# The next node, if any. | ||||||
|  | 	var next: nullable ISNode | ||||||
|  |  | ||||||
|  | 	# Note: A free constructor "init(val: Int, next: nullable ISNode)" is | ||||||
|  | 	# implicitly defined. | ||||||
|  | end | ||||||
|  |  | ||||||
|  | var l = new IntStack | ||||||
|  | l.push(1) | ||||||
|  | l.push(2) | ||||||
|  | l.push(3) | ||||||
|  |  | ||||||
|  | print l.sumall | ||||||
|  |  | ||||||
|  | # Note: the 'for' control structure cannot be used on IntStack in its current state. | ||||||
|  | # It requires a more advanced topic. | ||||||
|  | # However, why not using the 'loop' control structure? | ||||||
|  | loop | ||||||
|  | 	var i = l.pop | ||||||
|  | 	if i == null then break | ||||||
|  | 	# The following is statically safe because of the previous 'if'. | ||||||
|  | 	print i * 10 | ||||||
|  | end | ||||||
|  |  | ||||||
|  | # Note: 'or else' is used to give an alternative of a null expression. | ||||||
|  | l.push(5) | ||||||
|  | print l.pop or else 0 # l.pop gives 5, so print 5 | ||||||
|  | print l.pop or else 0 # l.pop gives null, so print the alternative: 0 | ||||||
|  |  | ||||||
|  |  | ||||||
							
								
								
									
										193
									
								
								samples/Nit/opengles2_hello_triangle.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										193
									
								
								samples/Nit/opengles2_hello_triangle.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,193 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # Copyright 2014 Alexis Laferrière <alexis.laf@xymus.net> | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | # Basic example of OpenGL ES 2.0 usage from the book OpenGL ES 2.0 Programming Guide. | ||||||
|  | # | ||||||
|  | # Code reference: | ||||||
|  | # https://code.google.com/p/opengles-book-samples/source/browse/trunk/LinuxX11/Chapter_2/Hello_Triangle/Hello_Triangle.c  | ||||||
|  | module opengles2_hello_triangle | ||||||
|  |  | ||||||
|  | import glesv2 | ||||||
|  | import egl | ||||||
|  | import mnit_linux # for sdl | ||||||
|  | import x11 | ||||||
|  |  | ||||||
|  | if "NIT_TESTING".environ == "true" then exit(0) | ||||||
|  |  | ||||||
|  | var window_width = 800 | ||||||
|  | var window_height = 600 | ||||||
|  |  | ||||||
|  | # | ||||||
|  | ## SDL | ||||||
|  | # | ||||||
|  | var sdl_display = new SDLDisplay(window_width, window_height) | ||||||
|  | var sdl_wm_info = new SDLSystemWindowManagerInfo | ||||||
|  | var x11_window_handle = sdl_wm_info.x11_window_handle | ||||||
|  |  | ||||||
|  | # | ||||||
|  | ## X11 | ||||||
|  | # | ||||||
|  | var x_display = x_open_default_display | ||||||
|  | assert x_display != 0 else print "x11 fail" | ||||||
|  |  | ||||||
|  | # | ||||||
|  | ## EGL | ||||||
|  | # | ||||||
|  | var egl_display = new EGLDisplay(x_display) | ||||||
|  | assert egl_display.is_valid else print "EGL display is not valid" | ||||||
|  | egl_display.initialize | ||||||
|  |  | ||||||
|  | print "EGL version: {egl_display.version}" | ||||||
|  | print "EGL vendor: {egl_display.vendor}" | ||||||
|  | print "EGL extensions: {egl_display.extensions.join(", ")}" | ||||||
|  | print "EGL client APIs: {egl_display.client_apis.join(", ")}" | ||||||
|  |  | ||||||
|  | assert egl_display.is_valid else print egl_display.error | ||||||
|  |  | ||||||
|  | var config_chooser = new EGLConfigChooser | ||||||
|  | #config_chooser.surface_type_egl | ||||||
|  | config_chooser.blue_size = 8 | ||||||
|  | config_chooser.green_size = 8 | ||||||
|  | config_chooser.red_size = 8 | ||||||
|  | #config_chooser.alpha_size = 8 | ||||||
|  | #config_chooser.depth_size = 8 | ||||||
|  | #config_chooser.stencil_size = 8 | ||||||
|  | #config_chooser.sample_buffers = 1 | ||||||
|  | config_chooser.close | ||||||
|  |  | ||||||
|  | var configs = config_chooser.choose(egl_display) | ||||||
|  | assert configs != null else print "choosing config failed: {egl_display.error}" | ||||||
|  | assert not configs.is_empty else print "no EGL config" | ||||||
|  |  | ||||||
|  | print "{configs.length} EGL configs available" | ||||||
|  | for config in configs do | ||||||
|  | 	var attribs = config.attribs(egl_display) | ||||||
|  | 	print "* caveats: {attribs.caveat}" | ||||||
|  | 	print "  conformant to: {attribs.conformant}" | ||||||
|  | 	print "  size of RGBA: {attribs.red_size} {attribs.green_size} {attribs.blue_size} {attribs.alpha_size}" | ||||||
|  | 	print "  buffer, depth, stencil: {attribs.buffer_size} {attribs.depth_size} {attribs.stencil_size}" | ||||||
|  | end | ||||||
|  |  | ||||||
|  | var config = configs.first | ||||||
|  |  | ||||||
|  | var format = config.attribs(egl_display).native_visual_id | ||||||
|  |  | ||||||
|  | # TODO android part | ||||||
|  | # Opengles1Display_midway_init(recv, format); | ||||||
|  |  | ||||||
|  | var surface = egl_display.create_window_surface(config, x11_window_handle, [0]) | ||||||
|  | assert surface.is_ok else print egl_display.error | ||||||
|  |  | ||||||
|  | var context = egl_display.create_context(config) | ||||||
|  | assert context.is_ok else print egl_display.error | ||||||
|  |  | ||||||
|  | var make_current_res = egl_display.make_current(surface, surface, context) | ||||||
|  | assert make_current_res | ||||||
|  |  | ||||||
|  | var width = surface.attribs(egl_display).width | ||||||
|  | var height = surface.attribs(egl_display).height | ||||||
|  | print "Width: {width}" | ||||||
|  | print "Height: {height}" | ||||||
|  |  | ||||||
|  | assert egl_bind_opengl_es_api else print "eglBingAPI failed: {egl_display.error}" | ||||||
|  |  | ||||||
|  | # | ||||||
|  | ## GLESv2 | ||||||
|  | # | ||||||
|  |  | ||||||
|  | print "Can compile shaders? {gl_shader_compiler}" | ||||||
|  | assert_no_gl_error | ||||||
|  |  | ||||||
|  | assert gl_shader_compiler else print "Cannot compile shaders" | ||||||
|  |  | ||||||
|  | # gl program | ||||||
|  | print gl_error.to_s | ||||||
|  | var program = new GLProgram | ||||||
|  | if not program.is_ok then | ||||||
|  | 	print "Program is not ok: {gl_error.to_s}\nLog:" | ||||||
|  | 	print program.info_log | ||||||
|  | 	abort | ||||||
|  | end | ||||||
|  | assert_no_gl_error | ||||||
|  |  | ||||||
|  | # vertex shader | ||||||
|  | var vertex_shader = new GLVertexShader | ||||||
|  | assert vertex_shader.is_ok else print "Vertex shader is not ok: {gl_error}" | ||||||
|  | vertex_shader.source = """ | ||||||
|  | attribute vec4 vPosition;    | ||||||
|  | void main()                  | ||||||
|  | {                            | ||||||
|  |   gl_Position = vPosition;   | ||||||
|  | }                           """ | ||||||
|  | vertex_shader.compile | ||||||
|  | assert vertex_shader.is_compiled else print "Vertex shader compilation failed with: {vertex_shader.info_log} {program.info_log}" | ||||||
|  | assert_no_gl_error | ||||||
|  |  | ||||||
|  | # fragment shader | ||||||
|  | var fragment_shader = new GLFragmentShader | ||||||
|  | assert fragment_shader.is_ok else print "Fragment shader is not ok: {gl_error}" | ||||||
|  | fragment_shader.source = """ | ||||||
|  | precision mediump float; | ||||||
|  | void main() | ||||||
|  | { | ||||||
|  | 	gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); | ||||||
|  | } | ||||||
|  | """ | ||||||
|  | fragment_shader.compile | ||||||
|  | assert fragment_shader.is_compiled else print "Fragment shader compilation failed with: {fragment_shader.info_log}" | ||||||
|  | assert_no_gl_error | ||||||
|  |  | ||||||
|  | program.attach_shader vertex_shader | ||||||
|  | program.attach_shader fragment_shader | ||||||
|  | program.bind_attrib_location(0, "vPosition") | ||||||
|  | program.link | ||||||
|  | assert program.is_linked else print "Linking failed: {program.info_log}" | ||||||
|  | assert_no_gl_error | ||||||
|  |  | ||||||
|  | # draw! | ||||||
|  | var vertices = [0.0, 0.5, 0.0, -0.5, -0.5, 0.0, 0.5, -0.5, 0.0] | ||||||
|  | var vertex_array = new VertexArray(0, 3, vertices) | ||||||
|  | vertex_array.attrib_pointer | ||||||
|  | gl_clear_color(0.5, 0.0, 0.5, 1.0) | ||||||
|  | for i in [0..10000[ do | ||||||
|  | 	printn "." | ||||||
|  | 	assert_no_gl_error | ||||||
|  | 	gl_viewport(0, 0, width, height) | ||||||
|  | 	gl_clear_color_buffer | ||||||
|  | 	program.use | ||||||
|  | 	vertex_array.enable | ||||||
|  | 	vertex_array.draw_arrays_triangles | ||||||
|  | 	egl_display.swap_buffers(surface) | ||||||
|  | end | ||||||
|  |  | ||||||
|  | # delete | ||||||
|  | program.delete | ||||||
|  | vertex_shader.delete | ||||||
|  | fragment_shader.delete | ||||||
|  |  | ||||||
|  | # | ||||||
|  | ## EGL | ||||||
|  | # | ||||||
|  | # close | ||||||
|  | egl_display.make_current(new EGLSurface.none, new EGLSurface.none, new EGLContext.none) | ||||||
|  | egl_display.destroy_context(context) | ||||||
|  | egl_display.destroy_surface(surface) | ||||||
|  |  | ||||||
|  | # | ||||||
|  | ## SDL | ||||||
|  | # | ||||||
|  | # close | ||||||
|  | sdl_display.destroy | ||||||
							
								
								
									
										22
									
								
								samples/Nit/print_arguments.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								samples/Nit/print_arguments.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # Copyright 2004-2008 Jean Privat <jean@pryen.org> | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | # How to print arguments of the command line. | ||||||
|  | module print_arguments | ||||||
|  |  | ||||||
|  | for a in args do | ||||||
|  | 	print a | ||||||
|  | end | ||||||
							
								
								
									
										48
									
								
								samples/Nit/procedural_array.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								samples/Nit/procedural_array.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # Copyright 2004-2008 Jean Privat <jean@pryen.org> | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | # A procedural program (without explicit class definition). | ||||||
|  | # This program manipulates arrays of integers. | ||||||
|  | module procedural_array | ||||||
|  |  | ||||||
|  | # The sum of the elements of `a'. | ||||||
|  | # Uses a 'for' control structure. | ||||||
|  | fun array_sum(a: Array[Int]): Int | ||||||
|  | do | ||||||
|  | 	var sum = 0 | ||||||
|  | 	for i in a do | ||||||
|  | 		sum = sum + i | ||||||
|  | 	end | ||||||
|  | 	return sum | ||||||
|  | end | ||||||
|  |  | ||||||
|  | # The sum of the elements of `a' (alternative version). | ||||||
|  | # Uses a 'while' control structure. | ||||||
|  | fun array_sum_alt(a: Array[Int]): Int | ||||||
|  | do | ||||||
|  | 	var sum = 0 | ||||||
|  | 	var i = 0 | ||||||
|  | 	while i < a.length do | ||||||
|  | 		sum = sum + a[i] | ||||||
|  | 		i = i + 1 | ||||||
|  | 	end | ||||||
|  | 	return sum | ||||||
|  | end | ||||||
|  |  | ||||||
|  | # The main part of the program. | ||||||
|  | var a = [10, 5, 8, 9] | ||||||
|  | print(array_sum(a)) | ||||||
|  | print(array_sum_alt(a)) | ||||||
							
								
								
									
										38
									
								
								samples/Nit/socket_client.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								samples/Nit/socket_client.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # Copyright 2013 Matthieu Lucas <lucasmatthieu@gmail.com> | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | # Client sample using the Socket module which connect to the server sample. | ||||||
|  | module socket_client | ||||||
|  |  | ||||||
|  | import socket | ||||||
|  |  | ||||||
|  | if args.length < 2 then | ||||||
|  | 	print "Usage : socket_client <host> <port>" | ||||||
|  | 	return | ||||||
|  | end | ||||||
|  |  | ||||||
|  | var s = new Socket.client(args[0], args[1].to_i) | ||||||
|  | print "[HOST ADDRESS] : {s.address}" | ||||||
|  | print "[HOST] : {s.host}" | ||||||
|  | print "[PORT] : {s.port}" | ||||||
|  | print "Connecting ... {s.connected}" | ||||||
|  | if s.connected then | ||||||
|  | 	print "Writing ... Hello server !" | ||||||
|  | 	s.write("Hello server !") | ||||||
|  | 	print "[Response from server] : {s.read(100)}" | ||||||
|  | 	print "Closing ..." | ||||||
|  | 	s.close | ||||||
|  | end | ||||||
							
								
								
									
										52
									
								
								samples/Nit/socket_server.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								samples/Nit/socket_server.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # Copyright 2013 Matthieu Lucas <lucasmatthieu@gmail.com> | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | # Server sample using the Socket module which allow client to connect | ||||||
|  | module socket_server | ||||||
|  |  | ||||||
|  | import socket | ||||||
|  |  | ||||||
|  | if args.is_empty then | ||||||
|  | 	print "Usage : socket_server <port>" | ||||||
|  | 	return | ||||||
|  | end | ||||||
|  |  | ||||||
|  | var socket = new Socket.server(args[0].to_i, 1) | ||||||
|  | print "[PORT] : {socket.port.to_s}" | ||||||
|  |  | ||||||
|  | var clients = new Array[Socket] | ||||||
|  | var max = socket | ||||||
|  | loop | ||||||
|  | 	var fs = new SocketObserver(true, true, true) | ||||||
|  | 	fs.readset.set(socket) | ||||||
|  |  | ||||||
|  | 	for c in clients do fs.readset.set(c) | ||||||
|  |  | ||||||
|  | 	if fs.select(max, 4, 0) == 0 then | ||||||
|  | 		print "Error occured in select {sys.errno.strerror}" | ||||||
|  | 		break | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	if fs.readset.is_set(socket) then | ||||||
|  | 		var ns = socket.accept | ||||||
|  | 		print "Accepting {ns.address} ... " | ||||||
|  | 		print "[Message from {ns.address}] : {ns.read(100)}" | ||||||
|  | 		ns.write("Goodbye client.") | ||||||
|  | 		print "Closing {ns.address} ..." | ||||||
|  | 		ns.close | ||||||
|  | 	end | ||||||
|  | end | ||||||
|  |  | ||||||
							
								
								
									
										94
									
								
								samples/Nit/tmpl_composer.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								samples/Nit/tmpl_composer.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,94 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | import template | ||||||
|  |  | ||||||
|  | ### Here, definition of the specific templates | ||||||
|  |  | ||||||
|  | # The root template for composers | ||||||
|  | class TmplComposers | ||||||
|  | 	super Template | ||||||
|  |  | ||||||
|  | 	# Short list of composers | ||||||
|  | 	var composers = new Array[TmplComposer] | ||||||
|  |  | ||||||
|  | 	# Detailled list of composers | ||||||
|  | 	var composer_details = new Array[TmplComposerDetail] | ||||||
|  |  | ||||||
|  | 	# Add a composer in both lists | ||||||
|  | 	fun add_composer(firstname, lastname: String, birth, death: Int) | ||||||
|  | 	do | ||||||
|  | 		composers.add(new TmplComposer(lastname)) | ||||||
|  | 		composer_details.add(new TmplComposerDetail(firstname, lastname, birth, death)) | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	redef fun rendering do | ||||||
|  | 		add """ | ||||||
|  | COMPOSERS | ||||||
|  | ========= | ||||||
|  | """ | ||||||
|  | 		add_all composers | ||||||
|  | 		add """ | ||||||
|  |  | ||||||
|  | DETAILS | ||||||
|  | ======= | ||||||
|  | """ | ||||||
|  | 		add_all composer_details | ||||||
|  | 	end | ||||||
|  | end | ||||||
|  |  | ||||||
|  | # A composer in the short list of composers | ||||||
|  | class TmplComposer | ||||||
|  | 	super Template | ||||||
|  |  | ||||||
|  | 	# Short name | ||||||
|  | 	var name: String | ||||||
|  |  | ||||||
|  | 	init(name: String) do self.name = name | ||||||
|  |  | ||||||
|  | 	redef fun rendering do add "- {name}\n" | ||||||
|  | end | ||||||
|  |  | ||||||
|  | # A composer in the detailled list of composers | ||||||
|  | class TmplComposerDetail | ||||||
|  | 	super Template | ||||||
|  |  | ||||||
|  | 	var firstname: String | ||||||
|  | 	var lastname: String | ||||||
|  | 	var birth: Int | ||||||
|  | 	var death: Int | ||||||
|  |  | ||||||
|  | 	init(firstname, lastname: String, birth, death: Int) do | ||||||
|  | 		self.firstname = firstname | ||||||
|  | 		self.lastname = lastname | ||||||
|  | 		self.birth = birth | ||||||
|  | 		self.death = death | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	redef fun rendering do add """ | ||||||
|  |  | ||||||
|  | COMPOSER: {{{firstname}}} {{{lastname}}} | ||||||
|  | BIRTH...: {{{birth}}} | ||||||
|  | DEATH...: {{{death}}} | ||||||
|  | """ | ||||||
|  |  | ||||||
|  | end | ||||||
|  |  | ||||||
|  | ### Here a simple usage of the templates | ||||||
|  |  | ||||||
|  | var f = new TmplComposers | ||||||
|  | f.add_composer("Johann Sebastian", "Bach", 1685, 1750) | ||||||
|  | f.add_composer("George Frideric", "Handel", 1685, 1759) | ||||||
|  | f.add_composer("Wolfgang Amadeus", "Mozart", 1756, 1791) | ||||||
|  | f.write_to(stdout) | ||||||
							
								
								
									
										46
									
								
								samples/Nit/websocket_server.nit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								samples/Nit/websocket_server.nit
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | |||||||
|  | # This file is part of NIT ( http://www.nitlanguage.org ). | ||||||
|  | # | ||||||
|  | # Copyright 2014 Lucas Bajolet <r4pass@hotmail.com> | ||||||
|  | # | ||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | # Sample module for a minimal chat server using Websockets on port 8088 | ||||||
|  | module websocket_server | ||||||
|  |  | ||||||
|  | import websocket | ||||||
|  |  | ||||||
|  | var sock = new WebSocket(8088, 1) | ||||||
|  |  | ||||||
|  | var msg: String | ||||||
|  |  | ||||||
|  | if sock.listener.eof then | ||||||
|  | 	print sys.errno.strerror | ||||||
|  | end | ||||||
|  |  | ||||||
|  | sock.accept | ||||||
|  |  | ||||||
|  | while not sock.listener.eof do | ||||||
|  | 	if not sock.connected then sock.accept | ||||||
|  | 	if sys.stdin.poll_in then | ||||||
|  | 		msg = gets | ||||||
|  | 		printn "Received message : {msg}" | ||||||
|  | 		if msg == "exit" then sock.close | ||||||
|  | 		if msg == "disconnect" then sock.disconnect_client | ||||||
|  | 		sock.write(msg) | ||||||
|  | 	end | ||||||
|  | 	if sock.can_read(10) then | ||||||
|  | 		msg = sock.read_line | ||||||
|  | 		if msg != "" then print msg | ||||||
|  | 	end | ||||||
|  | end | ||||||
|  |  | ||||||
							
								
								
									
										80
									
								
								samples/Nix/nginx.nix
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								samples/Nix/nginx.nix
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,80 @@ | |||||||
|  | { stdenv, fetchurl, fetchgit, openssl, zlib, pcre, libxml2, libxslt, expat | ||||||
|  | , rtmp ? false | ||||||
|  | , fullWebDAV ? false | ||||||
|  | , syslog ? false | ||||||
|  | , moreheaders ? false, ...}: | ||||||
|  |  | ||||||
|  | let | ||||||
|  |   version = "1.4.4"; | ||||||
|  |   mainSrc = fetchurl { | ||||||
|  |     url = "http://nginx.org/download/nginx-${version}.tar.gz"; | ||||||
|  |     sha256 = "1f82845mpgmhvm151fhn2cnqjggw9w7cvsqbva9rb320wmc9m63w"; | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   rtmp-ext = fetchgit { | ||||||
|  |     url = git://github.com/arut/nginx-rtmp-module.git; | ||||||
|  |     rev = "1cfb7aeb582789f3b15a03da5b662d1811e2a3f1"; | ||||||
|  |     sha256 = "03ikfd2l8mzsjwx896l07rdrw5jn7jjfdiyl572yb9jfrnk48fwi"; | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   dav-ext = fetchgit { | ||||||
|  |     url = git://github.com/arut/nginx-dav-ext-module.git; | ||||||
|  |     rev = "54cebc1f21fc13391aae692c6cce672fa7986f9d"; | ||||||
|  |     sha256 = "1dvpq1fg5rslnl05z8jc39sgnvh3akam9qxfl033akpczq1bh8nq"; | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   syslog-ext = fetchgit { | ||||||
|  |     url = https://github.com/yaoweibin/nginx_syslog_patch.git; | ||||||
|  |     rev = "165affd9741f0e30c4c8225da5e487d33832aca3"; | ||||||
|  |     sha256 = "14dkkafjnbapp6jnvrjg9ip46j00cr8pqc2g7374z9aj7hrvdvhs"; | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   moreheaders-ext = fetchgit { | ||||||
|  |     url = https://github.com/agentzh/headers-more-nginx-module.git; | ||||||
|  |     rev = "refs/tags/v0.23"; | ||||||
|  |     sha256 = "12pbjgsxnvcf2ff2i2qdn39q4cm5czlgrng96j8ml4cgxvnbdh39"; | ||||||
|  |   }; | ||||||
|  | in | ||||||
|  |  | ||||||
|  | stdenv.mkDerivation rec { | ||||||
|  |   name = "nginx-${version}"; | ||||||
|  |   src = mainSrc; | ||||||
|  |  | ||||||
|  |   buildInputs = [ openssl zlib pcre libxml2 libxslt | ||||||
|  |     ] ++ stdenv.lib.optional fullWebDAV expat; | ||||||
|  |  | ||||||
|  |   patches = if syslog then [ "${syslog-ext}/syslog_1.4.0.patch" ] else []; | ||||||
|  |  | ||||||
|  |   configureFlags = [ | ||||||
|  |     "--with-http_ssl_module" | ||||||
|  |     "--with-http_spdy_module" | ||||||
|  |     "--with-http_xslt_module" | ||||||
|  |     "--with-http_sub_module" | ||||||
|  |     "--with-http_dav_module" | ||||||
|  |     "--with-http_gzip_static_module" | ||||||
|  |     "--with-http_secure_link_module" | ||||||
|  |     "--with-ipv6" | ||||||
|  |     # Install destination problems | ||||||
|  |     # "--with-http_perl_module" | ||||||
|  |   ] ++ stdenv.lib.optional rtmp "--add-module=${rtmp-ext}" | ||||||
|  |     ++ stdenv.lib.optional fullWebDAV "--add-module=${dav-ext}" | ||||||
|  |     ++ stdenv.lib.optional syslog "--add-module=${syslog-ext}" | ||||||
|  |     ++ stdenv.lib.optional moreheaders "--add-module=${moreheaders-ext}"; | ||||||
|  |  | ||||||
|  |   preConfigure = '' | ||||||
|  |     export NIX_CFLAGS_COMPILE="$NIX_CFLAGS_COMPILE -I${libxml2 }/include/libxml2" | ||||||
|  |   ''; | ||||||
|  |  | ||||||
|  |   # escape example | ||||||
|  |   postInstall = '' | ||||||
|  |     mv $out/sbin $out/bin ''' ''${ | ||||||
|  |    ${ if true then ${ "" } else false } | ||||||
|  |   ''; | ||||||
|  |  | ||||||
|  |   meta = { | ||||||
|  |     description = "A reverse proxy and lightweight webserver"; | ||||||
|  |     maintainers = [ stdenv.lib.maintainers.raskin]; | ||||||
|  |     platforms = stdenv.lib.platforms.all; | ||||||
|  |     inherit version; | ||||||
|  |   }; | ||||||
|  | } | ||||||
							
								
								
									
										72
									
								
								samples/Ox/IJCEmet2009.oxh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								samples/Ox/IJCEmet2009.oxh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,72 @@ | |||||||
|  | /** Replicate Imai, Jain and Ching Econometrica 2009 (incomplete). | ||||||
|  |  | ||||||
|  | **/ | ||||||
|  | #include "IJCEmet2009.h" | ||||||
|  |  | ||||||
|  | Kapital::Kapital(L,const N,const entrant,const exit,const KP){ | ||||||
|  | 	StateVariable(L,N); | ||||||
|  | 	this.entrant = entrant; | ||||||
|  | 	this.exit = exit; | ||||||
|  | 	this.KP = KP; | ||||||
|  | 	actual = Kbar*vals/(N-1); | ||||||
|  | 	upper = log(actual~.Inf); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | Kapital::Transit(FeasA) { | ||||||
|  | 	decl ent =CV(entrant), stayout = FeasA[][exit.pos], tprob, sigu = CV(KP[SigU]); | ||||||
|  | 	if (!v && !ent) return { <0>, ones(stayout) }; | ||||||
|  | 	tprob = ent ? probn( (upper-CV(KP[Kbe]))/sigu ) | ||||||
|  | 	           : probn( (upper-(CV(KP[Kb0])+CV(KP[Kb2])*upper[v])) / sigu ); | ||||||
|  | 	tprob = tprob[1:] - tprob[:N-1]; | ||||||
|  | 	return { vals, tprob.*(1-stayout)+(1.0~zeros(1,N-1)).*stayout }; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | FirmEntry::Run() { | ||||||
|  | 	Initialize(); | ||||||
|  | 	GenerateSample(); | ||||||
|  | 	BDP->BayesianDP(); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | FirmEntry::Initialize() { | ||||||
|  | 	Rust::Initialize(Reachable,0); | ||||||
|  | 	sige = new StDeviations("sige",<0.3,0.3>,0); | ||||||
|  | 	entrant = new LaggedAction("entrant",d); | ||||||
|  | 	KP = new array[Kparams]; | ||||||
|  | 		KP[Kbe] = new Positive("be",0.5); | ||||||
|  | 		KP[Kb0] = new Free("b0",0.0); | ||||||
|  | 		KP[Kb1] = new Determined("b1",0.0); | ||||||
|  | 		KP[Kb2] = new Positive("b2",0.4); | ||||||
|  | 		KP[SigU] = new Positive("sigu",0.4); | ||||||
|  | 	EndogenousStates(K = new Kapital("K",KN,entrant,d,KP),entrant); | ||||||
|  | 	SetDelta(new Probability("delta",0.85)); | ||||||
|  | 	kcoef = new Positive("kcoef",0.1); | ||||||
|  | 	ecost = new Negative("ec",-0.4); | ||||||
|  | 	CreateSpaces(); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | FirmEntry::GenerateSample() { | ||||||
|  | 	Volume = LOUD; | ||||||
|  | 	EM = new ValueIteration(0); | ||||||
|  | //	EM -> Solve(0,0); | ||||||
|  | 	data = new DataSet(0,EM); | ||||||
|  | 	data->Simulate(DataN,DataT,0,FALSE); | ||||||
|  | 	data->Print("firmentry.xls"); | ||||||
|  | 	BDP = new ImaiJainChing("FMH",data,EM,ecost,sige,kcoef,KP,delta); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | /** Capital stock can be positive only for incumbents. | ||||||
|  | **/ | ||||||
|  | FirmEntry::Reachable()	{ return CV(entrant)*CV(K) ? 0 : new FirmEntry() ;	} | ||||||
|  |  | ||||||
|  | /** The one period return. | ||||||
|  | <DD> | ||||||
|  | <pre>U = </pre> | ||||||
|  | </DD> | ||||||
|  | **/ | ||||||
|  | FirmEntry::Utility()  { | ||||||
|  | 	decl ent = CV(entrant), | ||||||
|  | 		 u = | ||||||
|  | 		     ent*CV(ecost)+(1-ent)*CV(kcoef)*AV(K) | ||||||
|  | 		   | 0.0; | ||||||
|  | 	return u; | ||||||
|  | 	} | ||||||
							
								
								
									
										63
									
								
								samples/Ox/ParallelObjective.ox
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								samples/Ox/ParallelObjective.ox
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,63 @@ | |||||||
|  | /** Client and Server classes for parallel optimization using CFMPI.**/ | ||||||
|  | #include "ParallelObjective.h" | ||||||
|  |  | ||||||
|  | /** Set up MPI Client-Server support for objective optimization. | ||||||
|  | @param obj `Objective' to parallelize | ||||||
|  | @param DONOTUSECLIENT TRUE (default): client node does no object evaluation<br>FALSE after putting servers to work Client node does one evaluation. | ||||||
|  | **/ | ||||||
|  | ParallelObjective(obj,DONOTUSECLIENT) { | ||||||
|  | 	if (isclass(obj.p2p)) {oxwarning("P2P object already exists for "+obj.L+". Nothing changed"); return;} | ||||||
|  | 	obj.p2p = new P2P(DONOTUSECLIENT,new ObjClient(obj),new ObjServer(obj)); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | ObjClient::ObjClient(obj) { this.obj = obj;    } | ||||||
|  |  | ||||||
|  | ObjClient::Execute() {    } | ||||||
|  |  | ||||||
|  | ObjServer::ObjServer(obj) { | ||||||
|  |     this.obj = obj; | ||||||
|  |     basetag = P2P::STOP_TAG+1; | ||||||
|  |     iml = obj.NvfuncTerms; | ||||||
|  |     Nparams = obj.nstruct; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | /** Wait on the objective client. | ||||||
|  | **/ | ||||||
|  | ObjServer::Loop(nxtmsgsz) { | ||||||
|  |     Nparams = nxtmsgsz;   //free param length is no greater than Nparams | ||||||
|  |     if (Volume>QUIET) println("ObjServer server ",ID," Nparams ",Nparams); | ||||||
|  |     Server::Loop(Nparams); | ||||||
|  |     Recv(ANY_TAG);                      //receive the ending parameter vector | ||||||
|  |     obj->Encode(Buffer[:Nparams-1]);   //encode it. | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | /** Do the objective evaluation. | ||||||
|  | Receive structural parameter vector and `Objective::Encode`() it. | ||||||
|  | Call `Objective::vfunc`(). | ||||||
|  | @return Nparams (max. length of next expected message); | ||||||
|  | **/ | ||||||
|  | ObjServer::Execute() { | ||||||
|  | 	obj->Decode(Buffer[:obj.nfree-1]); | ||||||
|  | 	Buffer = obj.cur.V[] = obj->vfunc(); | ||||||
|  |     if (Volume>QUIET) println("Server Executive: ",ID," vfunc[0]= ",Buffer[0]); | ||||||
|  | 	return obj.nstruct; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | CstrServer::CstrServer(obj) { ObjServer(obj);	} | ||||||
|  |  | ||||||
|  | SepServer::SepServer(obj) { ObjServer(obj);	} | ||||||
|  |  | ||||||
|  | CstrServer::Execute() { | ||||||
|  | 	obj->Encode(Buffer); | ||||||
|  | 	obj->Lagrangian(0); | ||||||
|  | 	return rows(Buffer = obj.cur->Vec()); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | /** Separable objective evaluations. | ||||||
|  | **/ | ||||||
|  | SepServer::Execute() { | ||||||
|  | 	obj.Kvar.v = imod(Tag-basetag,obj.K); | ||||||
|  | 	obj->Encode(Buffer,TRUE); | ||||||
|  | 	Buffer = obj.Kvar->PDF() * obj->vfunc(); | ||||||
|  | 	return obj.NvfuncTerms; | ||||||
|  | 	} | ||||||
							
								
								
									
										38
									
								
								samples/Ox/particle.oxo
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								samples/Ox/particle.oxo
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | |||||||
|  | nldge::ParticleLogLikeli() | ||||||
|  | {	decl it, ip, | ||||||
|  | 		 mss, mbas, ms, my, mx, vw, vwi, dws, | ||||||
|  | 		 mhi, mhdet, loglikeli, mData, | ||||||
|  | 		 vxm, vxs, mxm=<>, mxsu=<>, mxsl=<>, | ||||||
|  | 		 time, timeall, timeran=0, timelik=0, timefun=0, timeint=0, timeres=0; | ||||||
|  |  | ||||||
|  | 	mData = GetData(m_asY); | ||||||
|  | 	mhdet = sqrt((2*M_PI)^m_cY * determinant(m_mMSbE.^2));		// covariance determinant | ||||||
|  | 	mhi   = invert(m_mMSbE.^2);					// invert covariance of measurement shocks | ||||||
|  |  | ||||||
|  | 	ms 	  = m_vSss + zeros(m_cPar, m_cS);			// start particles | ||||||
|  | 	mx 	  = m_vXss + zeros(m_cPar, m_cX);			// steady state of state and policy | ||||||
|  |  | ||||||
|  | 	loglikeli = 0;							// init likelihood | ||||||
|  | 																								//timeall=timer(); | ||||||
|  | 	for(it = 0; it < sizer(mData); it++) | ||||||
|  | 	{ | ||||||
|  | 		mss = rann(m_cPar, m_cSS) * m_mSSbE;			// state noise | ||||||
|  | 		fg(&ms, ms, mx, mss);					// transition prior as proposal | ||||||
|  | 		mx = m_oApprox.FastInterpolate(ms); 			// interpolate | ||||||
|  | 		fy(&my, ms, mx, zeros(m_cPar, m_cMS));			// evaluate importance weights | ||||||
|  | 		my -= mData[it][];					// observation error | ||||||
|  |  | ||||||
|  | 		vw = exp(-0.5 * outer(my,mhi,'d')' )/mhdet;		// vw = exp(-0.5 * sumr(my*mhi .*my ) )/mhdet; | ||||||
|  |  | ||||||
|  | 		vw = vw .== .NaN .? 0 .: vw;				// no policy can happen for extrem particles | ||||||
|  | 		dws = sumc(vw); | ||||||
|  | 		if(dws==0) return -.Inf;				// or extremely wrong parameters | ||||||
|  | 		loglikeli += log(dws/m_cPar)	;			// loglikelihood contribution | ||||||
|  | 																										//timelik += (timer()-time)/100; | ||||||
|  | 																										//time=timer(); | ||||||
|  | 		vwi = resample(vw/dws)-1;				// selection step in c++ | ||||||
|  | 		ms = ms[vwi][];						// on normalized weights | ||||||
|  | 		mx = mx[vwi][]; | ||||||
|  | 																	} | ||||||
|  | 	return loglikeli; | ||||||
|  | } | ||||||
							
								
								
									
										34
									
								
								samples/PHP/filenames/.php
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										34
									
								
								samples/PHP/filenames/.php
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,34 @@ | |||||||
|  | #!/usr/bin/env php | ||||||
|  | <? | ||||||
|  | $aMenuLinks = Array( | ||||||
|  | 	Array( | ||||||
|  | 		"Blog",  | ||||||
|  | 		SITE_DIR,  | ||||||
|  | 		Array(),  | ||||||
|  | 		Array(),  | ||||||
|  | 		""  | ||||||
|  | 	), | ||||||
|  | 	Array( | ||||||
|  | 		"Photos",  | ||||||
|  | 		SITE_DIR."photo/",  | ||||||
|  | 		Array(),  | ||||||
|  | 		Array(),  | ||||||
|  | 		""  | ||||||
|  | 	), | ||||||
|  | 	Array( | ||||||
|  | 		"About me",  | ||||||
|  | 		SITE_DIR."about.php",  | ||||||
|  | 		Array(),  | ||||||
|  | 		Array(),  | ||||||
|  | 		""  | ||||||
|  | 	), | ||||||
|  | 	Array( | ||||||
|  | 		"Contact",  | ||||||
|  | 		SITE_DIR."contacts.php",  | ||||||
|  | 		Array(),  | ||||||
|  | 		Array(),  | ||||||
|  | 		""  | ||||||
|  | 	), | ||||||
|  |  | ||||||
|  | ); | ||||||
|  | ?> | ||||||
							
								
								
									
										54
									
								
								samples/Pan/test.pan
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								samples/Pan/test.pan
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,54 @@ | |||||||
|  | object template pantest; | ||||||
|  |  | ||||||
|  | # Very simple pan test file | ||||||
|  | "/long/decimal" = 123; | ||||||
|  | "/long/octal" = 0755; | ||||||
|  | "/long/hexadecimal" = 0xFF; | ||||||
|  |  | ||||||
|  | "/double/simple" = 0.01; | ||||||
|  | "/double/pi" = 3.14159; | ||||||
|  | "/double/exponent" = 1e-8; | ||||||
|  | "/double/scientific" = 1.3E10; | ||||||
|  |  | ||||||
|  | "/string/single" = 'Faster, but escapes like \t, \n and \x3d don''t work, but '' should work.'; | ||||||
|  | "/string/double" = "Slower, but escapes like \t, \n and \x3d do work"; | ||||||
|  |  | ||||||
|  | variable TEST = 2; | ||||||
|  |  | ||||||
|  | "/x2" = to_string(TEST); | ||||||
|  | "/x2" ?= 'Default value'; | ||||||
|  |  | ||||||
|  | "/x3" = 1 + 2 + value("/long/decimal"); | ||||||
|  |  | ||||||
|  | "/x4" = undef; | ||||||
|  |  | ||||||
|  | "/x5" = null; | ||||||
|  |  | ||||||
|  | variable e ?= error("Test error message"); | ||||||
|  |  | ||||||
|  | # include gmond config for services-monitoring | ||||||
|  | include { 'site/ganglia/gmond/services-monitoring' }; | ||||||
|  |  | ||||||
|  | "/software/packages"=pkg_repl("httpd","2.2.3-43.sl5.3",PKG_ARCH_DEFAULT); | ||||||
|  | "/software/packages"=pkg_repl("php"); | ||||||
|  |  | ||||||
|  | # Example function | ||||||
|  | function show_things_view_for_stuff = { | ||||||
|  |     thing = ARGV[0]; | ||||||
|  |     foreach( i; mything; STUFF ) { | ||||||
|  |         if ( thing == mything ) { | ||||||
|  |             return( true ); | ||||||
|  |         } else { | ||||||
|  |             return SELF; | ||||||
|  |         }; | ||||||
|  |     }; | ||||||
|  |     false; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | variable HERE = <<EOF; | ||||||
|  | ; This example demonstrates an in-line heredoc style config file | ||||||
|  | [main] | ||||||
|  | awesome = true | ||||||
|  | EOF | ||||||
|  |  | ||||||
|  | variable small = false;#This should be highlighted normally again. | ||||||
							
								
								
									
										38
									
								
								samples/Pike/Error.pmod
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								samples/Pike/Error.pmod
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | |||||||
|  | #pike __REAL_VERSION__ | ||||||
|  |  | ||||||
|  | constant Generic = __builtin.GenericError; | ||||||
|  |  | ||||||
|  | constant Index = __builtin.IndexError; | ||||||
|  |  | ||||||
|  | constant BadArgument = __builtin.BadArgumentError; | ||||||
|  |  | ||||||
|  | constant Math = __builtin.MathError; | ||||||
|  |  | ||||||
|  | constant Resource = __builtin.ResourceError; | ||||||
|  |  | ||||||
|  | constant Permission = __builtin.PermissionError; | ||||||
|  |  | ||||||
|  | constant Decode = __builtin.DecodeError; | ||||||
|  |  | ||||||
|  | constant Cpp = __builtin.CppError; | ||||||
|  |  | ||||||
|  | constant Compilation = __builtin.CompilationError; | ||||||
|  |  | ||||||
|  | constant MasterLoad = __builtin.MasterLoadError; | ||||||
|  |  | ||||||
|  | constant ModuleLoad = __builtin.ModuleLoadError; | ||||||
|  |  | ||||||
|  | //! Returns an Error object for any argument it receives. If the | ||||||
|  | //! argument already is an Error object or is empty, it does nothing. | ||||||
|  | object mkerror(mixed error) | ||||||
|  | { | ||||||
|  |   if (error == UNDEFINED) | ||||||
|  |     return error; | ||||||
|  |   if (objectp(error) && error->is_generic_error) | ||||||
|  |     return error; | ||||||
|  |   if (arrayp(error)) | ||||||
|  |     return Error.Generic(@error); | ||||||
|  |   if (stringp(error)) | ||||||
|  |     return Error.Generic(error); | ||||||
|  |   return Error.Generic(sprintf("%O", error)); | ||||||
|  | } | ||||||
							
								
								
									
										360
									
								
								samples/Pike/FakeFile.pike
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										360
									
								
								samples/Pike/FakeFile.pike
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,360 @@ | |||||||
|  | #pike __REAL_VERSION__ | ||||||
|  |  | ||||||
|  | //! A string wrapper that pretends to be a @[Stdio.File] object | ||||||
|  | //! in addition to some features of a @[Stdio.FILE] object. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | //! This constant can be used to distinguish a FakeFile object | ||||||
|  | //! from a real @[Stdio.File] object. | ||||||
|  | constant is_fake_file = 1; | ||||||
|  |  | ||||||
|  | protected string data; | ||||||
|  | protected int ptr; | ||||||
|  | protected int(0..1) r; | ||||||
|  | protected int(0..1) w; | ||||||
|  | protected int mtime; | ||||||
|  |  | ||||||
|  | protected function read_cb; | ||||||
|  | protected function read_oob_cb; | ||||||
|  | protected function write_cb; | ||||||
|  | protected function write_oob_cb; | ||||||
|  | protected function close_cb; | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->close()] | ||||||
|  | int close(void|string direction) { | ||||||
|  |   direction = lower_case(direction||"rw"); | ||||||
|  |   int cr = has_value(direction, "r"); | ||||||
|  |   int cw = has_value(direction, "w"); | ||||||
|  |  | ||||||
|  |   if(cr) { | ||||||
|  |     r = 0; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if(cw) { | ||||||
|  |     w = 0; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // FIXME: Close callback | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //! @decl void create(string data, void|string type, void|int pointer) | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->create()] | ||||||
|  | void create(string _data, void|string type, int|void _ptr) { | ||||||
|  |   if(!_data) error("No data string given to FakeFile.\n"); | ||||||
|  |   data = _data; | ||||||
|  |   ptr = _ptr; | ||||||
|  |   mtime = time(); | ||||||
|  |   if(type) { | ||||||
|  |     type = lower_case(type); | ||||||
|  |     if(has_value(type, "r")) | ||||||
|  |       r = 1; | ||||||
|  |     if(has_value(type, "w")) | ||||||
|  |       w = 1; | ||||||
|  |   } | ||||||
|  |   else | ||||||
|  |     r = w = 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | protected string make_type_str() { | ||||||
|  |   string type = ""; | ||||||
|  |   if(r) type += "r"; | ||||||
|  |   if(w) type += "w"; | ||||||
|  |   return type; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->dup()] | ||||||
|  | this_program dup() { | ||||||
|  |   return this_program(data, make_type_str(), ptr); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //! Always returns 0. | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->errno()] | ||||||
|  | int errno() { return 0; } | ||||||
|  |  | ||||||
|  | //! Returns size and the creation time of the string. | ||||||
|  | Stdio.Stat stat() { | ||||||
|  |   Stdio.Stat st = Stdio.Stat(); | ||||||
|  |   st->size = sizeof(data); | ||||||
|  |   st->mtime=st->ctime=mtime; | ||||||
|  |   st->atime=time(); | ||||||
|  |   return st; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->line_iterator()] | ||||||
|  | String.SplitIterator line_iterator(int|void trim) { | ||||||
|  |   if(trim) | ||||||
|  |     return String.SplitIterator( data-"\r", '\n' ); | ||||||
|  |   return String.SplitIterator( data, '\n' ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | protected mixed id; | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->query_id()] | ||||||
|  | mixed query_id() { return id; } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->set_id()] | ||||||
|  | void set_id(mixed _id) { id = _id; } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->read_function()] | ||||||
|  | function(:string) read_function(int nbytes) { | ||||||
|  |   return lambda() { return read(nbytes); }; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->peek()] | ||||||
|  | int(-1..1) peek(int|float|void timeout) { | ||||||
|  |   if(!r) return -1; | ||||||
|  |   if(ptr >= sizeof(data)) return 0; | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //! Always returns 0. | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->query_address()] | ||||||
|  | string query_address(void|int(0..1) is_local) { return 0; } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->read()] | ||||||
|  | string read(void|int(0..) len, void|int(0..1) not_all) { | ||||||
|  |   if(!r) return 0; | ||||||
|  |   if (len < 0) error("Cannot read negative number of characters.\n"); | ||||||
|  |   int start=ptr; | ||||||
|  |   ptr += len; | ||||||
|  |   if(zero_type(len) || ptr>sizeof(data)) | ||||||
|  |     ptr = sizeof(data); | ||||||
|  |  | ||||||
|  |   // FIXME: read callback | ||||||
|  |   return data[start..ptr-1]; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.FILE()->gets()] | ||||||
|  | string gets() { | ||||||
|  |   if(!r) return 0; | ||||||
|  |   string ret; | ||||||
|  |   sscanf(data,"%*"+(string)ptr+"s%[^\n]",ret); | ||||||
|  |   if(ret) | ||||||
|  |   { | ||||||
|  |     ptr+=sizeof(ret)+1; | ||||||
|  |     if(ptr>sizeof(data)) | ||||||
|  |     { | ||||||
|  |       ptr=sizeof(data); | ||||||
|  |       if(!sizeof(ret)) | ||||||
|  | 	ret = 0; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // FIXME: read callback | ||||||
|  |   return ret; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.FILE()->getchar()] | ||||||
|  | int getchar() { | ||||||
|  |   if(!r) return 0; | ||||||
|  |   int c; | ||||||
|  |   if(catch(c=data[ptr])) | ||||||
|  |     c=-1; | ||||||
|  |   else | ||||||
|  |     ptr++; | ||||||
|  |  | ||||||
|  |   // FIXME: read callback | ||||||
|  |   return c; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.FILE()->unread()] | ||||||
|  | void unread(string s) { | ||||||
|  |   if(!r) return; | ||||||
|  |   if(data[ptr-sizeof(s)..ptr-1]==s) | ||||||
|  |     ptr-=sizeof(s); | ||||||
|  |   else | ||||||
|  |   { | ||||||
|  |     data=s+data[ptr..]; | ||||||
|  |     ptr=0; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->seek()] | ||||||
|  | int seek(int pos, void|int mult, void|int add) { | ||||||
|  |   if(mult) | ||||||
|  |     pos = pos*mult+add; | ||||||
|  |   if(pos<0) | ||||||
|  |   { | ||||||
|  |     pos = sizeof(data)+pos; | ||||||
|  |     if( pos < 0 ) | ||||||
|  | 	pos = 0; | ||||||
|  |   } | ||||||
|  |   ptr = pos; | ||||||
|  |   if( ptr > strlen( data ) ) | ||||||
|  |       ptr = strlen(data); | ||||||
|  |   return ptr; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //! Always returns 1. | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->sync()] | ||||||
|  | int(1..1) sync() { return 1; } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->tell()] | ||||||
|  | int tell() { return ptr; } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->truncate()] | ||||||
|  | int(0..1) truncate(int length) { | ||||||
|  |   data = data[..length-1]; | ||||||
|  |   return sizeof(data)==length; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->write()] | ||||||
|  | int(-1..) write(string|array(string) str, mixed ... extra) { | ||||||
|  |   if(!w) return -1; | ||||||
|  |   if(arrayp(str)) str=str*""; | ||||||
|  |   if(sizeof(extra)) str=sprintf(str, @extra); | ||||||
|  |  | ||||||
|  |   if(ptr==sizeof(data)) { | ||||||
|  |     data += str; | ||||||
|  |     ptr = sizeof(data); | ||||||
|  |   } | ||||||
|  |   else if(sizeof(str)==1) | ||||||
|  |     data[ptr++] = str[0]; | ||||||
|  |   else { | ||||||
|  |     data = data[..ptr-1] + str + data[ptr+sizeof(str)..]; | ||||||
|  |     ptr += sizeof(str); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // FIXME: write callback | ||||||
|  |   return sizeof(str); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->set_blocking] | ||||||
|  | void set_blocking() { | ||||||
|  |   close_cb = 0; | ||||||
|  |   read_cb = 0; | ||||||
|  |   read_oob_cb = 0; | ||||||
|  |   write_cb = 0; | ||||||
|  |   write_oob_cb = 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->set_blocking_keep_callbacks] | ||||||
|  | void set_blocking_keep_callbacks() { } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->set_blocking] | ||||||
|  | void set_nonblocking(function rcb, function wcb, function ccb, | ||||||
|  | 		     function rocb, function wocb) { | ||||||
|  |   read_cb = rcb; | ||||||
|  |   write_cb = wcb; | ||||||
|  |   close_cb = ccb; | ||||||
|  |   read_oob_cb = rocb; | ||||||
|  |   write_oob_cb = wocb; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->set_blocking_keep_callbacks] | ||||||
|  | void set_nonblocking_keep_callbacks() { } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->set_close_callback] | ||||||
|  | void set_close_callback(function cb) { close_cb = cb; } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->set_read_callback] | ||||||
|  | void set_read_callback(function cb) { read_cb = cb; } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->set_read_oob_callback] | ||||||
|  | void set_read_oob_callback(function cb) { read_oob_cb = cb; } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->set_write_callback] | ||||||
|  | void set_write_callback(function cb) { write_cb = cb; } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->set_write_oob_callback] | ||||||
|  | void set_write_oob_callback(function cb) { write_oob_cb = cb; } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->query_close_callback] | ||||||
|  | function query_close_callback() { return close_cb; } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->query_read_callback] | ||||||
|  | function query_read_callback() { return read_cb; } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->query_read_oob_callback] | ||||||
|  | function query_read_oob_callback() { return read_oob_cb; } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->query_write_callback] | ||||||
|  | function query_write_callback() { return write_cb; } | ||||||
|  |  | ||||||
|  | //! @seealso | ||||||
|  | //!   @[Stdio.File()->query_write_oob_callback] | ||||||
|  | function query_write_oob_callback() { return write_oob_cb; } | ||||||
|  |  | ||||||
|  | string _sprintf(int t) { | ||||||
|  |   return t=='O' && sprintf("%O(%d,%O)", this_program, sizeof(data), | ||||||
|  | 			   make_type_str()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | // FakeFile specials. | ||||||
|  |  | ||||||
|  | //! A FakeFile can be casted to a string. | ||||||
|  | mixed cast(string to) { | ||||||
|  |   switch(to) { | ||||||
|  |   case "string": return data; | ||||||
|  |   case "object": return this; | ||||||
|  |   } | ||||||
|  |   error("Can not cast object to %O.\n", to); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //! Sizeof on a FakeFile returns the size of its contents. | ||||||
|  | int(0..) _sizeof() { | ||||||
|  |   return sizeof(data); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //! @ignore | ||||||
|  |  | ||||||
|  | #define NOPE(X) mixed X (mixed ... args) { error("This is a FakeFile. %s is not available.\n", #X); } | ||||||
|  | NOPE(assign); | ||||||
|  | NOPE(async_connect); | ||||||
|  | NOPE(connect); | ||||||
|  | NOPE(connect_unix); | ||||||
|  | NOPE(open); | ||||||
|  | NOPE(open_socket); | ||||||
|  | NOPE(pipe); | ||||||
|  | NOPE(tcgetattr); | ||||||
|  | NOPE(tcsetattr); | ||||||
|  |  | ||||||
|  | // Stdio.Fd | ||||||
|  | NOPE(dup2); | ||||||
|  | NOPE(lock); // We could implement this | ||||||
|  | NOPE(mode); // We could implement this | ||||||
|  | NOPE(proxy); // We could implement this | ||||||
|  | NOPE(query_fd); | ||||||
|  | NOPE(read_oob); | ||||||
|  | NOPE(set_close_on_exec); | ||||||
|  | NOPE(set_keepalive); | ||||||
|  | NOPE(trylock); // We could implement this | ||||||
|  | NOPE(write_oob); | ||||||
|  |  | ||||||
|  | //! @endignore | ||||||
							
								
								
									
										260
									
								
								samples/Prolog/format_spec.pl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										260
									
								
								samples/Prolog/format_spec.pl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,260 @@ | |||||||
|  | :- module(format_spec, [ format_error/2 | ||||||
|  |                        , format_spec/2 | ||||||
|  |                        , format_spec//1 | ||||||
|  |                        , spec_arity/2 | ||||||
|  |                        , spec_types/2 | ||||||
|  |                        ]). | ||||||
|  |  | ||||||
|  | :- use_module(library(dcg/basics), [eos//0, integer//1, string_without//2]). | ||||||
|  | :- use_module(library(error)). | ||||||
|  | :- use_module(library(when), [when/2]). | ||||||
|  |  | ||||||
|  | % TODO loading this module is optional | ||||||
|  | % TODO it's for my own convenience during development | ||||||
|  | %:- use_module(library(mavis)). | ||||||
|  |  | ||||||
|  | %% format_error(+Goal, -Error:string) is nondet. | ||||||
|  | % | ||||||
|  | %  True if Goal exhibits an Error in its format string. The | ||||||
|  | %  Error string describes what is wrong with Goal. Iterates each | ||||||
|  | %  error on backtracking. | ||||||
|  | % | ||||||
|  | %  Goal may be one of the following predicates: | ||||||
|  | % | ||||||
|  | %    * format/2 | ||||||
|  | %    * format/3 | ||||||
|  | %    * debug/3 | ||||||
|  | format_error(format(Format,Args), Error) :- | ||||||
|  |     format_error_(Format, Args,Error). | ||||||
|  | format_error(format(_,Format,Args), Error) :- | ||||||
|  |     format_error_(Format,Args,Error). | ||||||
|  | format_error(debug(_,Format,Args), Error) :- | ||||||
|  |     format_error_(Format,Args,Error). | ||||||
|  |  | ||||||
|  | format_error_(Format,Args,Error) :- | ||||||
|  |     format_spec(Format, Spec), | ||||||
|  |     !, | ||||||
|  |     is_list(Args), | ||||||
|  |     spec_types(Spec, Types), | ||||||
|  |     types_error(Args, Types, Error). | ||||||
|  | format_error_(Format,_,Error) :- | ||||||
|  |     % \+ format_spec(Format, _), | ||||||
|  |     format(string(Error), "Invalid format string: ~q", [Format]). | ||||||
|  |  | ||||||
|  | types_error(Args, Types, Error) :- | ||||||
|  |     length(Types, TypesLen), | ||||||
|  |     length(Args, ArgsLen), | ||||||
|  |     TypesLen =\= ArgsLen, | ||||||
|  |     !, | ||||||
|  |     format( string(Error) | ||||||
|  |           , "Wrong argument count. Expected ~d, got ~d" | ||||||
|  |           , [TypesLen, ArgsLen] | ||||||
|  |           ). | ||||||
|  | types_error(Args, Types, Error) :- | ||||||
|  |     types_error_(Args, Types, Error). | ||||||
|  |  | ||||||
|  | types_error_([Arg|_],[Type|_],Error) :- | ||||||
|  |     ground(Arg), | ||||||
|  |     \+ is_of_type(Type,Arg), | ||||||
|  |     message_to_string(error(type_error(Type,Arg),_Location),Error). | ||||||
|  | types_error_([_|Args],[_|Types],Error) :- | ||||||
|  |     types_error_(Args, Types, Error). | ||||||
|  |  | ||||||
|  |  | ||||||
|  | % check/0 augmentation | ||||||
|  | :- multifile check:checker/2. | ||||||
|  | :- dynamic check:checker/2. | ||||||
|  | check:checker(format_spec:checker, "format/2 strings and arguments"). | ||||||
|  |  | ||||||
|  | :- dynamic format_fail/3. | ||||||
|  |  | ||||||
|  | checker :- | ||||||
|  |     prolog_walk_code([ module_class([user]) | ||||||
|  |                      , infer_meta_predicates(false) | ||||||
|  |                      , autoload(false)  % format/{2,3} are always loaded | ||||||
|  |                      , undefined(ignore) | ||||||
|  |                      , trace_reference(_) | ||||||
|  |                      , on_trace(check_format) | ||||||
|  |                      ]), | ||||||
|  |     retract(format_fail(Goal,Location,Error)), | ||||||
|  |     print_message(warning, format_error(Goal,Location,Error)), | ||||||
|  |     fail.  % iterate all errors | ||||||
|  | checker.  % succeed even if no errors are found | ||||||
|  |  | ||||||
|  | check_format(Module:Goal, _Caller, Location) :- | ||||||
|  |     predicate_property(Module:Goal, imported_from(Source)), | ||||||
|  |     memberchk(Source, [system,prolog_debug]), | ||||||
|  |     can_check(Goal), | ||||||
|  |     format_error(Goal, Error), | ||||||
|  |     assert(format_fail(Goal, Location, Error)), | ||||||
|  |     fail. | ||||||
|  | check_format(_,_,_).  % succeed to avoid printing goals | ||||||
|  |  | ||||||
|  | % true if format_error/2 can check this goal | ||||||
|  | can_check(Goal) :- | ||||||
|  |     once(clause(format_error(Goal,_),_)). | ||||||
|  |  | ||||||
|  | prolog:message(format_error(Goal,Location,Error)) --> | ||||||
|  |     prolog:message_location(Location), | ||||||
|  |     ['~n    In goal: ~q~n    ~s'-[Goal,Error]]. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | %% format_spec(-Spec)// | ||||||
|  | % | ||||||
|  | %  DCG for parsing format strings. It doesn't yet generate format | ||||||
|  | %  strings from a spec.  See format_spec/2 for details. | ||||||
|  | format_spec([]) --> | ||||||
|  |     eos. | ||||||
|  | format_spec([escape(Numeric,Modifier,Action)|Rest]) --> | ||||||
|  |     "~", | ||||||
|  |     numeric_argument(Numeric), | ||||||
|  |     modifier_argument(Modifier), | ||||||
|  |     action(Action), | ||||||
|  |     format_spec(Rest). | ||||||
|  | format_spec([text(String)|Rest]) --> | ||||||
|  |     { when((ground(String);ground(Codes)),string_codes(String, Codes)) }, | ||||||
|  |     string_without("~", Codes), | ||||||
|  |     { Codes \= [] }, | ||||||
|  |     format_spec(Rest). | ||||||
|  |  | ||||||
|  |  | ||||||
|  | %% format_spec(+Format, -Spec:list) is semidet. | ||||||
|  | % | ||||||
|  | %  Parse a format string.  Each element of Spec is one of the following: | ||||||
|  | % | ||||||
|  | %    * `text(Text)` - text sent to the output as is | ||||||
|  | %    * `escape(Num,Colon,Action)` - a format escape | ||||||
|  | % | ||||||
|  | %  `Num` represents the optional numeric portion of an esape. `Colon` | ||||||
|  | %  represents the optional colon in an escape. `Action` is an atom | ||||||
|  | %  representing the action to be take by this escape. | ||||||
|  | format_spec(Format, Spec) :- | ||||||
|  |     when((ground(Format);ground(Codes)),text_codes(Format, Codes)), | ||||||
|  |     once(phrase(format_spec(Spec), Codes, [])). | ||||||
|  |  | ||||||
|  | %% spec_arity(+FormatSpec, -Arity:positive_integer) is det. | ||||||
|  | % | ||||||
|  | %  True if FormatSpec requires format/2 to have Arity arguments. | ||||||
|  | spec_arity(Spec, Arity) :- | ||||||
|  |     spec_types(Spec, Types), | ||||||
|  |     length(Types, Arity). | ||||||
|  |  | ||||||
|  |  | ||||||
|  | %% spec_types(+FormatSpec, -Types:list(type)) is det. | ||||||
|  | % | ||||||
|  | %  True if FormatSpec requires format/2 to have arguments of Types. Each | ||||||
|  | %  value of Types is a type as described by error:has_type/2. This | ||||||
|  | %  notion of types is compatible with library(mavis). | ||||||
|  | spec_types(Spec, Types) :- | ||||||
|  |     phrase(spec_types(Spec), Types). | ||||||
|  |  | ||||||
|  | spec_types([]) --> | ||||||
|  |     []. | ||||||
|  | spec_types([Item|Items]) --> | ||||||
|  |     item_types(Item), | ||||||
|  |     spec_types(Items). | ||||||
|  |  | ||||||
|  | item_types(text(_)) --> | ||||||
|  |     []. | ||||||
|  | item_types(escape(Numeric,_,Action)) --> | ||||||
|  |     numeric_types(Numeric), | ||||||
|  |     action_types(Action). | ||||||
|  |  | ||||||
|  | numeric_types(number(_)) --> | ||||||
|  |     []. | ||||||
|  | numeric_types(character(_)) --> | ||||||
|  |     []. | ||||||
|  | numeric_types(star) --> | ||||||
|  |     [number]. | ||||||
|  | numeric_types(nothing) --> | ||||||
|  |     []. | ||||||
|  |  | ||||||
|  | action_types(Action) --> | ||||||
|  |     { atom_codes(Action, [Code]) }, | ||||||
|  |     { action_types(Code, Types) }, | ||||||
|  |     phrase(Types). | ||||||
|  |  | ||||||
|  |  | ||||||
|  | %% text_codes(Text:text, Codes:codes). | ||||||
|  | text_codes(Var, Codes) :- | ||||||
|  |     var(Var), | ||||||
|  |     !, | ||||||
|  |     string_codes(Var, Codes). | ||||||
|  | text_codes(Atom, Codes) :- | ||||||
|  |     atom(Atom), | ||||||
|  |     !, | ||||||
|  |     atom_codes(Atom, Codes). | ||||||
|  | text_codes(String, Codes) :- | ||||||
|  |     string(String), | ||||||
|  |     !, | ||||||
|  |     string_codes(String, Codes). | ||||||
|  | text_codes(Codes, Codes) :- | ||||||
|  |     is_of_type(codes, Codes). | ||||||
|  |  | ||||||
|  |  | ||||||
|  | numeric_argument(number(N)) --> | ||||||
|  |     integer(N). | ||||||
|  | numeric_argument(character(C)) --> | ||||||
|  |     "`", | ||||||
|  |     [C]. | ||||||
|  | numeric_argument(star) --> | ||||||
|  |     "*". | ||||||
|  | numeric_argument(nothing) --> | ||||||
|  |     "". | ||||||
|  |  | ||||||
|  |  | ||||||
|  | modifier_argument(colon) --> | ||||||
|  |     ":". | ||||||
|  | modifier_argument(no_colon) --> | ||||||
|  |     \+ ":". | ||||||
|  |  | ||||||
|  |  | ||||||
|  | action(Action) --> | ||||||
|  |     [C], | ||||||
|  |     { is_action(C) }, | ||||||
|  |     { atom_codes(Action, [C]) }. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | %% is_action(+Action:integer) is semidet. | ||||||
|  | %% is_action(-Action:integer) is multi. | ||||||
|  | % | ||||||
|  | %  True if Action is a valid format/2 action character. Iterates all | ||||||
|  | %  acceptable action characters, if Action is unbound. | ||||||
|  | is_action(Action) :- | ||||||
|  |     action_types(Action, _). | ||||||
|  |  | ||||||
|  | %% action_types(?Action:integer, ?Types:list(type)) | ||||||
|  | % | ||||||
|  | %  True if Action consumes arguments matching Types. An action (like | ||||||
|  | %  `~`), which consumes no arguments, has `Types=[]`.  For example, | ||||||
|  | % | ||||||
|  | %      ?- action_types(0'~, Types). | ||||||
|  | %      Types = []. | ||||||
|  | %      ?- action_types(0'a, Types). | ||||||
|  | %      Types = [atom]. | ||||||
|  | action_types(0'~, []). | ||||||
|  | action_types(0'a, [atom]). | ||||||
|  | action_types(0'c, [integer]).  % specifically, a code | ||||||
|  | action_types(0'd, [integer]). | ||||||
|  | action_types(0'D, [integer]). | ||||||
|  | action_types(0'e, [float]). | ||||||
|  | action_types(0'E, [float]). | ||||||
|  | action_types(0'f, [float]). | ||||||
|  | action_types(0'g, [float]). | ||||||
|  | action_types(0'G, [float]). | ||||||
|  | action_types(0'i, [any]). | ||||||
|  | action_types(0'I, [integer]). | ||||||
|  | action_types(0'k, [any]). | ||||||
|  | action_types(0'n, []). | ||||||
|  | action_types(0'N, []). | ||||||
|  | action_types(0'p, [any]). | ||||||
|  | action_types(0'q, [any]). | ||||||
|  | action_types(0'r, [integer]). | ||||||
|  | action_types(0'R, [integer]). | ||||||
|  | action_types(0's, [text]). | ||||||
|  | action_types(0'@, [callable]). | ||||||
|  | action_types(0't, []). | ||||||
|  | action_types(0'|, []). | ||||||
|  | action_types(0'+, []). | ||||||
|  | action_types(0'w, [any]). | ||||||
|  | action_types(0'W, [any, list]). | ||||||
							
								
								
									
										194
									
								
								samples/Prolog/func.pl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										194
									
								
								samples/Prolog/func.pl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,194 @@ | |||||||
|  | :- module(func, [ op(675, xfy, ($)) | ||||||
|  |                 , op(650, xfy, (of)) | ||||||
|  |                 , ($)/2 | ||||||
|  |                 , (of)/2 | ||||||
|  |                 ]). | ||||||
|  | :- use_module(library(list_util), [xfy_list/3]). | ||||||
|  | :- use_module(library(function_expansion)). | ||||||
|  | :- use_module(library(arithmetic)). | ||||||
|  | :- use_module(library(error)). | ||||||
|  |  | ||||||
|  |  | ||||||
|  | % true if the module whose terms are being read has specifically | ||||||
|  | % imported library(func). | ||||||
|  | wants_func :- | ||||||
|  |     prolog_load_context(module, Module), | ||||||
|  |     Module \== func,  % we don't want func sugar ourselves | ||||||
|  |     predicate_property(Module:of(_,_),imported_from(func)). | ||||||
|  |  | ||||||
|  |  | ||||||
|  | %%  compile_function(+Term, -In, -Out, -Goal) is semidet. | ||||||
|  | % | ||||||
|  | %   True if Term represents a function from In to Out | ||||||
|  | %   implemented by calling Goal.  This multifile hook is | ||||||
|  | %   called by $/2 and of/2 to convert a term into a goal. | ||||||
|  | %   It's used at compile time for macro expansion. | ||||||
|  | %   It's used at run time to handle functions which aren't | ||||||
|  | %   known at compile time. | ||||||
|  | %   When called as a hook, Term is guaranteed to be =nonvar=. | ||||||
|  | % | ||||||
|  | %   For example, to treat library(assoc) terms as functions which | ||||||
|  | %   map a key to a value, one might define: | ||||||
|  | % | ||||||
|  | %       :- multifile compile_function/4. | ||||||
|  | %       compile_function(Assoc, Key, Value, Goal) :- | ||||||
|  | %           is_assoc(Assoc), | ||||||
|  | %           Goal = get_assoc(Key, Assoc, Value). | ||||||
|  | % | ||||||
|  | %   Then one could write: | ||||||
|  | % | ||||||
|  | %       list_to_assoc([a-1, b-2, c-3], Assoc), | ||||||
|  | %       Two = Assoc $ b, | ||||||
|  | :- multifile compile_function/4. | ||||||
|  | compile_function(Var, _, _, _) :- | ||||||
|  |     % variables storing functions must be evaluated at run time | ||||||
|  |     % and can't be compiled, a priori, into a goal | ||||||
|  |     var(Var), | ||||||
|  |     !, | ||||||
|  |     fail. | ||||||
|  | compile_function(Expr, In, Out, Out is Expr) :- | ||||||
|  |     % arithmetic expression of one variable are simply evaluated | ||||||
|  |     \+ string(Expr),  % evaluable/1 throws exception with strings | ||||||
|  |     arithmetic:evaluable(Expr), | ||||||
|  |     term_variables(Expr, [In]). | ||||||
|  | compile_function(F, In, Out, func:Goal) :- | ||||||
|  |     % composed functions | ||||||
|  |     function_composition_term(F), | ||||||
|  |     user:function_expansion(F, func:Functor, true), | ||||||
|  |     Goal =.. [Functor,In,Out]. | ||||||
|  | compile_function(F, In, Out, Goal) :- | ||||||
|  |     % string interpolation via format templates | ||||||
|  |     format_template(F), | ||||||
|  |     ( atom(F) -> | ||||||
|  |         Goal = format(atom(Out), F, In) | ||||||
|  |     ; string(F) -> | ||||||
|  |         Goal = format(string(Out), F, In) | ||||||
|  |     ; error:has_type(codes, F) -> | ||||||
|  |         Goal = format(codes(Out), F, In) | ||||||
|  |     ; fail  % to be explicit | ||||||
|  |     ). | ||||||
|  | compile_function(Dict, In, Out, Goal) :- | ||||||
|  |     is_dict(Dict), | ||||||
|  |     Goal = get_dict(In, Dict, Out). | ||||||
|  |  | ||||||
|  | %%	$(+Function, +Argument) is det. | ||||||
|  | % | ||||||
|  | %	Apply Function to an Argument.  A Function is any predicate | ||||||
|  | %	whose final argument generates output and whose penultimate argument | ||||||
|  | %	accepts input. | ||||||
|  | % | ||||||
|  | %	This is realized by expanding function application to chained | ||||||
|  | %	predicate calls at compile time.  Function application itself can | ||||||
|  | %	be chained. | ||||||
|  | % | ||||||
|  | %	== | ||||||
|  | %	Reversed = reverse $ sort $ [c,d,b]. | ||||||
|  | %	== | ||||||
|  | :- meta_predicate $(2,+). | ||||||
|  | $(_,_) :- | ||||||
|  |     throw(error(permission_error(call, predicate, ($)/2), | ||||||
|  |           context(_, '$/2 must be subject to goal expansion'))). | ||||||
|  |  | ||||||
|  | user:function_expansion($(F,X), Y, Goal) :- | ||||||
|  |     wants_func, | ||||||
|  |     ( func:compile_function(F, X, Y, Goal) -> | ||||||
|  |         true | ||||||
|  |     ; var(F) -> Goal =      % defer until run time | ||||||
|  |         ( func:compile_function(F, X, Y, P) -> | ||||||
|  |             call(P) | ||||||
|  |         ; call(F, X, Y) | ||||||
|  |         ) | ||||||
|  |     ; Goal = call(F, X, Y) | ||||||
|  |     ). | ||||||
|  |  | ||||||
|  |  | ||||||
|  | %%	of(+F, +G) is det. | ||||||
|  | % | ||||||
|  | %	Creates a new function by composing F and G.  The functions are | ||||||
|  | %	composed at compile time to create a new, compiled predicate which | ||||||
|  | %	behaves like a function.  Function composition can be chained. | ||||||
|  | %	Composed functions can also be applied with $/2. | ||||||
|  | % | ||||||
|  | %	== | ||||||
|  | %	Reversed = reverse of sort $ [c,d,b]. | ||||||
|  | %	== | ||||||
|  | :- meta_predicate of(2,2). | ||||||
|  | of(_,_). | ||||||
|  |  | ||||||
|  |  | ||||||
|  | %%  format_template(Format) is semidet. | ||||||
|  | % | ||||||
|  | %   True if Format is a template string suitable for format/3. | ||||||
|  | %   The current check is very naive and should be improved. | ||||||
|  | format_template(Format) :- | ||||||
|  |     atom(Format), !, | ||||||
|  |     atom_codes(Format, Codes), | ||||||
|  |     format_template(Codes). | ||||||
|  | format_template(Format) :- | ||||||
|  |     string(Format), | ||||||
|  |     !, | ||||||
|  |     string_codes(Format, Codes), | ||||||
|  |     format_template(Codes). | ||||||
|  | format_template(Format) :- | ||||||
|  |     error:has_type(codes, Format), | ||||||
|  |     memberchk(0'~, Format).  % ' fix syntax highlighting | ||||||
|  |  | ||||||
|  |  | ||||||
|  | % True if the argument is a function composition term | ||||||
|  | function_composition_term(of(_,_)). | ||||||
|  |  | ||||||
|  | % Converts a function composition term into a list of functions to compose | ||||||
|  | functions_to_compose(Term, Funcs) :- | ||||||
|  |     functor(Term, Op, 2), | ||||||
|  |     Op = (of), | ||||||
|  |     xfy_list(Op, Term, Funcs). | ||||||
|  |  | ||||||
|  | % Thread a state variable through a list of functions.  This is similar | ||||||
|  | % to a DCG expansion, but much simpler. | ||||||
|  | thread_state([], [], Out, Out). | ||||||
|  | thread_state([F|Funcs], [Goal|Goals], In, Out) :- | ||||||
|  |     ( compile_function(F, In, Tmp, Goal) -> | ||||||
|  |         true | ||||||
|  |     ; var(F) -> | ||||||
|  |         instantiation_error(F) | ||||||
|  |     ; F =.. [Functor|Args], | ||||||
|  |       append(Args, [In, Tmp], NewArgs), | ||||||
|  |       Goal =.. [Functor|NewArgs] | ||||||
|  |     ), | ||||||
|  |     thread_state(Funcs, Goals, Tmp, Out). | ||||||
|  |  | ||||||
|  | user:function_expansion(Term, func:Functor, true) :- | ||||||
|  |     wants_func, | ||||||
|  |     functions_to_compose(Term, Funcs), | ||||||
|  |     debug(func, 'building composed function for: ~w', [Term]), | ||||||
|  |     variant_sha1(Funcs, Sha), | ||||||
|  |     format(atom(Functor), 'composed_function_~w', [Sha]), | ||||||
|  |     debug(func, '  name: ~s', [Functor]), | ||||||
|  |     ( func:current_predicate(Functor/2) -> | ||||||
|  |         debug(func, '  composed predicate already exists', []) | ||||||
|  |     ; true -> | ||||||
|  |         reverse(Funcs, RevFuncs), | ||||||
|  |         thread_state(RevFuncs, Threaded, In, Out), | ||||||
|  |         xfy_list(',', Body, Threaded), | ||||||
|  |         Head =.. [Functor, In, Out], | ||||||
|  |         func:assert(Head :- Body), | ||||||
|  |         func:compile_predicates([Functor/2]) | ||||||
|  |     ). | ||||||
|  |  | ||||||
|  |  | ||||||
|  | % support foo(x,~,y) evaluation | ||||||
|  | user:function_expansion(Term, Output, Goal) :- | ||||||
|  |     wants_func, | ||||||
|  |     compound(Term), | ||||||
|  |  | ||||||
|  |     % has a single ~ argument | ||||||
|  |     setof( X | ||||||
|  |          , ( arg(X,Term,Arg), Arg == '~' ) | ||||||
|  |          , [N] | ||||||
|  |          ), | ||||||
|  |  | ||||||
|  |     % replace ~ with a variable | ||||||
|  |     Term =.. [Name|Args0], | ||||||
|  |     nth1(N, Args0, ~, Rest), | ||||||
|  |     nth1(N, Args, Output, Rest), | ||||||
|  |     Goal =.. [Name|Args]. | ||||||
							
								
								
									
										97
									
								
								samples/Propeller Spin/4x4 Keypad Reader.spin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								samples/Propeller Spin/4x4 Keypad Reader.spin
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,97 @@ | |||||||
|  | {{ | ||||||
|  | ***************************************** | ||||||
|  | * 4x4 Keypad Reader           v1.0      * | ||||||
|  | * Author: Beau Schwabe                  * | ||||||
|  | * Copyright (c) 2007 Parallax           *                | ||||||
|  | * See end of file for terms of use.     *                | ||||||
|  | ***************************************** | ||||||
|  | }} | ||||||
|  | { | ||||||
|  |  | ||||||
|  | Operation: | ||||||
|  |  | ||||||
|  | This object uses a capacitive PIN approach to reading the keypad. | ||||||
|  | To do so, ALL pins are made LOW and an OUTPUT to "discharge" the | ||||||
|  | I/O pins.  Then, ALL pins are set to an INPUT state.  At this point, | ||||||
|  | only one pin is made HIGH and an OUTPUT at a time.  If the "switch" | ||||||
|  | is closed, then a HIGH will be read on the input, otherwise a LOW | ||||||
|  | will be returned. | ||||||
|  |  | ||||||
|  | The keypad decoding routine only requires two subroutines and returns | ||||||
|  | the entire 4x4 keypad matrix into a single WORD variable indicating | ||||||
|  | which buttons are pressed.  Multiple button presses are allowed with | ||||||
|  | the understanding that“BOX entries can be confused. An example of a | ||||||
|  | BOX entry... 1,2,4,5 or 1,4,3,6 or 4,6,*,#  etc. where any 3 of the 4 | ||||||
|  | buttons pressed will evaluate the non pressed button as being pressed, | ||||||
|  | even when they are not.  There is no danger of any physical or | ||||||
|  | electrical damage, that s just the way this sensing method happens to | ||||||
|  | work. | ||||||
|  |  | ||||||
|  | Schematic: | ||||||
|  | No resistors, No capacitors.  The connections are directly from the | ||||||
|  | keypad to the I/O's.  I literally plugged mine right into the demo | ||||||
|  | board RevC. | ||||||
|  |  | ||||||
|  | Looking at the Back of the 4x4 keypad... | ||||||
|  |  | ||||||
|  |        P7         P0 | ||||||
|  |          ││││││││ | ||||||
|  | ┌─────── ││││││││ ───────┐ | ||||||
|  | │     oo ││││││││ o      │ | ||||||
|  | │                        │ | ||||||
|  | │  O    O    O    O    O │  | ||||||
|  | │                        │ | ||||||
|  | │  O    O    O    O    O │ | ||||||
|  | │         {LABEL}        │ | ||||||
|  | │  O    O    O    O    O │  | ||||||
|  | │                        │ | ||||||
|  | │  O    O    O    O    O │ | ||||||
|  | │                        │ | ||||||
|  | │  O    O    O    O    O │ | ||||||
|  | │             o    o     │ | ||||||
|  | └────────────────────────┘ | ||||||
|  |  | ||||||
|  | } | ||||||
|  | VAR | ||||||
|  |   word  keypad | ||||||
|  |    | ||||||
|  | PUB ReadKeyPad | ||||||
|  |     keypad := 0                 'Clear 4x4 'keypad' value | ||||||
|  |     ReadRow(3)                  'Call routine to read entire ROW 0 | ||||||
|  |     keypad <<= 4                'Shift 'keypad' value left by 4 | ||||||
|  |     ReadRow(2)                  'Call routine to read entire ROW 1 | ||||||
|  |     keypad <<= 4                'Shift 'keypad' value left by 4 | ||||||
|  |     ReadRow(1)                  'Call routine to read entire ROW 2 | ||||||
|  |     keypad <<= 4                'Shift 'keypad' value left by 4 | ||||||
|  |     ReadRow(0)                  'Call routine to read entire ROW 3 | ||||||
|  |     Result := keypad | ||||||
|  |  | ||||||
|  | PRI ReadRow(n) | ||||||
|  |     outa[0..7]~                 'preset P0 to P7 as LOWs | ||||||
|  |     dira[0..7]~~                'make P0 to P7 OUTPUTs ... discharge pins or "capacitors" to VSS | ||||||
|  |     dira[0..7]~                 'make P0 to P7 INPUTSs ... now the pins act like tiny capacitors | ||||||
|  |     outa[n]~~                   'preset Pin 'n' HIGH          | ||||||
|  |     dira[n]~~                   'make Pin 'n' an OUTPUT... Make only one pin HIGH ; will charge | ||||||
|  |                                 '                          "capacitor" if switch is closed. | ||||||
|  |                                 '  | ||||||
|  |     keypad += ina[4..7]         'read ROW value        ... If a switch is open, the pin or "capacitor" | ||||||
|  |     dira[n]~                    'make Pn an INPUT          will remain discharged | ||||||
|  |      | ||||||
|  | DAT | ||||||
|  | {{ | ||||||
|  | ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ | ||||||
|  | │                                                   TERMS OF USE: MIT License                                                  │                                                             | ||||||
|  | ├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ | ||||||
|  | │Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation    │  | ||||||
|  | │files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,    │ | ||||||
|  | │modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ | ||||||
|  | │is furnished to do so, subject to the following conditions:                                                                   │ | ||||||
|  | │                                                                                                                              │ | ||||||
|  | │The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ | ||||||
|  | │                                                                                                                              │ | ||||||
|  | │THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE          │ | ||||||
|  | │WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR         │ | ||||||
|  | │COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,   │ | ||||||
|  | │ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                         │ | ||||||
|  | └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ | ||||||
|  | }}     | ||||||
							
								
								
									
										181
									
								
								samples/Propeller Spin/Debug_Lcd.spin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										181
									
								
								samples/Propeller Spin/Debug_Lcd.spin
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,181 @@ | |||||||
|  | ''**************************************** | ||||||
|  | ''*  Debug_Lcd v1.2                      * | ||||||
|  | ''*  Authors: Jon Williams, Jeff Martin  * | ||||||
|  | ''*  Copyright (c) 2006 Parallax, Inc.   * | ||||||
|  | ''*  See end of file for terms of use.   * | ||||||
|  | ''**************************************** | ||||||
|  | '' | ||||||
|  | '' Debugging wrapper for Serial_Lcd object | ||||||
|  | '' | ||||||
|  | '' v1.2 - March 26, 2008 - Updated by Jeff Martin to conform to Propeller object initialization standards. | ||||||
|  | '' v1.1 - April 29, 2006 - Updated by Jon Williams for consistency. | ||||||
|  | '' | ||||||
|  |  | ||||||
|  |  | ||||||
|  | OBJ | ||||||
|  |  | ||||||
|  |   lcd : "serial_lcd"                                    ' driver for Parallax Serial LCD | ||||||
|  |   num : "simple_numbers"                                ' number to string conversion | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB init(pin, baud, lines) : okay | ||||||
|  |  | ||||||
|  | '' Initializes serial LCD object | ||||||
|  | '' -- returns true if all parameters okay | ||||||
|  |  | ||||||
|  |   okay := lcd.init(pin, baud, lines)  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB finalize | ||||||
|  |  | ||||||
|  | '' Finalizes lcd object -- frees the pin (floats) | ||||||
|  |  | ||||||
|  |   lcd.finalize | ||||||
|  |  | ||||||
|  |    | ||||||
|  | PUB putc(txbyte) | ||||||
|  |  | ||||||
|  | '' Send a byte to the terminal | ||||||
|  |  | ||||||
|  |   lcd.putc(txbyte) | ||||||
|  |    | ||||||
|  |    | ||||||
|  | PUB str(strAddr) | ||||||
|  |  | ||||||
|  | '' Print a zero-terminated string | ||||||
|  |  | ||||||
|  |   lcd.str(strAddr) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB dec(value) | ||||||
|  |  | ||||||
|  | '' Print a signed decimal number | ||||||
|  |  | ||||||
|  |   lcd.str(num.dec(value))   | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB decf(value, width)  | ||||||
|  |  | ||||||
|  | '' Prints signed decimal value in space-padded, fixed-width field | ||||||
|  |  | ||||||
|  |   lcd.str(num.decf(value, width))    | ||||||
|  |    | ||||||
|  |  | ||||||
|  | PUB decx(value, digits)  | ||||||
|  |  | ||||||
|  | '' Prints zero-padded, signed-decimal string | ||||||
|  | '' -- if value is negative, field width is digits+1 | ||||||
|  |  | ||||||
|  |   lcd.str(num.decx(value, digits))  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB hex(value, digits) | ||||||
|  |  | ||||||
|  | '' Print a hexadecimal number | ||||||
|  |  | ||||||
|  |   lcd.str(num.hex(value, digits)) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB ihex(value, digits) | ||||||
|  |  | ||||||
|  | '' Print an indicated hexadecimal number | ||||||
|  |  | ||||||
|  |   lcd.str(num.ihex(value, digits))    | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB bin(value, digits) | ||||||
|  |  | ||||||
|  | '' Print a binary number | ||||||
|  |  | ||||||
|  |   lcd.str(num.bin(value, digits)) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB ibin(value, digits) | ||||||
|  |  | ||||||
|  | '' Print an indicated (%) binary number | ||||||
|  |  | ||||||
|  |   lcd.str(num.ibin(value, digits))      | ||||||
|  |      | ||||||
|  |  | ||||||
|  | PUB cls | ||||||
|  |  | ||||||
|  | '' Clears LCD and moves cursor to home (0, 0) position | ||||||
|  |  | ||||||
|  |   lcd.cls  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB home | ||||||
|  |  | ||||||
|  | '' Moves cursor to 0, 0 | ||||||
|  |  | ||||||
|  |   lcd.home | ||||||
|  |    | ||||||
|  |  | ||||||
|  | PUB gotoxy(col, line) | ||||||
|  |  | ||||||
|  | '' Moves cursor to col/line | ||||||
|  |  | ||||||
|  |   lcd.gotoxy(col, line) | ||||||
|  |  | ||||||
|  |    | ||||||
|  | PUB clrln(line) | ||||||
|  |  | ||||||
|  | '' Clears line | ||||||
|  |  | ||||||
|  |   lcd.clrln(line) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB cursor(type) | ||||||
|  |  | ||||||
|  | '' Selects cursor type | ||||||
|  | ''   0 : cursor off, blink off   | ||||||
|  | ''   1 : cursor off, blink on    | ||||||
|  | ''   2 : cursor on, blink off   | ||||||
|  | ''   3 : cursor on, blink on | ||||||
|  |  | ||||||
|  |   lcd.cursor(type) | ||||||
|  |         | ||||||
|  |  | ||||||
|  | PUB display(status) | ||||||
|  |  | ||||||
|  | '' Controls display visibility; use display(false) to hide contents without clearing | ||||||
|  |  | ||||||
|  |   if status | ||||||
|  |     lcd.displayOn | ||||||
|  |   else | ||||||
|  |     lcd.displayOff | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB custom(char, chrDataAddr) | ||||||
|  |  | ||||||
|  | '' Installs custom character map | ||||||
|  | '' -- chrDataAddr is address of 8-byte character definition array | ||||||
|  |  | ||||||
|  |   lcd.custom(char, chrDataAddr) | ||||||
|  |  | ||||||
|  |        | ||||||
|  | PUB backLight(status) | ||||||
|  |  | ||||||
|  | '' Enable (true) or disable (false) LCD backlight | ||||||
|  | '' -- affects only backlit models | ||||||
|  |  | ||||||
|  |   lcd.backLight(status) | ||||||
|  |  | ||||||
|  | {{ | ||||||
|  |  | ||||||
|  | ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ | ||||||
|  | │                                                   TERMS OF USE: MIT License                                                  │                                                             | ||||||
|  | ├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ | ||||||
|  | │Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation    │  | ||||||
|  | │files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,    │ | ||||||
|  | │modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ | ||||||
|  | │is furnished to do so, subject to the following conditions:                                                                   │ | ||||||
|  | │                                                                                                                              │ | ||||||
|  | │The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ | ||||||
|  | │                                                                                                                              │ | ||||||
|  | │THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE          │ | ||||||
|  | │WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR         │ | ||||||
|  | │COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,   │ | ||||||
|  | │ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                         │ | ||||||
|  | └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ | ||||||
|  | }}   | ||||||
							
								
								
									
										1669
									
								
								samples/Propeller Spin/Graphics.spin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1669
									
								
								samples/Propeller Spin/Graphics.spin
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										221
									
								
								samples/Propeller Spin/Inductor.spin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										221
									
								
								samples/Propeller Spin/Inductor.spin
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,221 @@ | |||||||
|  | {{ | ||||||
|  | ***************************************** | ||||||
|  | * Inductive Sensor Demo v1.0            * | ||||||
|  | * Author: Beau Schwabe                  * | ||||||
|  | * Copyright (c) 2007 Parallax           * | ||||||
|  | * See end of file for terms of use.     * | ||||||
|  | ***************************************** | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Test Circuit: | ||||||
|  |  | ||||||
|  |       10pF   100K  1M | ||||||
|  | FPin ───┳──┳── SDF(sigma-delta feedback) | ||||||
|  |           │      ┣──── SDI(sigma-delta input) | ||||||
|  |         L   100K | ||||||
|  |                       | ||||||
|  |          GND    GND   | ||||||
|  |                                   | ||||||
|  |  | ||||||
|  | Test Coils: | ||||||
|  |  | ||||||
|  | Wire used was the "Radio Shack Special" GREEN (about 27 gauge) | ||||||
|  |  | ||||||
|  | 25T (Coke Can form)    = 2.1MHz | ||||||
|  | 15T (Coke Can form)    = 3.9MHz | ||||||
|  |  5T (Coke Can form)    = 5.3MHz | ||||||
|  | 50T (BIC pen form)     = 3.2MHz | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | How does it work? | ||||||
|  |  | ||||||
|  | Note: The reported resonate frequency is NOT the actual resonate LC frequency.  Instead it is where the voltage produced from | ||||||
|  |       the LC circuit was clipped.   | ||||||
|  |  | ||||||
|  |       In the example circuit below: | ||||||
|  |        | ||||||
|  |              C     L | ||||||
|  |         A ────┳──── GND | ||||||
|  |                 │  | ||||||
|  |                 B          | ||||||
|  |  | ||||||
|  |       When you apply a small voltage at a specific frequency to an LC circuit (at point "A") that is at or near the resonate | ||||||
|  |       frequency of LC, it is not uncommon to measure 10's or 100's of times the amount of voltage (at point "B") that you are | ||||||
|  |       applying to the LC circuit. (at point "A") | ||||||
|  |  | ||||||
|  |  | ||||||
|  |       In the "Test Circuit" above, point "B" passes through a diode which then basically feeds a divide by 2 voltage divider: | ||||||
|  |  | ||||||
|  |               100K 100K | ||||||
|  |         B ───┳── GND | ||||||
|  |                   │ | ||||||
|  |                   C | ||||||
|  |  | ||||||
|  |       ...So in order see the sigma-delta ADC "clip" the frequency sweep result, the output from the LC circuit only needs | ||||||
|  |       to generate about 6.6 Volts above ground. (0.6V drop across the diode, and since the ADC is only sensitive to about | ||||||
|  |       3V, it works out to be about 6.6V after the voltage divider.) | ||||||
|  |  | ||||||
|  |  | ||||||
|  |       A typical magnitude plot of a frequency sweep applied to an LC circuit might look something like this: | ||||||
|  |        | ||||||
|  |                     * | ||||||
|  |                     * | ||||||
|  |                     * | ||||||
|  |                     * | ||||||
|  |                    * * | ||||||
|  |                   *   * | ||||||
|  |                  *     * | ||||||
|  |                *         * | ||||||
|  |              *             * | ||||||
|  |        *****                 ***** | ||||||
|  |  | ||||||
|  |  | ||||||
|  |        ...With 'clipping' the pattern looks more like this: | ||||||
|  |  | ||||||
|  |                   X**** | ||||||
|  |                  *     * | ||||||
|  |                *         * | ||||||
|  |              *             * | ||||||
|  |        *****                 ***** | ||||||
|  |  | ||||||
|  |        ...The 'X' denotes the location of the reported resonate frequency. The reason this is slightly off is for | ||||||
|  |        two reasons really. 1) lazy - I didn't want to fiddle with the voltage divider combo... adjusting so that the | ||||||
|  |        "peak" was also where the ADC happened to "clip".  2) some benefit - When you apply a frequency to a tuned LC | ||||||
|  |        circuit that's resonate frequency is the same as the applied frequency, the LC acts like a dead short.  A | ||||||
|  |        situation not exactly great for Propeller I/O's | ||||||
|  |  | ||||||
|  |        Now that we have that out of the way, what happens next?  How can we use this so called "coil" as a sensor? | ||||||
|  |  | ||||||
|  |        If a frequency sweep is initially preformed to determine the resonate frequency clip point, then it just so | ||||||
|  |        happens that adding additional "metal" (<- Does not need to be ferrous) causes the resonate frequency to shift | ||||||
|  |        to a HIGHER frequency. | ||||||
|  |  | ||||||
|  |        Once you determine the "clip" frequency and you use one of the available counters to constantly feed that | ||||||
|  |        particular frequency back to the LC circuit, the resulting ADC output is proportional and somewhat linear when | ||||||
|  |        metal objects are introduced to the coil. | ||||||
|  |  | ||||||
|  |        Assume frequency increases from Left to Right.  With a slight resonate shift to the right, the ADC reports a | ||||||
|  |        lower "de-tuned" value because the voltage magnitude no longer "clips" at the reported resonate frequency. | ||||||
|  |        Typical ranges are full scale between 65535 (no metal) and 0 (metal saturation) | ||||||
|  |  | ||||||
|  |   | ||||||
|  |                           X    ***** | ||||||
|  |                               *     * | ||||||
|  |  ADC reports value here --> *         * | ||||||
|  |                           *             * | ||||||
|  |                     *****                 ***** | ||||||
|  |  | ||||||
|  |                      Slight shift to the right | ||||||
|  |  | ||||||
|  |        I also made mention that the response is somewhat linear. As the LC resonance shifts and the ADC value begins | ||||||
|  |        to lower, the slope is steepest near the "clip" point.  Therefore, the slightest shift results in larger value | ||||||
|  |        changes.  Since the coil is actually the least sensitive to metal the further away it is (Law of squares) and | ||||||
|  |        most sensitive to metal the closer it is, the resulting combination acts to linearize the output. I need to | ||||||
|  |        point out that some LC combinations will exhibit plateaus and other anomalies caused by varying parasitic circuit | ||||||
|  |        conditions that will affect the overall output, so a little bit of trial and error is necessary to get things | ||||||
|  |        the way you want them. | ||||||
|  |  | ||||||
|  | }} | ||||||
|  | OBJ | ||||||
|  |    Freq   : "Synth" | ||||||
|  |    ADC    : "ADC" | ||||||
|  |    gr     : "graphics" | ||||||
|  |    Num    : "Numbers" | ||||||
|  | CON | ||||||
|  |   FPin =                        0 | ||||||
|  |  | ||||||
|  |   UpperFrequency =              6_000_000 | ||||||
|  |   LowerFrequency =              2_000_000 | ||||||
|  |  | ||||||
|  |   bitmap_base = $2000 | ||||||
|  |   display_base = $5000 | ||||||
|  |  | ||||||
|  | VAR | ||||||
|  |     long              FMax, FTemp, FValue, Frequency | ||||||
|  |      | ||||||
|  | PUB demo | ||||||
|  |     'start and setup graphics | ||||||
|  |     gr.start | ||||||
|  |     gr.setup(16, 12, 128, 96, bitmap_base) | ||||||
|  |  | ||||||
|  |     FindResonateFrequency | ||||||
|  |  | ||||||
|  |     DisplayInductorValue | ||||||
|  |  | ||||||
|  | PUB DisplayInductorValue | X | ||||||
|  |     Freq.Synth("A", FPin, FValue) | ||||||
|  |     repeat | ||||||
|  |       ADC.SigmaDelta(@FTemp) | ||||||
|  |  | ||||||
|  | '**************************************** Graphics Option Start ********************************************* | ||||||
|  |       'clear bitmap | ||||||
|  |       gr.clear | ||||||
|  |       'draw text | ||||||
|  |       gr.textmode(1,1,7,5) | ||||||
|  |       gr.colorwidth(1,0) | ||||||
|  |       gr.text(0,90,string("Inductive Propeller Sensor")) | ||||||
|  |  | ||||||
|  |       gr.colorwidth(1,5) | ||||||
|  |       X := (65535 - FTemp )*200/65535 | ||||||
|  |       gr.plot(-100+X,15) | ||||||
|  |  | ||||||
|  |       gr.textmode(1,1,7,%0000) | ||||||
|  |       gr.colorwidth(1,0) | ||||||
|  |       gr.text(-100,-20,string("Resonate Frequency =")) | ||||||
|  |       gr.text(35,-20,Num.ToStr(FValue,10)) | ||||||
|  |  | ||||||
|  |       gr.text(-100,-36,string("ADC Frequency Response =")) | ||||||
|  |       gr.text(65,-36,Num.ToStr(FTemp,10)) | ||||||
|  |  | ||||||
|  |       'copy bitmap to display | ||||||
|  |       gr.copy(display_base) | ||||||
|  | '**************************************** Graphics Option Finish *********************************************       | ||||||
|  |  | ||||||
|  | PUB FindResonateFrequency | P | ||||||
|  |     dira[FPin]                  := 1 | ||||||
|  |      | ||||||
|  |     FMax := 0 | ||||||
|  |     repeat Frequency from LowerFrequency to UpperFrequency step 1000 | ||||||
|  |       Freq.Synth("A", FPin, Frequency) | ||||||
|  |       ADC.SigmaDelta(@FTemp) | ||||||
|  |  | ||||||
|  |       if FTemp > FMax | ||||||
|  |          FMax := FTemp | ||||||
|  |          FValue := Frequency | ||||||
|  | '**************************************** Graphics Option Start ********************************************* | ||||||
|  |       P := (Frequency - LowerFrequency)*100/(UpperFrequency - LowerFrequency) | ||||||
|  |  | ||||||
|  |       gr.colorwidth(1,5) | ||||||
|  |       gr.plot(0,0) | ||||||
|  |       gr.line(P,0) | ||||||
|  |       gr.colorwidth(3,5) | ||||||
|  |       gr.line(100,0) | ||||||
|  |  | ||||||
|  |       gr.colorwidth(2,0) | ||||||
|  |       gr.plot(P,(FTemp/1024)+10) | ||||||
|  |       gr.colorwidth(0,1) | ||||||
|  |       gr.plot(P+1,5) | ||||||
|  |       gr.line(P+1,50) | ||||||
|  |  | ||||||
|  |       gr.copy(display_base) | ||||||
|  | '**************************************** Graphics Option Finish ********************************************* | ||||||
|  |  | ||||||
|  | DAT | ||||||
|  | {{ | ||||||
|  | ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ | ||||||
|  | │                                                   TERMS OF USE: MIT License                                                  │ | ||||||
|  | ├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ | ||||||
|  | │Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation    │ | ||||||
|  | │files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,    │ | ||||||
|  | │modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ | ||||||
|  | │is furnished to do so, subject to the following conditions:                                                                   │ | ||||||
|  | │                                                                                                                              │ | ||||||
|  | │The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ | ||||||
|  | │                                                                                                                              │ | ||||||
|  | │THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE          │ | ||||||
|  | │WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR         │ | ||||||
|  | │COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,   │ | ||||||
|  | │ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                         │ | ||||||
|  | └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ | ||||||
|  | }} | ||||||
							
								
								
									
										736
									
								
								samples/Propeller Spin/Keyboard.spin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										736
									
								
								samples/Propeller Spin/Keyboard.spin
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,736 @@ | |||||||
|  | ''*************************************** | ||||||
|  | ''*  PS/2 Keyboard Driver v1.0.1        * | ||||||
|  | ''*  Author: Chip Gracey                * | ||||||
|  | ''*  Copyright (c) 2004 Parallax, Inc.  * | ||||||
|  | ''*  See end of file for terms of use.  * | ||||||
|  | ''*************************************** | ||||||
|  |  | ||||||
|  | {-----------------REVISION HISTORY----------------- | ||||||
|  |  v1.0.1 - Updated 6/15/2006 to work with Propeller Tool 0.96} | ||||||
|  |   | ||||||
|  | VAR | ||||||
|  |  | ||||||
|  |   long  cog | ||||||
|  |  | ||||||
|  |   long  par_tail        'key buffer tail        read/write      (19 contiguous longs) | ||||||
|  |   long  par_head        'key buffer head        read-only | ||||||
|  |   long  par_present     'keyboard present       read-only | ||||||
|  |   long  par_states[8]   'key states (256 bits)  read-only | ||||||
|  |   long  par_keys[8]     'key buffer (16 words)  read-only       (also used to pass initial parameters) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB start(dpin, cpin) : okay | ||||||
|  |  | ||||||
|  | '' Start keyboard driver - starts a cog | ||||||
|  | '' returns false if no cog available | ||||||
|  | '' | ||||||
|  | ''   dpin  = data signal on PS/2 jack | ||||||
|  | ''   cpin  = clock signal on PS/2 jack | ||||||
|  | '' | ||||||
|  | ''     use 100-ohm resistors between pins and jack | ||||||
|  | ''     use 10K-ohm resistors to pull jack-side signals to VDD | ||||||
|  | ''     connect jack-power to 5V, jack-gnd to VSS | ||||||
|  | '' | ||||||
|  | '' all lock-keys will be enabled, NumLock will be initially 'on', | ||||||
|  | '' and auto-repeat will be set to 15cps with a delay of .5s | ||||||
|  |  | ||||||
|  |   okay := startx(dpin, cpin, %0_000_100, %01_01000) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB startx(dpin, cpin, locks, auto) : okay | ||||||
|  |  | ||||||
|  | '' Like start, but allows you to specify lock settings and auto-repeat | ||||||
|  | '' | ||||||
|  | ''   locks = lock setup | ||||||
|  | ''           bit 6 disallows shift-alphas (case set soley by CapsLock) | ||||||
|  | ''           bits 5..3 disallow toggle of NumLock/CapsLock/ScrollLock state | ||||||
|  | ''           bits 2..0 specify initial state of NumLock/CapsLock/ScrollLock | ||||||
|  | ''           (eg. %0_001_100 = disallow ScrollLock, NumLock initially 'on') | ||||||
|  | '' | ||||||
|  | ''   auto  = auto-repeat setup | ||||||
|  | ''           bits 6..5 specify delay (0=.25s, 1=.5s, 2=.75s, 3=1s) | ||||||
|  | ''           bits 4..0 specify repeat rate (0=30cps..31=2cps) | ||||||
|  | ''           (eg %01_00000 = .5s delay, 30cps repeat) | ||||||
|  |  | ||||||
|  |   stop | ||||||
|  |   longmove(@par_keys, @dpin, 4) | ||||||
|  |   okay := cog := cognew(@entry, @par_tail) + 1 | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB stop | ||||||
|  |  | ||||||
|  | '' Stop keyboard driver - frees a cog | ||||||
|  |  | ||||||
|  |   if cog | ||||||
|  |     cogstop(cog~ -  1) | ||||||
|  |   longfill(@par_tail, 0, 19) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB present : truefalse | ||||||
|  |  | ||||||
|  | '' Check if keyboard present - valid ~2s after start | ||||||
|  | '' returns t|f | ||||||
|  |  | ||||||
|  |   truefalse := -par_present | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB key : keycode | ||||||
|  |  | ||||||
|  | '' Get key (never waits) | ||||||
|  | '' returns key (0 if buffer empty) | ||||||
|  |  | ||||||
|  |   if par_tail <> par_head | ||||||
|  |     keycode := par_keys.word[par_tail] | ||||||
|  |     par_tail := ++par_tail & $F | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB getkey : keycode | ||||||
|  |  | ||||||
|  | '' Get next key (may wait for keypress) | ||||||
|  | '' returns key | ||||||
|  |  | ||||||
|  |   repeat until (keycode := key) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB newkey : keycode | ||||||
|  |  | ||||||
|  | '' Clear buffer and get new key (always waits for keypress) | ||||||
|  | '' returns key | ||||||
|  |  | ||||||
|  |   par_tail := par_head | ||||||
|  |   keycode := getkey | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB gotkey : truefalse | ||||||
|  |  | ||||||
|  | '' Check if any key in buffer | ||||||
|  | '' returns t|f | ||||||
|  |  | ||||||
|  |   truefalse := par_tail <> par_head | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB clearkeys | ||||||
|  |  | ||||||
|  | '' Clear key buffer | ||||||
|  |  | ||||||
|  |   par_tail := par_head | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB keystate(k) : state | ||||||
|  |  | ||||||
|  | '' Get the state of a particular key | ||||||
|  | '' returns t|f | ||||||
|  |  | ||||||
|  |   state := -(par_states[k >> 5] >> k & 1) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | DAT | ||||||
|  |  | ||||||
|  | '****************************************** | ||||||
|  | '* Assembly language PS/2 keyboard driver * | ||||||
|  | '****************************************** | ||||||
|  |  | ||||||
|  |                         org | ||||||
|  | ' | ||||||
|  | ' | ||||||
|  | ' Entry | ||||||
|  | ' | ||||||
|  | entry                   movd    :par,#_dpin             'load input parameters _dpin/_cpin/_locks/_auto | ||||||
|  |                         mov     x,par | ||||||
|  |                         add     x,#11*4 | ||||||
|  |                         mov     y,#4 | ||||||
|  | :par                    rdlong  0,x | ||||||
|  |                         add     :par,dlsb | ||||||
|  |                         add     x,#4 | ||||||
|  |                         djnz    y,#:par | ||||||
|  |  | ||||||
|  |                         mov     dmask,#1                'set pin masks | ||||||
|  |                         shl     dmask,_dpin | ||||||
|  |                         mov     cmask,#1 | ||||||
|  |                         shl     cmask,_cpin | ||||||
|  |  | ||||||
|  |                         test    _dpin,#$20      wc      'modify port registers within code | ||||||
|  |                         muxc    _d1,dlsb | ||||||
|  |                         muxc    _d2,dlsb | ||||||
|  |                         muxc    _d3,#1 | ||||||
|  |                         muxc    _d4,#1 | ||||||
|  |                         test    _cpin,#$20      wc | ||||||
|  |                         muxc    _c1,dlsb | ||||||
|  |                         muxc    _c2,dlsb | ||||||
|  |                         muxc    _c3,#1 | ||||||
|  |  | ||||||
|  |                         mov     _head,#0                'reset output parameter _head | ||||||
|  | ' | ||||||
|  | ' | ||||||
|  | ' Reset keyboard | ||||||
|  | ' | ||||||
|  | reset                   mov     dira,#0                 'reset directions | ||||||
|  |                         mov     dirb,#0 | ||||||
|  |  | ||||||
|  |                         movd    :par,#_present          'reset output parameters _present/_states[8] | ||||||
|  |                         mov     x,#1+8 | ||||||
|  | :par                    mov     0,#0 | ||||||
|  |                         add     :par,dlsb | ||||||
|  |                         djnz    x,#:par | ||||||
|  |  | ||||||
|  |                         mov     stat,#8                 'set reset flag | ||||||
|  | ' | ||||||
|  | ' | ||||||
|  | ' Update parameters | ||||||
|  | ' | ||||||
|  | update                  movd    :par,#_head             'update output parameters _head/_present/_states[8] | ||||||
|  |                         mov     x,par | ||||||
|  |                         add     x,#1*4 | ||||||
|  |                         mov     y,#1+1+8 | ||||||
|  | :par                    wrlong  0,x | ||||||
|  |                         add     :par,dlsb | ||||||
|  |                         add     x,#4 | ||||||
|  |                         djnz    y,#:par | ||||||
|  |  | ||||||
|  |                         test    stat,#8         wc      'if reset flag, transmit reset command | ||||||
|  |         if_c            mov     data,#$FF | ||||||
|  |         if_c            call    #transmit | ||||||
|  | ' | ||||||
|  | ' | ||||||
|  | ' Get scancode | ||||||
|  | ' | ||||||
|  | newcode                 mov     stat,#0                 'reset state | ||||||
|  |  | ||||||
|  | :same                   call    #receive                'receive byte from keyboard | ||||||
|  |  | ||||||
|  |                         cmp     data,#$83+1     wc      'scancode? | ||||||
|  |  | ||||||
|  |         if_nc           cmp     data,#$AA       wz      'powerup/reset? | ||||||
|  |         if_nc_and_z     jmp     #configure | ||||||
|  |  | ||||||
|  |         if_nc           cmp     data,#$E0       wz      'extended? | ||||||
|  |         if_nc_and_z     or      stat,#1 | ||||||
|  |         if_nc_and_z     jmp     #:same | ||||||
|  |  | ||||||
|  |         if_nc           cmp     data,#$F0       wz      'released? | ||||||
|  |         if_nc_and_z     or      stat,#2 | ||||||
|  |         if_nc_and_z     jmp     #:same | ||||||
|  |  | ||||||
|  |         if_nc           jmp     #newcode                'unknown, ignore | ||||||
|  | ' | ||||||
|  | ' | ||||||
|  | ' Translate scancode and enter into buffer | ||||||
|  | ' | ||||||
|  |                         test    stat,#1         wc      'lookup code with extended flag | ||||||
|  |                         rcl     data,#1 | ||||||
|  |                         call    #look | ||||||
|  |  | ||||||
|  |                         cmp     data,#0         wz      'if unknown, ignore | ||||||
|  |         if_z            jmp     #newcode | ||||||
|  |  | ||||||
|  |                         mov     t,_states+6             'remember lock keys in _states | ||||||
|  |  | ||||||
|  |                         mov     x,data                  'set/clear key bit in _states | ||||||
|  |                         shr     x,#5 | ||||||
|  |                         add     x,#_states | ||||||
|  |                         movd    :reg,x | ||||||
|  |                         mov     y,#1 | ||||||
|  |                         shl     y,data | ||||||
|  |                         test    stat,#2         wc | ||||||
|  | :reg                    muxnc   0,y | ||||||
|  |  | ||||||
|  |         if_nc           cmpsub  data,#$F0       wc      'if released or shift/ctrl/alt/win, done | ||||||
|  |         if_c            jmp     #update | ||||||
|  |  | ||||||
|  |                         mov     y,_states+7             'get shift/ctrl/alt/win bit pairs | ||||||
|  |                         shr     y,#16 | ||||||
|  |  | ||||||
|  |                         cmpsub  data,#$E0       wc      'translate keypad, considering numlock | ||||||
|  |         if_c            test    _locks,#%100    wz | ||||||
|  |         if_c_and_z      add     data,#@keypad1-@table | ||||||
|  |         if_c_and_nz     add     data,#@keypad2-@table | ||||||
|  |         if_c            call    #look | ||||||
|  |         if_c            jmp     #:flags | ||||||
|  |  | ||||||
|  |                         cmpsub  data,#$DD       wc      'handle scrlock/capslock/numlock | ||||||
|  |         if_c            mov     x,#%001_000 | ||||||
|  |         if_c            shl     x,data | ||||||
|  |         if_c            andn    x,_locks | ||||||
|  |         if_c            shr     x,#3 | ||||||
|  |         if_c            shr     t,#29                   'ignore auto-repeat | ||||||
|  |         if_c            andn    x,t             wz | ||||||
|  |         if_c            xor     _locks,x | ||||||
|  |         if_c            add     data,#$DD | ||||||
|  |         if_c_and_nz     or      stat,#4                 'if change, set configure flag to update leds | ||||||
|  |  | ||||||
|  |                         test    y,#%11          wz      'get shift into nz | ||||||
|  |  | ||||||
|  |         if_nz           cmp     data,#$60+1     wc      'check shift1 | ||||||
|  |         if_nz_and_c     cmpsub  data,#$5B       wc | ||||||
|  |         if_nz_and_c     add     data,#@shift1-@table | ||||||
|  |         if_nz_and_c     call    #look | ||||||
|  |         if_nz_and_c     andn    y,#%11 | ||||||
|  |  | ||||||
|  |         if_nz           cmp     data,#$3D+1     wc      'check shift2 | ||||||
|  |         if_nz_and_c     cmpsub  data,#$27       wc | ||||||
|  |         if_nz_and_c     add     data,#@shift2-@table | ||||||
|  |         if_nz_and_c     call    #look | ||||||
|  |         if_nz_and_c     andn    y,#%11 | ||||||
|  |  | ||||||
|  |                         test    _locks,#%010    wc      'check shift-alpha, considering capslock | ||||||
|  |                         muxnc   :shift,#$20 | ||||||
|  |                         test    _locks,#$40     wc | ||||||
|  |         if_nz_and_nc    xor     :shift,#$20 | ||||||
|  |                         cmp     data,#"z"+1     wc | ||||||
|  |         if_c            cmpsub  data,#"a"       wc | ||||||
|  | :shift  if_c            add     data,#"A" | ||||||
|  |         if_c            andn    y,#%11 | ||||||
|  |  | ||||||
|  | :flags                  ror     data,#8                 'add shift/ctrl/alt/win flags | ||||||
|  |                         mov     x,#4                    '+$100 if shift | ||||||
|  | :loop                   test    y,#%11          wz      '+$200 if ctrl | ||||||
|  |                         shr     y,#2                    '+$400 if alt | ||||||
|  |         if_nz           or      data,#1                 '+$800 if win | ||||||
|  |                         ror     data,#1 | ||||||
|  |                         djnz    x,#:loop | ||||||
|  |                         rol     data,#12 | ||||||
|  |  | ||||||
|  |                         rdlong  x,par                   'if room in buffer and key valid, enter | ||||||
|  |                         sub     x,#1 | ||||||
|  |                         and     x,#$F | ||||||
|  |                         cmp     x,_head         wz | ||||||
|  |         if_nz           test    data,#$FF       wz | ||||||
|  |         if_nz           mov     x,par | ||||||
|  |         if_nz           add     x,#11*4 | ||||||
|  |         if_nz           add     x,_head | ||||||
|  |         if_nz           add     x,_head | ||||||
|  |         if_nz           wrword  data,x | ||||||
|  |         if_nz           add     _head,#1 | ||||||
|  |         if_nz           and     _head,#$F | ||||||
|  |  | ||||||
|  |                         test    stat,#4         wc      'if not configure flag, done | ||||||
|  |         if_nc           jmp     #update                 'else configure to update leds | ||||||
|  | ' | ||||||
|  | ' | ||||||
|  | ' Configure keyboard | ||||||
|  | ' | ||||||
|  | configure               mov     data,#$F3               'set keyboard auto-repeat | ||||||
|  |                         call    #transmit | ||||||
|  |                         mov     data,_auto | ||||||
|  |                         and     data,#%11_11111 | ||||||
|  |                         call    #transmit | ||||||
|  |  | ||||||
|  |                         mov     data,#$ED               'set keyboard lock-leds | ||||||
|  |                         call    #transmit | ||||||
|  |                         mov     data,_locks | ||||||
|  |                         rev     data,#-3 & $1F | ||||||
|  |                         test    data,#%100      wc | ||||||
|  |                         rcl     data,#1 | ||||||
|  |                         and     data,#%111 | ||||||
|  |                         call    #transmit | ||||||
|  |  | ||||||
|  |                         mov     x,_locks                'insert locks into _states | ||||||
|  |                         and     x,#%111 | ||||||
|  |                         shl     _states+7,#3 | ||||||
|  |                         or      _states+7,x | ||||||
|  |                         ror     _states+7,#3 | ||||||
|  |  | ||||||
|  |                         mov     _present,#1             'set _present | ||||||
|  |  | ||||||
|  |                         jmp     #update                 'done | ||||||
|  | ' | ||||||
|  | ' | ||||||
|  | ' Lookup byte in table | ||||||
|  | ' | ||||||
|  | look                    ror     data,#2                 'perform lookup | ||||||
|  |                         movs    :reg,data | ||||||
|  |                         add     :reg,#table | ||||||
|  |                         shr     data,#27 | ||||||
|  |                         mov     x,data | ||||||
|  | :reg                    mov     data,0 | ||||||
|  |                         shr     data,x | ||||||
|  |  | ||||||
|  |                         jmp     #rand                   'isolate byte | ||||||
|  | ' | ||||||
|  | ' | ||||||
|  | ' Transmit byte to keyboard | ||||||
|  | ' | ||||||
|  | transmit | ||||||
|  | _c1                     or      dira,cmask              'pull clock low | ||||||
|  |                         movs    napshr,#13              'hold clock for ~128us (must be >100us) | ||||||
|  |                         call    #nap | ||||||
|  | _d1                     or      dira,dmask              'pull data low | ||||||
|  |                         movs    napshr,#18              'hold data for ~4us | ||||||
|  |                         call    #nap | ||||||
|  | _c2                     xor     dira,cmask              'release clock | ||||||
|  |  | ||||||
|  |                         test    data,#$0FF      wc      'append parity and stop bits to byte | ||||||
|  |                         muxnc   data,#$100 | ||||||
|  |                         or      data,dlsb | ||||||
|  |  | ||||||
|  |                         mov     x,#10                   'ready 10 bits | ||||||
|  | transmit_bit            call    #wait_c0                'wait until clock low | ||||||
|  |                         shr     data,#1         wc      'output data bit | ||||||
|  | _d2                     muxnc   dira,dmask | ||||||
|  |                         mov     wcond,c1                'wait until clock high | ||||||
|  |                         call    #wait | ||||||
|  |                         djnz    x,#transmit_bit         'another bit? | ||||||
|  |  | ||||||
|  |                         mov     wcond,c0d0              'wait until clock and data low | ||||||
|  |                         call    #wait | ||||||
|  |                         mov     wcond,c1d1              'wait until clock and data high | ||||||
|  |                         call    #wait | ||||||
|  |  | ||||||
|  |                         call    #receive_ack            'receive ack byte with timed wait | ||||||
|  |                         cmp     data,#$FA       wz      'if ack error, reset keyboard | ||||||
|  |         if_nz           jmp     #reset | ||||||
|  |  | ||||||
|  | transmit_ret            ret | ||||||
|  | ' | ||||||
|  | ' | ||||||
|  | ' Receive byte from keyboard | ||||||
|  | ' | ||||||
|  | receive                 test    _cpin,#$20      wc      'wait indefinitely for initial clock low | ||||||
|  |                         waitpne cmask,cmask | ||||||
|  | receive_ack | ||||||
|  |                         mov     x,#11                   'ready 11 bits | ||||||
|  | receive_bit             call    #wait_c0                'wait until clock low | ||||||
|  |                         movs    napshr,#16              'pause ~16us | ||||||
|  |                         call    #nap | ||||||
|  | _d3                     test    dmask,ina       wc      'input data bit | ||||||
|  |                         rcr     data,#1 | ||||||
|  |                         mov     wcond,c1                'wait until clock high | ||||||
|  |                         call    #wait | ||||||
|  |                         djnz    x,#receive_bit          'another bit? | ||||||
|  |  | ||||||
|  |                         shr     data,#22                'align byte | ||||||
|  |                         test    data,#$1FF      wc      'if parity error, reset keyboard | ||||||
|  |         if_nc           jmp     #reset | ||||||
|  | rand                    and     data,#$FF               'isolate byte | ||||||
|  |  | ||||||
|  | look_ret | ||||||
|  | receive_ack_ret | ||||||
|  | receive_ret             ret | ||||||
|  | ' | ||||||
|  | ' | ||||||
|  | ' Wait for clock/data to be in required state(s) | ||||||
|  | ' | ||||||
|  | wait_c0                 mov     wcond,c0                '(wait until clock low) | ||||||
|  |  | ||||||
|  | wait                    mov     y,tenms                 'set timeout to 10ms | ||||||
|  |  | ||||||
|  | wloop                   movs    napshr,#18              'nap ~4us | ||||||
|  |                         call    #nap | ||||||
|  | _c3                     test    cmask,ina       wc      'check required state(s) | ||||||
|  | _d4                     test    dmask,ina       wz      'loop until got state(s) or timeout | ||||||
|  | wcond   if_never        djnz    y,#wloop                '(replaced with c0/c1/c0d0/c1d1) | ||||||
|  |  | ||||||
|  |                         tjz     y,#reset                'if timeout, reset keyboard | ||||||
|  | wait_ret | ||||||
|  | wait_c0_ret             ret | ||||||
|  |  | ||||||
|  |  | ||||||
|  | c0      if_c            djnz    y,#wloop                '(if_never replacements) | ||||||
|  | c1      if_nc           djnz    y,#wloop | ||||||
|  | c0d0    if_c_or_nz      djnz    y,#wloop | ||||||
|  | c1d1    if_nc_or_z      djnz    y,#wloop | ||||||
|  | ' | ||||||
|  | ' | ||||||
|  | ' Nap | ||||||
|  | ' | ||||||
|  | nap                     rdlong  t,#0                    'get clkfreq | ||||||
|  | napshr                  shr     t,#18/16/13             'shr scales time | ||||||
|  |                         min     t,#3                    'ensure waitcnt won't snag | ||||||
|  |                         add     t,cnt                   'add cnt to time | ||||||
|  |                         waitcnt t,#0                    'wait until time elapses (nap) | ||||||
|  |  | ||||||
|  | nap_ret                 ret | ||||||
|  | ' | ||||||
|  | ' | ||||||
|  | ' Initialized data | ||||||
|  | ' | ||||||
|  | ' | ||||||
|  | dlsb                    long    1 << 9 | ||||||
|  | tenms                   long    10_000 / 4 | ||||||
|  | ' | ||||||
|  | ' | ||||||
|  | ' Lookup table | ||||||
|  | '                               ascii   scan    extkey  regkey  ()=keypad | ||||||
|  | ' | ||||||
|  | table                   word    $0000   '00 | ||||||
|  |                         word    $00D8   '01             F9 | ||||||
|  |                         word    $0000   '02 | ||||||
|  |                         word    $00D4   '03             F5 | ||||||
|  |                         word    $00D2   '04             F3 | ||||||
|  |                         word    $00D0   '05             F1 | ||||||
|  |                         word    $00D1   '06             F2 | ||||||
|  |                         word    $00DB   '07             F12 | ||||||
|  |                         word    $0000   '08 | ||||||
|  |                         word    $00D9   '09             F10 | ||||||
|  |                         word    $00D7   '0A             F8 | ||||||
|  |                         word    $00D5   '0B             F6 | ||||||
|  |                         word    $00D3   '0C             F4 | ||||||
|  |                         word    $0009   '0D             Tab | ||||||
|  |                         word    $0060   '0E             ` | ||||||
|  |                         word    $0000   '0F | ||||||
|  |                         word    $0000   '10 | ||||||
|  |                         word    $F5F4   '11     Alt-R   Alt-L | ||||||
|  |                         word    $00F0   '12             Shift-L | ||||||
|  |                         word    $0000   '13 | ||||||
|  |                         word    $F3F2   '14     Ctrl-R  Ctrl-L | ||||||
|  |                         word    $0071   '15             q | ||||||
|  |                         word    $0031   '16             1 | ||||||
|  |                         word    $0000   '17 | ||||||
|  |                         word    $0000   '18 | ||||||
|  |                         word    $0000   '19 | ||||||
|  |                         word    $007A   '1A             z | ||||||
|  |                         word    $0073   '1B             s | ||||||
|  |                         word    $0061   '1C             a | ||||||
|  |                         word    $0077   '1D             w | ||||||
|  |                         word    $0032   '1E             2 | ||||||
|  |                         word    $F600   '1F     Win-L | ||||||
|  |                         word    $0000   '20 | ||||||
|  |                         word    $0063   '21             c | ||||||
|  |                         word    $0078   '22             x | ||||||
|  |                         word    $0064   '23             d | ||||||
|  |                         word    $0065   '24             e | ||||||
|  |                         word    $0034   '25             4 | ||||||
|  |                         word    $0033   '26             3 | ||||||
|  |                         word    $F700   '27     Win-R | ||||||
|  |                         word    $0000   '28 | ||||||
|  |                         word    $0020   '29             Space | ||||||
|  |                         word    $0076   '2A             v | ||||||
|  |                         word    $0066   '2B             f | ||||||
|  |                         word    $0074   '2C             t | ||||||
|  |                         word    $0072   '2D             r | ||||||
|  |                         word    $0035   '2E             5 | ||||||
|  |                         word    $CC00   '2F     Apps | ||||||
|  |                         word    $0000   '30 | ||||||
|  |                         word    $006E   '31             n | ||||||
|  |                         word    $0062   '32             b | ||||||
|  |                         word    $0068   '33             h | ||||||
|  |                         word    $0067   '34             g | ||||||
|  |                         word    $0079   '35             y | ||||||
|  |                         word    $0036   '36             6 | ||||||
|  |                         word    $CD00   '37     Power | ||||||
|  |                         word    $0000   '38 | ||||||
|  |                         word    $0000   '39 | ||||||
|  |                         word    $006D   '3A             m | ||||||
|  |                         word    $006A   '3B             j | ||||||
|  |                         word    $0075   '3C             u | ||||||
|  |                         word    $0037   '3D             7 | ||||||
|  |                         word    $0038   '3E             8 | ||||||
|  |                         word    $CE00   '3F     Sleep | ||||||
|  |                         word    $0000   '40 | ||||||
|  |                         word    $002C   '41             , | ||||||
|  |                         word    $006B   '42             k | ||||||
|  |                         word    $0069   '43             i | ||||||
|  |                         word    $006F   '44             o | ||||||
|  |                         word    $0030   '45             0 | ||||||
|  |                         word    $0039   '46             9 | ||||||
|  |                         word    $0000   '47 | ||||||
|  |                         word    $0000   '48 | ||||||
|  |                         word    $002E   '49             . | ||||||
|  |                         word    $EF2F   '4A     (/)     / | ||||||
|  |                         word    $006C   '4B             l | ||||||
|  |                         word    $003B   '4C             ; | ||||||
|  |                         word    $0070   '4D             p | ||||||
|  |                         word    $002D   '4E             - | ||||||
|  |                         word    $0000   '4F | ||||||
|  |                         word    $0000   '50 | ||||||
|  |                         word    $0000   '51 | ||||||
|  |                         word    $0027   '52             ' | ||||||
|  |                         word    $0000   '53 | ||||||
|  |                         word    $005B   '54             [ | ||||||
|  |                         word    $003D   '55             = | ||||||
|  |                         word    $0000   '56 | ||||||
|  |                         word    $0000   '57 | ||||||
|  |                         word    $00DE   '58             CapsLock | ||||||
|  |                         word    $00F1   '59             Shift-R | ||||||
|  |                         word    $EB0D   '5A     (Enter) Enter | ||||||
|  |                         word    $005D   '5B             ] | ||||||
|  |                         word    $0000   '5C | ||||||
|  |                         word    $005C   '5D             \ | ||||||
|  |                         word    $CF00   '5E     WakeUp | ||||||
|  |                         word    $0000   '5F | ||||||
|  |                         word    $0000   '60 | ||||||
|  |                         word    $0000   '61 | ||||||
|  |                         word    $0000   '62 | ||||||
|  |                         word    $0000   '63 | ||||||
|  |                         word    $0000   '64 | ||||||
|  |                         word    $0000   '65 | ||||||
|  |                         word    $00C8   '66             BackSpace | ||||||
|  |                         word    $0000   '67 | ||||||
|  |                         word    $0000   '68 | ||||||
|  |                         word    $C5E1   '69     End     (1) | ||||||
|  |                         word    $0000   '6A | ||||||
|  |                         word    $C0E4   '6B     Left    (4) | ||||||
|  |                         word    $C4E7   '6C     Home    (7) | ||||||
|  |                         word    $0000   '6D | ||||||
|  |                         word    $0000   '6E | ||||||
|  |                         word    $0000   '6F | ||||||
|  |                         word    $CAE0   '70     Insert  (0) | ||||||
|  |                         word    $C9EA   '71     Delete  (.) | ||||||
|  |                         word    $C3E2   '72     Down    (2) | ||||||
|  |                         word    $00E5   '73             (5) | ||||||
|  |                         word    $C1E6   '74     Right   (6) | ||||||
|  |                         word    $C2E8   '75     Up      (8) | ||||||
|  |                         word    $00CB   '76             Esc | ||||||
|  |                         word    $00DF   '77             NumLock | ||||||
|  |                         word    $00DA   '78             F11 | ||||||
|  |                         word    $00EC   '79             (+) | ||||||
|  |                         word    $C7E3   '7A     PageDn  (3) | ||||||
|  |                         word    $00ED   '7B             (-) | ||||||
|  |                         word    $DCEE   '7C     PrScr   (*) | ||||||
|  |                         word    $C6E9   '7D     PageUp  (9) | ||||||
|  |                         word    $00DD   '7E             ScrLock | ||||||
|  |                         word    $0000   '7F | ||||||
|  |                         word    $0000   '80 | ||||||
|  |                         word    $0000   '81 | ||||||
|  |                         word    $0000   '82 | ||||||
|  |                         word    $00D6   '83             F7 | ||||||
|  |  | ||||||
|  | keypad1                 byte    $CA, $C5, $C3, $C7, $C0, 0, $C1, $C4, $C2, $C6, $C9, $0D, "+-*/" | ||||||
|  |  | ||||||
|  | keypad2                 byte    "0123456789.", $0D, "+-*/" | ||||||
|  |  | ||||||
|  | shift1                  byte    "{|}", 0, 0, "~" | ||||||
|  |  | ||||||
|  | shift2                  byte    $22, 0, 0, 0, 0, "<_>?)!@#$%^&*(", 0, ":", 0, "+" | ||||||
|  | ' | ||||||
|  | ' | ||||||
|  | ' Uninitialized data | ||||||
|  | ' | ||||||
|  | dmask                   res     1 | ||||||
|  | cmask                   res     1 | ||||||
|  | stat                    res     1 | ||||||
|  | data                    res     1 | ||||||
|  | x                       res     1 | ||||||
|  | y                       res     1 | ||||||
|  | t                       res     1 | ||||||
|  |  | ||||||
|  | _head                   res     1       'write-only | ||||||
|  | _present                res     1       'write-only | ||||||
|  | _states                 res     8       'write-only | ||||||
|  | _dpin                   res     1       'read-only at start | ||||||
|  | _cpin                   res     1       'read-only at start | ||||||
|  | _locks                  res     1       'read-only at start | ||||||
|  | _auto                   res     1       'read-only at start | ||||||
|  |  | ||||||
|  | '' | ||||||
|  | '' | ||||||
|  | ''      _________ | ||||||
|  | ''      Key Codes | ||||||
|  | '' | ||||||
|  | ''      00..DF  = keypress and keystate | ||||||
|  | ''      E0..FF  = keystate only | ||||||
|  | '' | ||||||
|  | '' | ||||||
|  | ''      09      Tab | ||||||
|  | ''      0D      Enter | ||||||
|  | ''      20      Space | ||||||
|  | ''      21      ! | ||||||
|  | ''      22      " | ||||||
|  | ''      23      # | ||||||
|  | ''      24      $ | ||||||
|  | ''      25      % | ||||||
|  | ''      26      & | ||||||
|  | ''      27      ' | ||||||
|  | ''      28      ( | ||||||
|  | ''      29      ) | ||||||
|  | ''      2A      * | ||||||
|  | ''      2B      + | ||||||
|  | ''      2C      , | ||||||
|  | ''      2D      - | ||||||
|  | ''      2E      . | ||||||
|  | ''      2F      / | ||||||
|  | ''      30      0..9 | ||||||
|  | ''      3A      : | ||||||
|  | ''      3B      ; | ||||||
|  | ''      3C      < | ||||||
|  | ''      3D      = | ||||||
|  | ''      3E      > | ||||||
|  | ''      3F      ? | ||||||
|  | ''      40      @        | ||||||
|  | ''      41..5A  A..Z | ||||||
|  | ''      5B      [ | ||||||
|  | ''      5C      \ | ||||||
|  | ''      5D      ] | ||||||
|  | ''      5E      ^ | ||||||
|  | ''      5F      _ | ||||||
|  | ''      60      ` | ||||||
|  | ''      61..7A  a..z | ||||||
|  | ''      7B      { | ||||||
|  | ''      7C      | | ||||||
|  | ''      7D      } | ||||||
|  | ''      7E      ~ | ||||||
|  | '' | ||||||
|  | ''      80-BF   (future international character support) | ||||||
|  | '' | ||||||
|  | ''      C0      Left Arrow | ||||||
|  | ''      C1      Right Arrow | ||||||
|  | ''      C2      Up Arrow | ||||||
|  | ''      C3      Down Arrow | ||||||
|  | ''      C4      Home | ||||||
|  | ''      C5      End | ||||||
|  | ''      C6      Page Up | ||||||
|  | ''      C7      Page Down | ||||||
|  | ''      C8      Backspace | ||||||
|  | ''      C9      Delete | ||||||
|  | ''      CA      Insert | ||||||
|  | ''      CB      Esc | ||||||
|  | ''      CC      Apps | ||||||
|  | ''      CD      Power | ||||||
|  | ''      CE      Sleep | ||||||
|  | ''      CF      Wakeup | ||||||
|  | '' | ||||||
|  | ''      D0..DB  F1..F12 | ||||||
|  | ''      DC      Print Screen | ||||||
|  | ''      DD      Scroll Lock | ||||||
|  | ''      DE      Caps Lock | ||||||
|  | ''      DF      Num Lock | ||||||
|  | '' | ||||||
|  | ''      E0..E9  Keypad 0..9 | ||||||
|  | ''      EA      Keypad . | ||||||
|  | ''      EB      Keypad Enter | ||||||
|  | ''      EC      Keypad + | ||||||
|  | ''      ED      Keypad - | ||||||
|  | ''      EE      Keypad * | ||||||
|  | ''      EF      Keypad / | ||||||
|  | '' | ||||||
|  | ''      F0      Left Shift | ||||||
|  | ''      F1      Right Shift | ||||||
|  | ''      F2      Left Ctrl | ||||||
|  | ''      F3      Right Ctrl | ||||||
|  | ''      F4      Left Alt | ||||||
|  | ''      F5      Right Alt | ||||||
|  | ''      F6      Left Win | ||||||
|  | ''      F7      Right Win | ||||||
|  | '' | ||||||
|  | ''      FD      Scroll Lock State | ||||||
|  | ''      FE      Caps Lock State | ||||||
|  | ''      FF      Num Lock State | ||||||
|  | '' | ||||||
|  | ''      +100    if Shift | ||||||
|  | ''      +200    if Ctrl | ||||||
|  | ''      +400    if Alt | ||||||
|  | ''      +800    if Win | ||||||
|  | '' | ||||||
|  | ''      eg. Ctrl-Alt-Delete = $6C9 | ||||||
|  | '' | ||||||
|  | '' | ||||||
|  | '' Note: Driver will buffer up to 15 keystrokes, then ignore overflow. | ||||||
|  |  | ||||||
|  | {{ | ||||||
|  |  | ||||||
|  | ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ | ||||||
|  | │                                                   TERMS OF USE: MIT License                                                  │                                                             | ||||||
|  | ├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ | ||||||
|  | │Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation    │  | ||||||
|  | │files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,    │ | ||||||
|  | │modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ | ||||||
|  | │is furnished to do so, subject to the following conditions:                                                                   │ | ||||||
|  | │                                                                                                                              │ | ||||||
|  | │The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ | ||||||
|  | │                                                                                                                              │ | ||||||
|  | │THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE          │ | ||||||
|  | │WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR         │ | ||||||
|  | │COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,   │ | ||||||
|  | │ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                         │ | ||||||
|  | └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ | ||||||
|  | }} | ||||||
							
								
								
									
										711
									
								
								samples/Propeller Spin/TV.spin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										711
									
								
								samples/Propeller Spin/TV.spin
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,711 @@ | |||||||
|  | ''*************************************** | ||||||
|  | ''*  TV Driver v1.1                     * | ||||||
|  | ''*  Author: Chip Gracey                * | ||||||
|  | ''*  Copyright (c) 2004 Parallax, Inc.  *                | ||||||
|  | ''*  See end of file for terms of use.  *                | ||||||
|  | ''*************************************** | ||||||
|  |  | ||||||
|  | ' v1.0 - 01 May 2006 - original version | ||||||
|  | ' v1.1 - 17 May 2006 - pixel tile size can now be 16 x 32 to enable more efficient | ||||||
|  | '                       character displays utilizing the internal font - see 'tv_mode' | ||||||
|  |  | ||||||
|  |  | ||||||
|  | CON | ||||||
|  |  | ||||||
|  |   fntsc         = 3_579_545     'NTSC color frequency | ||||||
|  |   lntsc         = 3640          'NTSC color cycles per line * 16 | ||||||
|  |   sntsc         = 624           'NTSC color cycles per sync * 16 | ||||||
|  |  | ||||||
|  |   fpal          = 4_433_618     'PAL color frequency | ||||||
|  |   lpal          = 4540          'PAL color cycles per line * 16 | ||||||
|  |   spal          = 848           'PAL color cycles per sync * 16 | ||||||
|  |  | ||||||
|  |   paramcount    = 14 | ||||||
|  |   colortable    = $180          'start of colortable inside cog | ||||||
|  |    | ||||||
|  |  | ||||||
|  | VAR | ||||||
|  |  | ||||||
|  |   long  cog | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB start(tvptr) : okay | ||||||
|  |  | ||||||
|  | '' Start TV driver - starts a cog | ||||||
|  | '' returns false if no cog available | ||||||
|  | '' | ||||||
|  | ''   tvptr = pointer to TV parameters | ||||||
|  |  | ||||||
|  |   stop | ||||||
|  |   okay := cog := cognew(@entry, tvptr) + 1 | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB stop | ||||||
|  |  | ||||||
|  | '' Stop TV driver - frees a cog | ||||||
|  |  | ||||||
|  |   if cog | ||||||
|  |     cogstop(cog~ - 1) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | DAT | ||||||
|  |  | ||||||
|  | '******************************* | ||||||
|  | '* Assembly language TV driver * | ||||||
|  | '******************************* | ||||||
|  |  | ||||||
|  |                         org | ||||||
|  | ' | ||||||
|  | ' | ||||||
|  | ' Entry | ||||||
|  | ' | ||||||
|  | entry                   mov     taskptr,#tasks          'reset tasks | ||||||
|  |  | ||||||
|  |                         mov     x,#10                   'perform task sections initially | ||||||
|  | :init                   jmpret  taskret,taskptr | ||||||
|  |                         djnz    x,#:init | ||||||
|  | ' | ||||||
|  | ' | ||||||
|  | ' Superfield | ||||||
|  | ' | ||||||
|  | superfield              mov     taskptr,#tasks          'reset tasks | ||||||
|  |  | ||||||
|  |                         test    _mode,#%0001    wc      'if ntsc, set phaseflip | ||||||
|  |         if_nc           mov     phaseflip,phasemask | ||||||
|  |  | ||||||
|  |                         test    _mode,#%0010    wz      'get interlace into nz | ||||||
|  | ' | ||||||
|  | ' | ||||||
|  | ' Field | ||||||
|  | ' | ||||||
|  | field                   mov     x,vinv                  'do invisible back porch lines | ||||||
|  | :black                  call    #hsync                  'do hsync | ||||||
|  |                         waitvid burst,sync_high2        'do black | ||||||
|  |                         jmpret  taskret,taskptr         'call task section (z undisturbed) | ||||||
|  |                         djnz    x,#:black               'another black line? | ||||||
|  |  | ||||||
|  |                         wrlong  visible,par             'set status to visible | ||||||
|  |  | ||||||
|  |                         mov     x,vb                    'do visible back porch lines | ||||||
|  |                         call    #blank_lines | ||||||
|  |  | ||||||
|  |                         mov     screen,_screen          'point to first tile (upper-leftmost) | ||||||
|  |                         mov     y,_vt                   'set vertical tiles | ||||||
|  | :line                   mov     vx,_vx                  'set vertical expand | ||||||
|  | :vert   if_z            xor     interlace,#1            'interlace skip? | ||||||
|  |         if_z            tjz     interlace,#:skip | ||||||
|  |  | ||||||
|  |                         call    #hsync                  'do hsync | ||||||
|  |  | ||||||
|  |                         mov     vscl,hb                 'do visible back porch pixels | ||||||
|  |                         xor     tile,colortable | ||||||
|  |                         waitvid tile,#0 | ||||||
|  |  | ||||||
|  |                         mov     x,_ht                   'set horizontal tiles | ||||||
|  |                         mov     vscl,hx                 'set horizontal expand | ||||||
|  |  | ||||||
|  | :tile                   rdword  tile,screen             'read tile | ||||||
|  |                         or      tile,line               'set pointer bits into tile | ||||||
|  |                         rol     tile,#6                 'read tile pixels | ||||||
|  |                         rdlong  pixels,tile             '(2 instructions between reads) | ||||||
|  |                         shr     tile,#10+6              'set tile colors | ||||||
|  |                         movs    :color,tile | ||||||
|  |                         add     screen,#2               'point to next tile | ||||||
|  |                         mov     tile,phaseflip | ||||||
|  | :color                  xor     tile,colortable | ||||||
|  |                         waitvid tile,pixels             'pass colors and pixels to video | ||||||
|  |                         djnz    x,#:tile                'another tile? | ||||||
|  |  | ||||||
|  |                         sub     screen,hc2x             'repoint to first tile in same line | ||||||
|  |  | ||||||
|  |                         mov     vscl,hf                 'do visible front porch pixels | ||||||
|  |                         mov     tile,phaseflip | ||||||
|  |                         xor     tile,colortable | ||||||
|  |                         waitvid tile,#0 | ||||||
|  |  | ||||||
|  | :skip                   djnz    vx,#:vert               'vertical expand? | ||||||
|  |                         ror     line,linerot            'set next line | ||||||
|  |                         add     line,lineadd    wc | ||||||
|  |                         rol     line,linerot       | ||||||
|  |         if_nc           jmp     #:line | ||||||
|  |                         add     screen,hc2x             'point to first tile in next line | ||||||
|  |                         djnz    y,#:line                'another tile line? | ||||||
|  |  | ||||||
|  |         if_z            xor     interlace,#1    wz      'get interlace and field1 into z | ||||||
|  |  | ||||||
|  |                         test    _mode,#%0001    wc      'do visible front porch lines | ||||||
|  |                         mov     x,vf | ||||||
|  |         if_nz_and_c     add     x,#1 | ||||||
|  |                         call    #blank_lines | ||||||
|  |  | ||||||
|  |         if_nz           wrlong  invisible,par           'unless interlace and field1, set status to invisible | ||||||
|  |  | ||||||
|  |         if_z_eq_c       call    #hsync                  'if required, do short line | ||||||
|  |         if_z_eq_c       mov     vscl,hrest | ||||||
|  |         if_z_eq_c       waitvid burst,sync_high2 | ||||||
|  |         if_z_eq_c       xor     phaseflip,phasemask | ||||||
|  |  | ||||||
|  |                         call    #vsync_high             'do high vsync pulses | ||||||
|  |  | ||||||
|  |                         movs    vsync1,#sync_low1       'do low vsync pulses | ||||||
|  |                         movs    vsync2,#sync_low2 | ||||||
|  |                         call    #vsync_low | ||||||
|  |  | ||||||
|  |                         call    #vsync_high             'do high vsync pulses | ||||||
|  |  | ||||||
|  |         if_nz           mov     vscl,hhalf              'if odd frame, do half line | ||||||
|  |         if_nz           waitvid burst,sync_high2 | ||||||
|  |  | ||||||
|  |         if_z            jmp     #field                  'if interlace and field1, display field2 | ||||||
|  |                         jmp     #superfield             'else, new superfield | ||||||
|  | ' | ||||||
|  | ' | ||||||
|  | ' Blank lines | ||||||
|  | ' | ||||||
|  | blank_lines             call    #hsync                  'do hsync | ||||||
|  |  | ||||||
|  |                         xor     tile,colortable         'do background | ||||||
|  |                         waitvid tile,#0 | ||||||
|  |  | ||||||
|  |                         djnz    x,#blank_lines | ||||||
|  |  | ||||||
|  | blank_lines_ret         ret | ||||||
|  | ' | ||||||
|  | ' | ||||||
|  | ' Horizontal sync | ||||||
|  | ' | ||||||
|  | hsync                   test    _mode,#%0001    wc      'if pal, toggle phaseflip | ||||||
|  |         if_c            xor     phaseflip,phasemask | ||||||
|  |  | ||||||
|  |                         mov     vscl,sync_scale1        'do hsync        | ||||||
|  |                         mov     tile,phaseflip | ||||||
|  |                         xor     tile,burst | ||||||
|  |                         waitvid tile,sync_normal | ||||||
|  |  | ||||||
|  |                         mov     vscl,hvis               'setup in case blank line | ||||||
|  |                         mov     tile,phaseflip | ||||||
|  |  | ||||||
|  | hsync_ret               ret | ||||||
|  | ' | ||||||
|  | ' | ||||||
|  | ' Vertical sync | ||||||
|  | ' | ||||||
|  | vsync_high              movs    vsync1,#sync_high1      'vertical sync | ||||||
|  |                         movs    vsync2,#sync_high2 | ||||||
|  |  | ||||||
|  | vsync_low               mov     x,vrep | ||||||
|  |  | ||||||
|  | vsyncx                  mov     vscl,sync_scale1 | ||||||
|  | vsync1                  waitvid burst,sync_high1 | ||||||
|  |  | ||||||
|  |                         mov     vscl,sync_scale2 | ||||||
|  | vsync2                  waitvid burst,sync_high2 | ||||||
|  |  | ||||||
|  |                         djnz    x,#vsyncx | ||||||
|  | vsync_low_ret | ||||||
|  | vsync_high_ret          ret | ||||||
|  | ' | ||||||
|  | ' | ||||||
|  | ' Tasks - performed in sections during invisible back porch lines | ||||||
|  | ' | ||||||
|  | tasks                   mov     t1,par                  'load parameters | ||||||
|  |                         movd    :par,#_enable           '(skip _status) | ||||||
|  |                         mov     t2,#paramcount - 1 | ||||||
|  | :load                   add     t1,#4 | ||||||
|  | :par                    rdlong  0,t1 | ||||||
|  |                         add     :par,d0 | ||||||
|  |                         djnz    t2,#:load               '+119 | ||||||
|  |  | ||||||
|  |                         mov     t1,_pins                'set video pins and directions | ||||||
|  |                         test    t1,#$08         wc | ||||||
|  |         if_nc           mov     t2,pins0 | ||||||
|  |         if_c            mov     t2,pins1 | ||||||
|  |                         test    t1,#$40         wc | ||||||
|  |                         shr     t1,#1 | ||||||
|  |                         shl     t1,#3 | ||||||
|  |                         shr     t2,t1 | ||||||
|  |                         movs    vcfg,t2 | ||||||
|  |                         shr     t1,#6 | ||||||
|  |                         movd    vcfg,t1 | ||||||
|  |                         shl     t1,#3 | ||||||
|  |                         and     t2,#$FF | ||||||
|  |                         shl     t2,t1 | ||||||
|  |         if_nc           mov     dira,t2 | ||||||
|  |         if_nc           mov     dirb,#0 | ||||||
|  |         if_c            mov     dira,#0 | ||||||
|  |         if_c            mov     dirb,t2                 '+18 | ||||||
|  |  | ||||||
|  |                         tjz     _enable,#disabled       '+2, disabled? | ||||||
|  |  | ||||||
|  |                         jmpret  taskptr,taskret         '+1=140, break and return later | ||||||
|  |  | ||||||
|  |                         movs    :rd,#wtab               'load ntsc/pal metrics from word table | ||||||
|  |                         movd    :wr,#hvis | ||||||
|  |                         mov     t1,#wtabx - wtab | ||||||
|  |                         test    _mode,#%0001    wc | ||||||
|  | :rd                     mov     t2,0 | ||||||
|  |                         add     :rd,#1 | ||||||
|  |         if_nc           shl     t2,#16 | ||||||
|  |                         shr     t2,#16 | ||||||
|  | :wr                     mov     0,t2 | ||||||
|  |                         add     :wr,d0 | ||||||
|  |                         djnz    t1,#:rd                 '+54 | ||||||
|  |  | ||||||
|  |         if_nc           movs    :ltab,#ltab             'load ntsc/pal metrics from long table | ||||||
|  |         if_c            movs    :ltab,#ltab+1 | ||||||
|  |                         movd    :ltab,#fcolor | ||||||
|  |                         mov     t1,#(ltabx - ltab) >> 1 | ||||||
|  | :ltab                   mov     0,0 | ||||||
|  |                         add     :ltab,d0s1 | ||||||
|  |                         djnz    t1,#:ltab               '+17 | ||||||
|  |  | ||||||
|  |                         rdlong  t1,#0                   'get CLKFREQ | ||||||
|  |                         shr     t1,#1                   'if CLKFREQ < 16MHz, cancel _broadcast | ||||||
|  |                         cmp     t1,m8           wc | ||||||
|  |         if_c            mov     _broadcast,#0 | ||||||
|  |                         shr     t1,#1                   'if CLKFREQ < color frequency * 4, disable | ||||||
|  |                         cmp     t1,fcolor       wc | ||||||
|  |         if_c            jmp     #disabled               '+11 | ||||||
|  |  | ||||||
|  |                         jmpret  taskptr,taskret         '+1=83, break and return later | ||||||
|  |  | ||||||
|  |                         mov     t1,fcolor               'set ctra pll to fcolor * 16 | ||||||
|  |                         call    #divide                 'if ntsc, set vco to fcolor * 32 (114.5454 MHz) | ||||||
|  |                         test    _mode,#%0001    wc      'if pal, set vco to fcolor * 16 (70.9379 MHz) | ||||||
|  |         if_c            movi    ctra,#%00001_111        'select fcolor * 16 output (ntsc=/2, pal=/1) | ||||||
|  |         if_nc           movi    ctra,#%00001_110 | ||||||
|  |         if_nc           shl     t2,#1 | ||||||
|  |                         mov     frqa,t2                 '+147 | ||||||
|  |  | ||||||
|  |                         jmpret  taskptr,taskret         '+1=148, break and return later | ||||||
|  |  | ||||||
|  |                         mov     t1,_broadcast           'set ctrb pll to _broadcast | ||||||
|  |                         mov     t2,#0                   'if 0, turn off ctrb | ||||||
|  |                         tjz     t1,#:off | ||||||
|  |                         min     t1,m8                   'limit from 8MHz to 128MHz | ||||||
|  |                         max     t1,m128 | ||||||
|  |                         mov     t2,#%00001_100          'adjust _broadcast to be within 4MHz-8MHz | ||||||
|  | :scale                  shr     t1,#1                   '(vco will be within 64MHz-128MHz) | ||||||
|  |                         cmp     m8,t1           wc | ||||||
|  |         if_c            add     t2,#%00000_001 | ||||||
|  |         if_c            jmp     #:scale | ||||||
|  | :off                    movi    ctrb,t2 | ||||||
|  |                         call    #divide | ||||||
|  |                         mov     frqb,t2                 '+165 | ||||||
|  |  | ||||||
|  |                         jmpret  taskptr,taskret         '+1=166, break and return later | ||||||
|  |  | ||||||
|  |                         mov     t1,#%10100_000          'set video configuration | ||||||
|  |                         test    _pins,#$01      wc      '(swap broadcast/baseband output bits?) | ||||||
|  |         if_c            or      t1,#%01000_000 | ||||||
|  |                         test    _mode,#%1000    wc      '(strip chroma from broadcast?) | ||||||
|  |         if_nc           or      t1,#%00010_000 | ||||||
|  |                         test    _mode,#%0100    wc      '(strip chroma from baseband?) | ||||||
|  |         if_nc           or      t1,#%00001_000 | ||||||
|  |                         and     _auralcog,#%111         '(set aural cog) | ||||||
|  |                         or      t1,_auralcog | ||||||
|  |                         movi    vcfg,t1                 '+10 | ||||||
|  |  | ||||||
|  |                         mov     hx,_hx                  'compute horizontal metrics | ||||||
|  |                         shl     hx,#8 | ||||||
|  |                         or      hx,_hx | ||||||
|  |                         shl     hx,#4 | ||||||
|  |  | ||||||
|  |                         mov     hc2x,_ht | ||||||
|  |                         shl     hc2x,#1 | ||||||
|  |  | ||||||
|  |                         mov     t1,_ht | ||||||
|  |                         mov     t2,_hx | ||||||
|  |                         call    #multiply | ||||||
|  |                         mov     hf,hvis | ||||||
|  |                         sub     hf,t1 | ||||||
|  |                         shr     hf,#1           wc | ||||||
|  |                         mov     hb,_ho | ||||||
|  |                         addx    hb,hf | ||||||
|  |                         sub     hf,_ho                  '+52 | ||||||
|  |  | ||||||
|  |                         mov     t1,_vt                  'compute vertical metrics | ||||||
|  |                         mov     t2,_vx | ||||||
|  |                         call    #multiply | ||||||
|  |                         test    _mode,#%10000   wc      'consider tile size | ||||||
|  |                         muxc    linerot,#1 | ||||||
|  |                         mov     lineadd,lineinc | ||||||
|  |         if_c            shr     lineadd,#1 | ||||||
|  |         if_c            shl     t1,#1 | ||||||
|  |                         test    _mode,#%0010    wc      'consider interlace | ||||||
|  |         if_c            shr     t1,#1 | ||||||
|  |                         mov     vf,vvis | ||||||
|  |                         sub     vf,t1 | ||||||
|  |                         shr     vf,#1           wc | ||||||
|  |                         neg     vb,_vo | ||||||
|  |                         addx    vb,vf | ||||||
|  |                         add     vf,_vo                  '+53 | ||||||
|  |  | ||||||
|  |                         xor     _mode,#%0010            '+1, flip interlace bit for display | ||||||
|  |  | ||||||
|  | :colors                 jmpret  taskptr,taskret         '+1=117/160, break and return later | ||||||
|  |  | ||||||
|  |                         mov     t1,#13                  'load next 13 colors into colortable | ||||||
|  | :colorloop              mov     t2,:colorreg            '5 times = 65 (all 64 colors loaded) | ||||||
|  |                         shr     t2,#9-2 | ||||||
|  |                         and     t2,#$FC | ||||||
|  |                         add     t2,_colors | ||||||
|  | :colorreg               rdlong  colortable,t2 | ||||||
|  |                         add     :colorreg,d0 | ||||||
|  |                         andn    :colorreg,d6 | ||||||
|  |                         djnz    t1,#:colorloop          '+158 | ||||||
|  |  | ||||||
|  |                         jmp     #:colors                '+1, keep loading colors | ||||||
|  | ' | ||||||
|  | ' | ||||||
|  | ' Divide t1/CLKFREQ to get frqa or frqb value into t2 | ||||||
|  | ' | ||||||
|  | divide                  rdlong  m1,#0                   'get CLKFREQ | ||||||
|  |  | ||||||
|  |                         mov     m2,#32+1 | ||||||
|  | :loop                   cmpsub  t1,m1           wc | ||||||
|  |                         rcl     t2,#1 | ||||||
|  |                         shl     t1,#1 | ||||||
|  |                         djnz    m2,#:loop | ||||||
|  |  | ||||||
|  | divide_ret              ret                             '+140 | ||||||
|  | ' | ||||||
|  | ' | ||||||
|  | ' Multiply t1 * t2 * 16 (t1, t2 = bytes) | ||||||
|  | ' | ||||||
|  | multiply                shl     t2,#8+4-1 | ||||||
|  |  | ||||||
|  |                         mov     m1,#8 | ||||||
|  | :loop                   shr     t1,#1           wc | ||||||
|  |         if_c            add     t1,t2 | ||||||
|  |                         djnz    m1,#:loop | ||||||
|  |  | ||||||
|  | multiply_ret            ret                             '+37 | ||||||
|  | ' | ||||||
|  | ' | ||||||
|  | ' Disabled - reset status, nap ~4ms, try again | ||||||
|  | ' | ||||||
|  | disabled                mov     ctra,#0                 'reset ctra | ||||||
|  |                         mov     ctrb,#0                 'reset ctrb | ||||||
|  |                         mov     vcfg,#0                 'reset video | ||||||
|  |  | ||||||
|  |                         wrlong  outa,par                'set status to disabled | ||||||
|  |  | ||||||
|  |                         rdlong  t1,#0                   'get CLKFREQ | ||||||
|  |                         shr     t1,#8                   'nap for ~4ms | ||||||
|  |                         min     t1,#3 | ||||||
|  |                         add     t1,cnt | ||||||
|  |                         waitcnt t1,#0 | ||||||
|  |  | ||||||
|  |                         jmp     #entry                  'reload parameters | ||||||
|  | ' | ||||||
|  | ' | ||||||
|  | ' Initialized data | ||||||
|  | ' | ||||||
|  | m8                      long    8_000_000 | ||||||
|  | m128                    long    128_000_000 | ||||||
|  | d0                      long    1 << 9 << 0 | ||||||
|  | d6                      long    1 << 9 << 6 | ||||||
|  | d0s1                    long    1 << 9 << 0 + 1 << 1 | ||||||
|  | interlace               long    0 | ||||||
|  | invisible               long    1 | ||||||
|  | visible                 long    2 | ||||||
|  | phaseflip               long    $00000000 | ||||||
|  | phasemask               long    $F0F0F0F0 | ||||||
|  | line                    long    $00060000 | ||||||
|  | lineinc                 long    $10000000 | ||||||
|  | linerot                 long    0 | ||||||
|  | pins0                   long    %11110000_01110000_00001111_00000111 | ||||||
|  | pins1                   long    %11111111_11110111_01111111_01110111 | ||||||
|  | sync_high1              long    %0101010101010101010101_101010_0101 | ||||||
|  | sync_high2              long    %01010101010101010101010101010101       'used for black | ||||||
|  | sync_low1               long    %1010101010101010101010101010_0101 | ||||||
|  | sync_low2               long    %01_101010101010101010101010101010 | ||||||
|  | ' | ||||||
|  | ' | ||||||
|  | ' NTSC/PAL metrics tables | ||||||
|  | '                               ntsc                    pal | ||||||
|  | '                               ---------------------------------------------- | ||||||
|  | wtab                    word    lntsc - sntsc,          lpal - spal     'hvis | ||||||
|  |                         word    lntsc / 2 - sntsc,      lpal / 2 - spal 'hrest | ||||||
|  |                         word    lntsc / 2,              lpal / 2        'hhalf | ||||||
|  |                         word    243,                    286             'vvis | ||||||
|  |                         word    10,                     18              'vinv | ||||||
|  |                         word    6,                      5               'vrep | ||||||
|  |                         word    $02_8A,                 $02_AA          'burst | ||||||
|  | wtabx | ||||||
|  | ltab                    long    fntsc                                   'fcolor | ||||||
|  |                         long    fpal | ||||||
|  |                         long    sntsc >> 4 << 12 + sntsc                'sync_scale1 | ||||||
|  |                         long    spal >> 4 << 12 + spal | ||||||
|  |                         long    67 << 12 + lntsc / 2 - sntsc            'sync_scale2 | ||||||
|  |                         long    79 << 12 + lpal / 2 - spal | ||||||
|  |                         long    %0101_00000000_01_10101010101010_0101   'sync_normal | ||||||
|  |                         long    %010101_00000000_01_101010101010_0101 | ||||||
|  | ltabx | ||||||
|  | ' | ||||||
|  | ' | ||||||
|  | ' Uninitialized data | ||||||
|  | ' | ||||||
|  | taskptr                 res     1                       'tasks | ||||||
|  | taskret                 res     1 | ||||||
|  | t1                      res     1 | ||||||
|  | t2                      res     1 | ||||||
|  | m1                      res     1 | ||||||
|  | m2                      res     1 | ||||||
|  |  | ||||||
|  | x                       res     1                       'display | ||||||
|  | y                       res     1 | ||||||
|  | hf                      res     1 | ||||||
|  | hb                      res     1 | ||||||
|  | vf                      res     1 | ||||||
|  | vb                      res     1 | ||||||
|  | hx                      res     1 | ||||||
|  | vx                      res     1 | ||||||
|  | hc2x                    res     1 | ||||||
|  | screen                  res     1 | ||||||
|  | tile                    res     1 | ||||||
|  | pixels                  res     1 | ||||||
|  | lineadd                 res     1 | ||||||
|  |  | ||||||
|  | hvis                    res     1                       'loaded from word table | ||||||
|  | hrest                   res     1 | ||||||
|  | hhalf                   res     1 | ||||||
|  | vvis                    res     1 | ||||||
|  | vinv                    res     1 | ||||||
|  | vrep                    res     1 | ||||||
|  | burst                   res     1 | ||||||
|  |  | ||||||
|  | fcolor                  res     1                       'loaded from long table | ||||||
|  | sync_scale1             res     1 | ||||||
|  | sync_scale2             res     1 | ||||||
|  | sync_normal             res     1 | ||||||
|  | ' | ||||||
|  | ' | ||||||
|  | ' Parameter buffer | ||||||
|  | ' | ||||||
|  | _enable                 res     1       '0/non-0        read-only | ||||||
|  | _pins                   res     1       '%pppmmmm       read-only | ||||||
|  | _mode                   res     1       '%tccip         read-only | ||||||
|  | _screen                 res     1       '@word          read-only | ||||||
|  | _colors                 res     1       '@long          read-only | ||||||
|  | _ht                     res     1       '1+             read-only | ||||||
|  | _vt                     res     1       '1+             read-only | ||||||
|  | _hx                     res     1       '4+             read-only | ||||||
|  | _vx                     res     1       '1+             read-only | ||||||
|  | _ho                     res     1       '0+-            read-only | ||||||
|  | _vo                     res     1       '0+-            read-only | ||||||
|  | _broadcast              res     1       '0+             read-only | ||||||
|  | _auralcog               res     1       '0-7            read-only | ||||||
|  |  | ||||||
|  |                         fit     colortable              'fit underneath colortable ($180-$1BF) | ||||||
|  | '' | ||||||
|  | ''___ | ||||||
|  | ''VAR                   'TV parameters - 14 contiguous longs | ||||||
|  | '' | ||||||
|  | ''  long  tv_status     '0/1/2 = off/invisible/visible              read-only | ||||||
|  | ''  long  tv_enable     '0/non-0 = off/on                           write-only | ||||||
|  | ''  long  tv_pins       '%pppmmmm = pin group, pin group mode       write-only | ||||||
|  | ''  long  tv_mode       '%tccip = tile,chroma,interlace,ntsc/pal    write-only | ||||||
|  | ''  long  tv_screen     'pointer to screen (words)                  write-only       | ||||||
|  | ''  long  tv_colors     'pointer to colors (longs)                  write-only                             | ||||||
|  | ''  long  tv_ht         'horizontal tiles                           write-only                             | ||||||
|  | ''  long  tv_vt         'vertical tiles                             write-only                             | ||||||
|  | ''  long  tv_hx         'horizontal tile expansion                  write-only                             | ||||||
|  | ''  long  tv_vx         'vertical tile expansion                    write-only                             | ||||||
|  | ''  long  tv_ho         'horizontal offset                          write-only                             | ||||||
|  | ''  long  tv_vo         'vertical offset                            write-only                             | ||||||
|  | ''  long  tv_broadcast  'broadcast frequency (Hz)                   write-only                             | ||||||
|  | ''  long  tv_auralcog   'aural fm cog                               write-only                             | ||||||
|  | ''                                                                                               | ||||||
|  | ''The preceding VAR section may be copied into your code.         | ||||||
|  | ''After setting variables, do start(@tv_status) to start driver.  | ||||||
|  | ''                                                                | ||||||
|  | ''All parameters are reloaded each superframe, allowing you to make live | ||||||
|  | ''changes. To minimize flicker, correlate changes with tv_status. | ||||||
|  | '' | ||||||
|  | ''Experimentation may be required to optimize some parameters. | ||||||
|  | '' | ||||||
|  | ''Parameter descriptions: | ||||||
|  | ''  _________ | ||||||
|  | ''  tv_status | ||||||
|  | '' | ||||||
|  | ''    driver sets this to indicate status: | ||||||
|  | ''      0: driver disabled (tv_enable = 0 or CLKFREQ < requirement) | ||||||
|  | ''      1: currently outputting invisible sync data | ||||||
|  | ''      2: currently outputting visible screen data | ||||||
|  | ''  _________ | ||||||
|  | ''  tv_enable | ||||||
|  | '' | ||||||
|  | ''        0: disable (pins will be driven low, reduces power) | ||||||
|  | ''    non-0: enable | ||||||
|  | ''  _______ | ||||||
|  | ''  tv_pins | ||||||
|  | '' | ||||||
|  | ''    bits 6..4 select pin group: | ||||||
|  | ''      %000: pins 7..0 | ||||||
|  | ''      %001: pins 15..8 | ||||||
|  | ''      %010: pins 23..16 | ||||||
|  | ''      %011: pins 31..24 | ||||||
|  | ''      %100: pins 39..32 | ||||||
|  | ''      %101: pins 47..40 | ||||||
|  | ''      %110: pins 55..48 | ||||||
|  | ''      %111: pins 63..56 | ||||||
|  | '' | ||||||
|  | ''    bits 3..0 select pin group mode: | ||||||
|  | ''      %0000: %0000_0111    -                    baseband | ||||||
|  | ''      %0001: %0000_0111    -                    broadcast | ||||||
|  | ''      %0010: %0000_1111    -                    baseband + chroma | ||||||
|  | ''      %0011: %0000_1111    -                    broadcast + aural | ||||||
|  | ''      %0100: %0111_0000    broadcast            - | ||||||
|  | ''      %0101: %0111_0000    baseband             - | ||||||
|  | ''      %0110: %1111_0000    broadcast + aural    - | ||||||
|  | ''      %0111: %1111_0000    baseband + chroma    - | ||||||
|  | ''      %1000: %0111_0111    broadcast            baseband | ||||||
|  | ''      %1001: %0111_0111    baseband             broadcast | ||||||
|  | ''      %1010: %0111_1111    broadcast            baseband + chroma | ||||||
|  | ''      %1011: %0111_1111    baseband             broadcast + aural | ||||||
|  | ''      %1100: %1111_0111    broadcast + aural    baseband | ||||||
|  | ''      %1101: %1111_0111    baseband + chroma    broadcast | ||||||
|  | ''      %1110: %1111_1111    broadcast + aural    baseband + chroma | ||||||
|  | ''      %1111: %1111_1111    baseband + chroma    broadcast + aural | ||||||
|  | ''      ----------------------------------------------------------- | ||||||
|  | ''            active pins    top nibble           bottom nibble | ||||||
|  | '' | ||||||
|  | ''      the baseband signal nibble is arranged as: | ||||||
|  | ''        bit 3: chroma signal for s-video (attach via 560-ohm resistor) | ||||||
|  | ''        bits 2..0: baseband video (sum 270/560/1100-ohm resistors to form 75-ohm 1V signal) | ||||||
|  | '' | ||||||
|  | ''      the broadcast signal nibble is arranged as: | ||||||
|  | ''        bit 3: aural subcarrier (sum 560-ohm resistor into network below) | ||||||
|  | ''        bits 2..0: visual carrier (sum 270/560/1100-ohm resistors to form 75-ohm 1V signal) | ||||||
|  | ''  _______ | ||||||
|  | ''  tv_mode | ||||||
|  | '' | ||||||
|  | ''    bit 4 selects between 16x16 and 16x32 pixel tiles: | ||||||
|  | ''      0: 16x16 pixel tiles (tileheight = 16) | ||||||
|  | ''      1: 16x32 pixel tiles (tileheight = 32) | ||||||
|  | '' | ||||||
|  | ''    bit 3 controls chroma mixing into broadcast: | ||||||
|  | ''      0: mix chroma into broadcast (color) | ||||||
|  | ''      1: strip chroma from broadcast (black/white) | ||||||
|  | '' | ||||||
|  | ''    bit 2 controls chroma mixing into baseband: | ||||||
|  | ''      0: mix chroma into baseband (composite color) | ||||||
|  | ''      1: strip chroma from baseband (black/white or s-video) | ||||||
|  | '' | ||||||
|  | ''    bit 1 controls interlace: | ||||||
|  | ''      0: progressive scan (243 display lines for NTSC, 286 for PAL) | ||||||
|  | ''           less flicker, good for motion | ||||||
|  | ''      1: interlaced scan (486 display lines for NTSC, 572 for PAL) | ||||||
|  | ''           doubles the vertical display lines, good for text | ||||||
|  | '' | ||||||
|  | ''    bit 0 selects NTSC or PAL format | ||||||
|  | ''      0: NTSC | ||||||
|  | ''           3016 horizontal display ticks | ||||||
|  | ''           243 or 486 (interlaced) vertical display lines | ||||||
|  | ''           CLKFREQ must be at least 14_318_180 (4 * 3_579_545 Hz)* | ||||||
|  | ''      1: PAL | ||||||
|  | ''           3692 horizontal display ticks | ||||||
|  | ''           286 or 572 (interlaced) vertical display lines | ||||||
|  | ''           CLKFREQ must be at least 17_734_472 (4 * 4_433_618 Hz)* | ||||||
|  | '' | ||||||
|  | ''      * driver will disable itself while CLKFREQ is below requirement | ||||||
|  | ''  _________ | ||||||
|  | ''  tv_screen | ||||||
|  | '' | ||||||
|  | ''    pointer to words which define screen contents (left-to-right, top-to-bottom) | ||||||
|  | ''      number of words must be tv_ht * tv_vt | ||||||
|  | ''      each word has two bitfields: a 6-bit colorset ptr and a 10-bit pixelgroup ptr | ||||||
|  | ''        bits 15..10: select the colorset* for the associated pixel tile | ||||||
|  | ''        bits 9..0: select the pixelgroup** address %ppppppppppcccc00 (p=address, c=0..15) | ||||||
|  | '' | ||||||
|  | ''       * colorsets are longs which each define four 8-bit colors | ||||||
|  | '' | ||||||
|  | ''      ** pixelgroups are <tileheight> longs which define (left-to-right, top-to-bottom) the 2-bit | ||||||
|  | ''         (four color) pixels that make up a 16x16 or a 32x32 pixel tile | ||||||
|  | ''  _________ | ||||||
|  | ''  tv_colors | ||||||
|  | '' | ||||||
|  | ''    pointer to longs which define colorsets | ||||||
|  | ''      number of longs must be 1..64 | ||||||
|  | ''      each long has four 8-bit fields which define colors for 2-bit (four color) pixels | ||||||
|  | ''      first long's bottom color is also used as the screen background color | ||||||
|  | ''      8-bit color fields are as follows: | ||||||
|  | ''        bits 7..4: chroma data (0..15 = blue..green..red..)* | ||||||
|  | ''        bit 3: controls chroma modulation (0=off, 1=on) | ||||||
|  | ''        bits 2..0: 3-bit luminance level: | ||||||
|  | ''          values 0..1: reserved for sync - don't use | ||||||
|  | ''          values 2..7: valid luminance range, modulation adds/subtracts 1 (beware of 7) | ||||||
|  | ''          value 0 may be modulated to produce a saturated color toggling between levels 1 and 7 | ||||||
|  | '' | ||||||
|  | ''      * because of TV's limitations, it doesn't look good when chroma changes abruptly - | ||||||
|  | ''        rather, use luminance - change chroma only against a black or white background for | ||||||
|  | ''        best appearance | ||||||
|  | ''  _____ | ||||||
|  | ''  tv_ht | ||||||
|  | '' | ||||||
|  | ''    horizontal number pixel tiles - must be at least 1 | ||||||
|  | ''    practical limit is 40 for NTSC, 50 for PAL | ||||||
|  | ''  _____ | ||||||
|  | ''  tv_vt | ||||||
|  | '' | ||||||
|  | ''    vertical number of pixel tiles - must be at least 1 | ||||||
|  | ''    practical limit is 13 for NTSC, 15 for PAL (26/30 max for interlaced NTSC/PAL) | ||||||
|  | ''  _____ | ||||||
|  | ''  tv_hx | ||||||
|  | '' | ||||||
|  | ''    horizontal tile expansion factor - must be at least 3 for NTSC, 4 for PAL | ||||||
|  | '' | ||||||
|  | ''    make sure 16 * tv_ht * tv_hx + ||tv_ho + 32 is less than the horizontal display ticks | ||||||
|  | ''  _____ | ||||||
|  | ''  tv_vx | ||||||
|  | '' | ||||||
|  | ''    vertical tile expansion factor - must be at least 1 | ||||||
|  | '' | ||||||
|  | ''    make sure <tileheight> * tv_vt * tv_vx + ||tv_vo + 1 is less than the display lines | ||||||
|  | ''  _____ | ||||||
|  | ''  tv_ho | ||||||
|  | '' | ||||||
|  | ''    horizontal offset in ticks - pos/neg value (0 for centered image) | ||||||
|  | ''    shifts the display right/left | ||||||
|  | ''  _____ | ||||||
|  | ''  tv_vo | ||||||
|  | '' | ||||||
|  | ''    vertical offset in lines - pos/neg value (0 for centered image) | ||||||
|  | ''    shifts the display up/down | ||||||
|  | ''  ____________ | ||||||
|  | ''  tv_broadcast | ||||||
|  | '' | ||||||
|  | ''    broadcast frequency expressed in Hz (ie channel 2 is 55_250_000) | ||||||
|  | ''    if 0, modulator is turned off - saves power | ||||||
|  | '' | ||||||
|  | ''    broadcasting requires CLKFREQ to be at least 16_000_000 | ||||||
|  | ''    while CLKFREQ is below 16_000_000, modulator will be turned off | ||||||
|  | ''  ___________ | ||||||
|  | ''  tv_auralcog | ||||||
|  | '' | ||||||
|  | ''    selects cog to supply aural fm signal - 0..7 | ||||||
|  | ''    uses ctra pll output from selected cog | ||||||
|  | '' | ||||||
|  | ''    in NTSC, the offset frequency must be 4.5MHz and the max bandwidth +-25KHz | ||||||
|  | ''    in PAL, the offset frequency and max bandwidth vary by PAL type | ||||||
|  |  | ||||||
|  | {{ | ||||||
|  |  | ||||||
|  | ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ | ||||||
|  | │                                                   TERMS OF USE: MIT License                                                  │                                                             | ||||||
|  | ├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ | ||||||
|  | │Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation    │  | ||||||
|  | │files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,    │ | ||||||
|  | │modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ | ||||||
|  | │is furnished to do so, subject to the following conditions:                                                                   │ | ||||||
|  | │                                                                                                                              │ | ||||||
|  | │The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ | ||||||
|  | │                                                                                                                              │ | ||||||
|  | │THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE          │ | ||||||
|  | │WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR         │ | ||||||
|  | │COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,   │ | ||||||
|  | │ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                         │ | ||||||
|  | └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ | ||||||
|  | }} | ||||||
							
								
								
									
										244
									
								
								samples/Propeller Spin/TV_Terminal.spin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										244
									
								
								samples/Propeller Spin/TV_Terminal.spin
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,244 @@ | |||||||
|  | ''*************************************** | ||||||
|  | ''*  TV Terminal v1.1                   * | ||||||
|  | ''*  Author: Chip Gracey                * | ||||||
|  | ''*  Copyright (c) 2005 Parallax, Inc.  * | ||||||
|  | ''*  See end of file for terms of use.  * | ||||||
|  | ''*************************************** | ||||||
|  |  | ||||||
|  | {-----------------REVISION HISTORY----------------- | ||||||
|  |  v1.1 - Updated 5/15/2006 to use actual pin number, instead of pin group, for Start method's basepin parameter.} | ||||||
|  |   | ||||||
|  | CON | ||||||
|  |  | ||||||
|  |   x_tiles = 16 | ||||||
|  |   y_tiles = 13 | ||||||
|  |  | ||||||
|  |   x_screen = x_tiles << 4 | ||||||
|  |   y_screen = y_tiles << 4 | ||||||
|  |  | ||||||
|  |   width = 0             '0 = minimum | ||||||
|  |   x_scale = 1           '1 = minimum | ||||||
|  |   y_scale = 1           '1 = minimum | ||||||
|  |   x_spacing = 6         '6 = normal | ||||||
|  |   y_spacing = 13        '13 = normal | ||||||
|  |  | ||||||
|  |   x_chr = x_scale * x_spacing | ||||||
|  |   y_chr = y_scale * y_spacing | ||||||
|  |  | ||||||
|  |   y_offset = y_spacing / 6 + y_chr - 1 | ||||||
|  |  | ||||||
|  |   x_limit = x_screen / (x_scale * x_spacing) | ||||||
|  |   y_limit = y_screen / (y_scale * y_spacing) | ||||||
|  |   y_max = y_limit - 1 | ||||||
|  |  | ||||||
|  |   y_screen_bytes = y_screen << 2 | ||||||
|  |   y_scroll = y_chr << 2 | ||||||
|  |   y_scroll_longs = y_chr * y_max | ||||||
|  |   y_clear = y_scroll_longs << 2 | ||||||
|  |   y_clear_longs = y_screen - y_scroll_longs | ||||||
|  |  | ||||||
|  |   paramcount = 14        | ||||||
|  |  | ||||||
|  |    | ||||||
|  | VAR | ||||||
|  |  | ||||||
|  |   long  x, y, bitmap_base | ||||||
|  |  | ||||||
|  |   long  tv_status     '0/1/2 = off/visible/invisible           read-only | ||||||
|  |   long  tv_enable     '0/? = off/on                            write-only | ||||||
|  |   long  tv_pins       '%ppmmm = pins                           write-only | ||||||
|  |   long  tv_mode       '%ccinp = chroma,interlace,ntsc/pal,swap write-only | ||||||
|  |   long  tv_screen     'pointer to screen (words)               write-only | ||||||
|  |   long  tv_colors     'pointer to colors (longs)               write-only                | ||||||
|  |   long  tv_hc         'horizontal cells                        write-only | ||||||
|  |   long  tv_vc         'vertical cells                          write-only | ||||||
|  |   long  tv_hx         'horizontal cell expansion               write-only | ||||||
|  |   long  tv_vx         'vertical cell expansion                 write-only | ||||||
|  |   long  tv_ho         'horizontal offset                       write-only | ||||||
|  |   long  tv_vo         'vertical offset                         write-only | ||||||
|  |   long  tv_broadcast  'broadcast frequency (Hz)                write-only | ||||||
|  |   long  tv_auralcog   'aural fm cog                            write-only | ||||||
|  |  | ||||||
|  |   long  bitmap[x_tiles * y_tiles << 4 + 16]     'add 16 longs to allow for 64-byte alignment | ||||||
|  |   word  screen[x_tiles * y_tiles] | ||||||
|  |    | ||||||
|  |  | ||||||
|  | OBJ | ||||||
|  |  | ||||||
|  |   tv    : "tv" | ||||||
|  |   gr    : "graphics" | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB start(basepin) | ||||||
|  |  | ||||||
|  | '' Start terminal | ||||||
|  | '' | ||||||
|  | ''  basepin = first of three pins on a 4-pin boundary (0, 4, 8...) to have | ||||||
|  | ''  1.1k, 560, and 270 ohm resistors connected and summed to form the 1V, | ||||||
|  | ''  75 ohm DAC for baseband video    | ||||||
|  |  | ||||||
|  |   'init bitmap and tile screen | ||||||
|  |   bitmap_base := (@bitmap + $3F) & $7FC0 | ||||||
|  |   repeat x from 0 to x_tiles - 1 | ||||||
|  |     repeat y from 0 to y_tiles - 1 | ||||||
|  |       screen[y * x_tiles + x] := bitmap_base >> 6 + y + x * y_tiles | ||||||
|  |  | ||||||
|  |   'start tv | ||||||
|  |   tvparams_pins := (basepin & $38) << 1 | (basepin & 4 == 4) & %0101 | ||||||
|  |   longmove(@tv_status, @tvparams, paramcount) | ||||||
|  |   tv_screen := @screen | ||||||
|  |   tv_colors := @color_schemes | ||||||
|  |   tv.start(@tv_status) | ||||||
|  |  | ||||||
|  |   'start graphics | ||||||
|  |   gr.start | ||||||
|  |   gr.setup(x_tiles, y_tiles, 0, y_screen, bitmap_base) | ||||||
|  |   gr.textmode(x_scale, y_scale, x_spacing, 0) | ||||||
|  |   gr.width(width) | ||||||
|  |   out(0) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB stop | ||||||
|  |  | ||||||
|  | '' Stop terminal | ||||||
|  |  | ||||||
|  |   tv.stop | ||||||
|  |   gr.stop | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB out(c) | ||||||
|  |  | ||||||
|  | '' Print a character | ||||||
|  | '' | ||||||
|  | ''       $00 = home | ||||||
|  | ''  $01..$03 = color | ||||||
|  | ''  $04..$07 = color schemes | ||||||
|  | ''       $09 = tab | ||||||
|  | ''       $0D = return | ||||||
|  | ''  $20..$7E = character | ||||||
|  |  | ||||||
|  |   case c | ||||||
|  |  | ||||||
|  |     $00:                'home? | ||||||
|  |       gr.clear | ||||||
|  |       x := y := 0 | ||||||
|  |  | ||||||
|  |     $01..$03:           'color? | ||||||
|  |       gr.color(c) | ||||||
|  |  | ||||||
|  |     $04..$07:           'color scheme? | ||||||
|  |       tv_colors := @color_schemes[c & 3] | ||||||
|  |  | ||||||
|  |     $09:                'tab? | ||||||
|  |       repeat | ||||||
|  |         out($20) | ||||||
|  |       while x & 7 | ||||||
|  |  | ||||||
|  |     $0D:                'return? | ||||||
|  |       newline | ||||||
|  |  | ||||||
|  |     $20..$7E:           'character? | ||||||
|  |       gr.text(x * x_chr, -y * y_chr - y_offset, @c) | ||||||
|  |       gr.finish | ||||||
|  |       if ++x == x_limit | ||||||
|  |         newline | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB str(string_ptr) | ||||||
|  |  | ||||||
|  | '' Print a zero-terminated string | ||||||
|  |  | ||||||
|  |   repeat strsize(string_ptr) | ||||||
|  |     out(byte[string_ptr++]) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB dec(value) | i | ||||||
|  |  | ||||||
|  | '' Print a decimal number | ||||||
|  |  | ||||||
|  |   if value < 0 | ||||||
|  |     -value | ||||||
|  |     out("-") | ||||||
|  |  | ||||||
|  |   i := 1_000_000_000 | ||||||
|  |  | ||||||
|  |   repeat 10 | ||||||
|  |     if value => i | ||||||
|  |       out(value / i + "0") | ||||||
|  |       value //= i | ||||||
|  |       result~~ | ||||||
|  |     elseif result or i == 1 | ||||||
|  |       out("0") | ||||||
|  |     i /= 10 | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB hex(value, digits) | ||||||
|  |  | ||||||
|  | '' Print a hexadecimal number | ||||||
|  |  | ||||||
|  |   value <<= (8 - digits) << 2 | ||||||
|  |   repeat digits | ||||||
|  |     out(lookupz((value <-= 4) & $F : "0".."9", "A".."F")) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB bin(value, digits) | ||||||
|  |  | ||||||
|  | '' Print a binary number | ||||||
|  |  | ||||||
|  |   value <<= 32 - digits | ||||||
|  |   repeat digits | ||||||
|  |     out((value <-= 1) & 1 + "0") | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PRI newline | ||||||
|  |  | ||||||
|  |   if ++y == y_limit | ||||||
|  |     gr.finish | ||||||
|  |     repeat x from 0 to x_tiles - 1 | ||||||
|  |       y := bitmap_base + x * y_screen_bytes | ||||||
|  |       longmove(y, y + y_scroll, y_scroll_longs) | ||||||
|  |       longfill(y + y_clear, 0, y_clear_longs) | ||||||
|  |     y := y_max | ||||||
|  |   x := 0 | ||||||
|  |  | ||||||
|  |  | ||||||
|  | DAT | ||||||
|  |  | ||||||
|  | tvparams                long    0               'status | ||||||
|  |                         long    1               'enable | ||||||
|  | tvparams_pins           long    %001_0101       'pins | ||||||
|  |                         long    %0000           'mode | ||||||
|  |                         long    0               'screen | ||||||
|  |                         long    0               'colors | ||||||
|  |                         long    x_tiles         'hc | ||||||
|  |                         long    y_tiles         'vc | ||||||
|  |                         long    10              'hx | ||||||
|  |                         long    1               'vx | ||||||
|  |                         long    0               'ho | ||||||
|  |                         long    0               'vo | ||||||
|  |                         long    55_250_000      'broadcast | ||||||
|  |                         long    0               'auralcog | ||||||
|  |  | ||||||
|  | color_schemes           long    $BC_6C_05_02 | ||||||
|  |                         long    $0E_0D_0C_0A | ||||||
|  |                         long    $6E_6D_6C_6A | ||||||
|  |                         long    $BE_BD_BC_BA | ||||||
|  |  | ||||||
|  | {{ | ||||||
|  |  | ||||||
|  | ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ | ||||||
|  | │                                                   TERMS OF USE: MIT License                                                  │                                                             | ||||||
|  | ├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ | ||||||
|  | │Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation    │  | ||||||
|  | │files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,    │ | ||||||
|  | │modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ | ||||||
|  | │is furnished to do so, subject to the following conditions:                                                                   │ | ||||||
|  | │                                                                                                                              │ | ||||||
|  | │The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ | ||||||
|  | │                                                                                                                              │ | ||||||
|  | │THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE          │ | ||||||
|  | │WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR         │ | ||||||
|  | │COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,   │ | ||||||
|  | │ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                         │ | ||||||
|  | └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ | ||||||
|  | }}                    | ||||||
							
								
								
									
										232
									
								
								samples/Propeller Spin/TV_Text.spin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										232
									
								
								samples/Propeller Spin/TV_Text.spin
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,232 @@ | |||||||
|  | ''*************************************** | ||||||
|  | ''*  TV Text 40x13 v1.0                 * | ||||||
|  | ''*  Author: Chip Gracey                * | ||||||
|  | ''*  Copyright (c) 2006 Parallax, Inc.  *                | ||||||
|  | ''*  See end of file for terms of use.  *                | ||||||
|  | ''*************************************** | ||||||
|  |  | ||||||
|  | CON | ||||||
|  |  | ||||||
|  |   cols = 40 | ||||||
|  |   rows = 13 | ||||||
|  |  | ||||||
|  |   screensize = cols * rows | ||||||
|  |   lastrow = screensize - cols | ||||||
|  |  | ||||||
|  |   tv_count = 14 | ||||||
|  |  | ||||||
|  |    | ||||||
|  | VAR | ||||||
|  |  | ||||||
|  |   long  col, row, color, flag | ||||||
|  |    | ||||||
|  |   word  screen[screensize] | ||||||
|  |   long  colors[8 * 2] | ||||||
|  |  | ||||||
|  |   long  tv_status     '0/1/2 = off/invisible/visible              read-only   (14 longs) | ||||||
|  |   long  tv_enable     '0/non-0 = off/on                           write-only | ||||||
|  |   long  tv_pins       '%pppmmmm = pin group, pin group mode       write-only | ||||||
|  |   long  tv_mode       '%tccip = tile,chroma,interlace,ntsc/pal    write-only | ||||||
|  |   long  tv_screen     'pointer to screen (words)                  write-only       | ||||||
|  |   long  tv_colors     'pointer to colors (longs)                  write-only                             | ||||||
|  |   long  tv_ht         'horizontal tiles                           write-only                             | ||||||
|  |   long  tv_vt         'vertical tiles                             write-only                             | ||||||
|  |   long  tv_hx         'horizontal tile expansion                  write-only                             | ||||||
|  |   long  tv_vx         'vertical tile expansion                    write-only                             | ||||||
|  |   long  tv_ho         'horizontal offset                          write-only                             | ||||||
|  |   long  tv_vo         'vertical offset                            write-only                             | ||||||
|  |   long  tv_broadcast  'broadcast frequency (Hz)                   write-only                             | ||||||
|  |   long  tv_auralcog   'aural fm cog                               write-only                             | ||||||
|  |  | ||||||
|  |  | ||||||
|  | OBJ | ||||||
|  |  | ||||||
|  |   tv : "tv" | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB start(basepin) : okay | ||||||
|  |  | ||||||
|  | '' Start terminal - starts a cog | ||||||
|  | '' returns false if no cog available | ||||||
|  |  | ||||||
|  |   setcolors(@palette) | ||||||
|  |   out(0) | ||||||
|  |    | ||||||
|  |   longmove(@tv_status, @tv_params, tv_count) | ||||||
|  |   tv_pins := (basepin & $38) << 1 | (basepin & 4 == 4) & %0101 | ||||||
|  |   tv_screen := @screen | ||||||
|  |   tv_colors := @colors | ||||||
|  |    | ||||||
|  |   okay := tv.start(@tv_status) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB stop | ||||||
|  |  | ||||||
|  | '' Stop terminal - frees a cog | ||||||
|  |  | ||||||
|  |   tv.stop | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB str(stringptr) | ||||||
|  |  | ||||||
|  | '' Print a zero-terminated string | ||||||
|  |  | ||||||
|  |   repeat strsize(stringptr) | ||||||
|  |     out(byte[stringptr++]) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB dec(value) | i | ||||||
|  |  | ||||||
|  | '' Print a decimal number | ||||||
|  |  | ||||||
|  |   if value < 0 | ||||||
|  |     -value | ||||||
|  |     out("-") | ||||||
|  |  | ||||||
|  |   i := 1_000_000_000 | ||||||
|  |  | ||||||
|  |   repeat 10 | ||||||
|  |     if value => i | ||||||
|  |       out(value / i + "0") | ||||||
|  |       value //= i | ||||||
|  |       result~~ | ||||||
|  |     elseif result or i == 1 | ||||||
|  |       out("0") | ||||||
|  |     i /= 10 | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB hex(value, digits) | ||||||
|  |  | ||||||
|  | '' Print a hexadecimal number | ||||||
|  |  | ||||||
|  |   value <<= (8 - digits) << 2 | ||||||
|  |   repeat digits | ||||||
|  |     out(lookupz((value <-= 4) & $F : "0".."9", "A".."F")) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB bin(value, digits) | ||||||
|  |  | ||||||
|  | '' Print a binary number | ||||||
|  |  | ||||||
|  |   value <<= 32 - digits | ||||||
|  |   repeat digits | ||||||
|  |     out((value <-= 1) & 1 + "0") | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB out(c) | i, k | ||||||
|  |  | ||||||
|  | '' Output a character | ||||||
|  | '' | ||||||
|  | ''     $00 = clear screen | ||||||
|  | ''     $01 = home | ||||||
|  | ''     $08 = backspace | ||||||
|  | ''     $09 = tab (8 spaces per) | ||||||
|  | ''     $0A = set X position (X follows) | ||||||
|  | ''     $0B = set Y position (Y follows) | ||||||
|  | ''     $0C = set color (color follows) | ||||||
|  | ''     $0D = return | ||||||
|  | ''  others = printable characters | ||||||
|  |  | ||||||
|  |   case flag | ||||||
|  |     $00: case c | ||||||
|  |            $00: wordfill(@screen, $220, screensize) | ||||||
|  |                 col := row := 0 | ||||||
|  |            $01: col := row := 0 | ||||||
|  |            $08: if col | ||||||
|  |                   col-- | ||||||
|  |            $09: repeat | ||||||
|  |                   print(" ") | ||||||
|  |                 while col & 7 | ||||||
|  |            $0A..$0C: flag := c | ||||||
|  |                      return | ||||||
|  |            $0D: newline | ||||||
|  |            other: print(c) | ||||||
|  |     $0A: col := c // cols | ||||||
|  |     $0B: row := c // rows | ||||||
|  |     $0C: color := c & 7 | ||||||
|  |   flag := 0 | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB setcolors(colorptr) | i, fore, back | ||||||
|  |  | ||||||
|  | '' Override default color palette | ||||||
|  | '' colorptr must point to a list of up to 8 colors | ||||||
|  | '' arranged as follows: | ||||||
|  | '' | ||||||
|  | ''               fore   back | ||||||
|  | ''               ------------ | ||||||
|  | '' palette  byte color, color     'color 0 | ||||||
|  | ''          byte color, color     'color 1 | ||||||
|  | ''          byte color, color     'color 2 | ||||||
|  | ''          ... | ||||||
|  |  | ||||||
|  |   repeat i from 0 to 7 | ||||||
|  |     fore := byte[colorptr][i << 1] | ||||||
|  |     back := byte[colorptr][i << 1 + 1] | ||||||
|  |     colors[i << 1]     := fore << 24 + back << 16 + fore << 8 + back | ||||||
|  |     colors[i << 1 + 1] := fore << 24 + fore << 16 + back << 8 + back | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PRI print(c) | ||||||
|  |  | ||||||
|  |   screen[row * cols + col] := (color << 1 + c & 1) << 10 + $200 + c & $FE | ||||||
|  |   if ++col == cols | ||||||
|  |     newline | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PRI newline | i | ||||||
|  |  | ||||||
|  |   col := 0 | ||||||
|  |   if ++row == rows | ||||||
|  |     row-- | ||||||
|  |     wordmove(@screen, @screen[cols], lastrow)   'scroll lines | ||||||
|  |     wordfill(@screen[lastrow], $220, cols)      'clear new line | ||||||
|  |  | ||||||
|  |  | ||||||
|  | DAT | ||||||
|  |  | ||||||
|  | tv_params               long    0               'status | ||||||
|  |                         long    1               'enable | ||||||
|  |                         long    0               'pins | ||||||
|  |                         long    %10010          'mode | ||||||
|  |                         long    0               'screen | ||||||
|  |                         long    0               'colors | ||||||
|  |                         long    cols            'hc | ||||||
|  |                         long    rows            'vc | ||||||
|  |                         long    4               'hx | ||||||
|  |                         long    1               'vx | ||||||
|  |                         long    0               'ho | ||||||
|  |                         long    0               'vo | ||||||
|  |                         long    0               'broadcast | ||||||
|  |                         long    0               'auralcog | ||||||
|  |  | ||||||
|  |  | ||||||
|  |                         '       fore   back | ||||||
|  |                         '       color  color | ||||||
|  | palette                 byte    $07,   $0A    '0    white / dark blue | ||||||
|  |                         byte    $07,   $BB    '1    white / red | ||||||
|  |                         byte    $9E,   $9B    '2   yellow / brown | ||||||
|  |                         byte    $04,   $07    '3     grey / white | ||||||
|  |                         byte    $3D,   $3B    '4     cyan / dark cyan | ||||||
|  |                         byte    $6B,   $6E    '5    green / gray-green | ||||||
|  |                         byte    $BB,   $CE    '6      red / pink | ||||||
|  |                         byte    $3C,   $0A    '7     cyan / blue | ||||||
|  |  | ||||||
|  | {{ | ||||||
|  |  | ||||||
|  | ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ | ||||||
|  | │                                                   TERMS OF USE: MIT License                                                  │                                                             | ||||||
|  | ├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ | ||||||
|  | │Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation    │  | ||||||
|  | │files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,    │ | ||||||
|  | │modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ | ||||||
|  | │is furnished to do so, subject to the following conditions:                                                                   │ | ||||||
|  | │                                                                                                                              │ | ||||||
|  | │The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ | ||||||
|  | │                                                                                                                              │ | ||||||
|  | │THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE          │ | ||||||
|  | │WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR         │ | ||||||
|  | │COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,   │ | ||||||
|  | │ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                         │ | ||||||
|  | └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ | ||||||
|  | }}                         | ||||||
							
								
								
									
										596
									
								
								samples/Propeller Spin/VGA.spin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										596
									
								
								samples/Propeller Spin/VGA.spin
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,596 @@ | |||||||
|  | ''*************************************** | ||||||
|  | ''*  VGA Driver v1.1                    * | ||||||
|  | ''*  Author: Chip Gracey                * | ||||||
|  | ''*  Copyright (c) 2006 Parallax, Inc.  * | ||||||
|  | ''*  See end of file for terms of use.  * | ||||||
|  | ''*************************************** | ||||||
|  |  | ||||||
|  | ' v1.0 - 01 May 2006 - original version | ||||||
|  | ' v1.1 - 15 May 2006 - pixel tile size can now be 16 x 32 to enable more efficient | ||||||
|  | '                       character displays utilizing the internal font - see 'vga_mode' | ||||||
|  |  | ||||||
|  | CON | ||||||
|  |  | ||||||
|  |   paramcount    = 21 | ||||||
|  |   colortable    = $180  'start of colortable inside cog | ||||||
|  |    | ||||||
|  |  | ||||||
|  | VAR | ||||||
|  |  | ||||||
|  |   long  cog | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB start(vgaptr) : okay | ||||||
|  |  | ||||||
|  | '' Start VGA driver - starts a cog | ||||||
|  | '' returns false if no cog available | ||||||
|  | '' | ||||||
|  | ''   vgaptr = pointer to VGA parameters | ||||||
|  |  | ||||||
|  |   stop | ||||||
|  |   okay := cog := cognew(@entry, vgaptr) + 1 | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB stop | ||||||
|  |  | ||||||
|  | '' Stop VGA driver - frees a cog | ||||||
|  |  | ||||||
|  |   if cog | ||||||
|  |     cogstop(cog~ - 1) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | DAT | ||||||
|  |  | ||||||
|  | '******************************** | ||||||
|  | '* Assembly language VGA driver * | ||||||
|  | '******************************** | ||||||
|  |  | ||||||
|  |                         org | ||||||
|  | ' | ||||||
|  | ' | ||||||
|  | ' Entry | ||||||
|  | ' | ||||||
|  | entry                   mov     taskptr,#tasks          'reset tasks | ||||||
|  |  | ||||||
|  |                         mov     x,#8                    'perform task sections initially | ||||||
|  | :init                   jmpret  taskret,taskptr | ||||||
|  |                         djnz    x,#:init | ||||||
|  | ' | ||||||
|  | ' | ||||||
|  | ' Superfield | ||||||
|  | ' | ||||||
|  | superfield              mov     hv,hvbase               'set hv | ||||||
|  |  | ||||||
|  |                         mov     interlace,#0            'reset interlace | ||||||
|  |  | ||||||
|  |                         test    _mode,#%0100    wz      'get interlace into nz | ||||||
|  | ' | ||||||
|  | ' | ||||||
|  | ' Field | ||||||
|  | ' | ||||||
|  | field                   wrlong  visible,par             'set status to visible | ||||||
|  |  | ||||||
|  |                         tjz     vb,#:nobl               'do any visible back porch lines | ||||||
|  |                         mov     x,vb | ||||||
|  |                         movd    bcolor,#colortable | ||||||
|  |                         call    #blank_line | ||||||
|  | :nobl | ||||||
|  |                         mov     screen,_screen          'point to first tile (upper-leftmost) | ||||||
|  |                         mov     y,_vt                   'set vertical tiles | ||||||
|  | :line                   mov     vx,_vx                  'set vertical expand | ||||||
|  | :vert   if_nz           xor     interlace,#1            'interlace skip? | ||||||
|  |         if_nz           tjz     interlace,#:skip | ||||||
|  |  | ||||||
|  |                         tjz     hb,#:nobp               'do any visible back porch pixels | ||||||
|  |                         mov     vscl,hb | ||||||
|  |                         waitvid colortable,#0 | ||||||
|  | :nobp | ||||||
|  |                         mov     x,_ht                   'set horizontal tiles | ||||||
|  |                         mov     vscl,hx                 'set horizontal expand | ||||||
|  |  | ||||||
|  | :tile                   rdword  tile,screen             'read tile | ||||||
|  |                         add     tile,line               'set pointer bits into tile | ||||||
|  |                         rol     tile,#6                 'read tile pixels | ||||||
|  |                         rdlong  pixels,tile             '(8 clocks between reads) | ||||||
|  |                         shr     tile,#10+6              'set tile colors | ||||||
|  |                         movd    :color,tile | ||||||
|  |                         add     screen,#2               'point to next tile | ||||||
|  | :color                  waitvid colortable,pixels       'pass colors and pixels to video | ||||||
|  |                         djnz    x,#:tile                'another tile? | ||||||
|  |  | ||||||
|  |                         sub     screen,hc2x             'repoint to first tile in same line | ||||||
|  |  | ||||||
|  |                         tjz     hf,#:nofp               'do any visible front porch pixels | ||||||
|  |                         mov     vscl,hf | ||||||
|  |                         waitvid colortable,#0 | ||||||
|  | :nofp | ||||||
|  |                         mov     x,#1                    'do hsync | ||||||
|  |                         call    #blank_hsync            '(x=0) | ||||||
|  |  | ||||||
|  | :skip                   djnz    vx,#:vert               'vertical expand? | ||||||
|  |                         ror     line,linerot            'set next line | ||||||
|  |                         add     line,lineadd    wc | ||||||
|  |                         rol     line,linerot                         | ||||||
|  |         if_nc           jmp     #:line | ||||||
|  |                         add     screen,hc2x             'point to first tile in next line | ||||||
|  |                         djnz    y,#:line        wc      'another tile line? (c=0) | ||||||
|  |  | ||||||
|  |                         tjz     vf,#:nofl               'do any visible front porch lines | ||||||
|  |                         mov     x,vf | ||||||
|  |                         movd    bcolor,#colortable | ||||||
|  |                         call    #blank_line | ||||||
|  | :nofl | ||||||
|  |         if_nz           xor     interlace,#1    wc,wz   'get interlace and field1 into nz (c=0/?) | ||||||
|  |  | ||||||
|  |         if_z            wrlong  invisible,par           'unless interlace and field1, set status to invisible | ||||||
|  |  | ||||||
|  |                         mov     taskptr,#tasks          'reset tasks | ||||||
|  |  | ||||||
|  |                         addx    x,_vf           wc      'do invisible front porch lines (x=0 before, c=0 after) | ||||||
|  |                         call    #blank_line | ||||||
|  |  | ||||||
|  |                         mov     x,_vs                   'do vsync lines | ||||||
|  |                         call    #blank_vsync | ||||||
|  |  | ||||||
|  |                         mov     x,_vb                   'do invisible back porch lines, except last | ||||||
|  |                         call    #blank_vsync | ||||||
|  |  | ||||||
|  |         if_nz           jmp     #field                  'if interlace and field1, display field2 | ||||||
|  |                         jmp     #superfield             'else, new superfield | ||||||
|  | ' | ||||||
|  | ' | ||||||
|  | ' Blank line(s) | ||||||
|  | ' | ||||||
|  | blank_vsync             cmp     interlace,#2    wc      'vsync (c=1) | ||||||
|  |  | ||||||
|  | blank_line              mov     vscl,h1                 'blank line or vsync-interlace? | ||||||
|  |         if_nc           add     vscl,h2 | ||||||
|  |         if_c_and_nz     xor     hv,#%01 | ||||||
|  |         if_c            waitvid hv,#0 | ||||||
|  |         if_c            mov     vscl,h2                 'blank line or vsync-normal? | ||||||
|  |         if_c_and_z      xor     hv,#%01 | ||||||
|  | bcolor                  waitvid hv,#0 | ||||||
|  |  | ||||||
|  |         if_nc           jmpret  taskret,taskptr         'call task section (z undisturbed) | ||||||
|  |  | ||||||
|  | blank_hsync             mov     vscl,_hf                'hsync, do invisible front porch pixels | ||||||
|  |                         waitvid hv,#0 | ||||||
|  |  | ||||||
|  |                         mov     vscl,_hs                'do invisble sync pixels | ||||||
|  |                         xor     hv,#%10 | ||||||
|  |                         waitvid hv,#0 | ||||||
|  |  | ||||||
|  |                         mov     vscl,_hb                'do invisible back porch pixels | ||||||
|  |                         xor     hv,#%10 | ||||||
|  |                         waitvid hv,#0 | ||||||
|  |  | ||||||
|  |                         djnz    x,#blank_line   wc      '(c=0) | ||||||
|  |  | ||||||
|  |                         movd    bcolor,#hv | ||||||
|  | blank_hsync_ret | ||||||
|  | blank_line_ret | ||||||
|  | blank_vsync_ret         ret | ||||||
|  | ' | ||||||
|  | ' | ||||||
|  | ' Tasks - performed in sections during invisible back porch lines | ||||||
|  | ' | ||||||
|  | tasks                   mov     t1,par                  'load parameters | ||||||
|  |                         movd    :par,#_enable           '(skip _status) | ||||||
|  |                         mov     t2,#paramcount - 1 | ||||||
|  | :load                   add     t1,#4 | ||||||
|  | :par                    rdlong  0,t1 | ||||||
|  |                         add     :par,d0 | ||||||
|  |                         djnz    t2,#:load               '+164 | ||||||
|  |  | ||||||
|  |                         mov     t1,#2                   'set video pins and directions | ||||||
|  |                         shl     t1,_pins                '(if video disabled, pins will drive low) | ||||||
|  |                         sub     t1,#1 | ||||||
|  |                         test    _pins,#$20      wc | ||||||
|  |                         and     _pins,#$38 | ||||||
|  |                         shr     t1,_pins | ||||||
|  |                         movs    vcfg,t1 | ||||||
|  |                         shl     t1,_pins | ||||||
|  |                         shr     _pins,#3 | ||||||
|  |                         movd    vcfg,_pins | ||||||
|  |         if_nc           mov     dira,t1 | ||||||
|  |         if_nc           mov     dirb,#0 | ||||||
|  |         if_c            mov     dira,#0 | ||||||
|  |         if_c            mov     dirb,t1                 '+14 | ||||||
|  |  | ||||||
|  |                         tjz     _enable,#disabled       '+2, disabled? | ||||||
|  |  | ||||||
|  |                         jmpret  taskptr,taskret         '+1=181, break and return later | ||||||
|  |  | ||||||
|  |                         rdlong  t1,#0                   'make sure CLKFREQ => 16MHz | ||||||
|  |                         shr     t1,#1 | ||||||
|  |                         cmp     t1,m8           wc | ||||||
|  |         if_c            jmp     #disabled               '+8 | ||||||
|  |  | ||||||
|  |                         min     _rate,pllmin            'limit _rate to pll range | ||||||
|  |                         max     _rate,pllmax            '+2 | ||||||
|  |  | ||||||
|  |                         mov     t1,#%00001_011          'set ctra configuration | ||||||
|  | :max                    cmp     m8,_rate        wc      'adjust rate to be within 4MHz-8MHz | ||||||
|  |         if_c            shr     _rate,#1                '(vco will be within 64MHz-128MHz) | ||||||
|  |         if_c            add     t1,#%00000_001 | ||||||
|  |         if_c            jmp     #:max | ||||||
|  | :min                    cmp     _rate,m4        wc | ||||||
|  |         if_c            shl     _rate,#1 | ||||||
|  |         if_c            sub     x,#%00000_001 | ||||||
|  |         if_c            jmp     #:min | ||||||
|  |                         movi    ctra,t1                 '+22 | ||||||
|  |  | ||||||
|  |                         rdlong  t1,#0                   'divide _rate/CLKFREQ and set frqa | ||||||
|  |                         mov     hvbase,#32+1 | ||||||
|  | :div                    cmpsub  _rate,t1        wc | ||||||
|  |                         rcl     t2,#1 | ||||||
|  |                         shl     _rate,#1 | ||||||
|  |                         djnz    hvbase,#:div            '(hvbase=0) | ||||||
|  |                         mov     frqa,t2                 '+136 | ||||||
|  |  | ||||||
|  |                         test    _mode,#%0001    wc      'make hvbase | ||||||
|  |                         muxnc   hvbase,vmask | ||||||
|  |                         test    _mode,#%0010    wc | ||||||
|  |                         muxnc   hvbase,hmask            '+4 | ||||||
|  |  | ||||||
|  |                         jmpret  taskptr,taskret         '+1=173, break and return later | ||||||
|  |  | ||||||
|  |                         mov     hx,_hx                  'compute horizontal metrics | ||||||
|  |                         shl     hx,#8 | ||||||
|  |                         or      hx,_hx | ||||||
|  |                         shl     hx,#4 | ||||||
|  |  | ||||||
|  |                         mov     hc2x,_ht | ||||||
|  |                         shl     hc2x,#1 | ||||||
|  |  | ||||||
|  |                         mov     h1,_hd | ||||||
|  |                         neg     h2,_hf | ||||||
|  |                         sub     h2,_hs | ||||||
|  |                         sub     h2,_hb | ||||||
|  |                         sub     h1,h2 | ||||||
|  |                         shr     h1,#1           wc | ||||||
|  |                         addx    h2,h1 | ||||||
|  |  | ||||||
|  |                         mov     t1,_ht | ||||||
|  |                         mov     t2,_hx | ||||||
|  |                         call    #multiply | ||||||
|  |                         mov     hf,_hd | ||||||
|  |                         sub     hf,t1 | ||||||
|  |                         shr     hf,#1           wc | ||||||
|  |                         mov     hb,_ho | ||||||
|  |                         addx    hb,hf | ||||||
|  |                         sub     hf,_ho                  '+59 | ||||||
|  |  | ||||||
|  |                         mov     t1,_vt                  'compute vertical metrics | ||||||
|  |                         mov     t2,_vx | ||||||
|  |                         call    #multiply | ||||||
|  |                         test    _mode,#%1000    wc      'consider tile size | ||||||
|  |                         muxc    linerot,#1 | ||||||
|  |                         mov     lineadd,lineinc | ||||||
|  |         if_c            shr     lineadd,#1 | ||||||
|  |         if_c            shl     t1,#1 | ||||||
|  |                         test    _mode,#%0100    wc      'consider interlace | ||||||
|  |         if_c            shr     t1,#1 | ||||||
|  |                         mov     vf,_vd | ||||||
|  |                         sub     vf,t1 | ||||||
|  |                         shr     vf,#1           wc | ||||||
|  |                         neg     vb,_vo | ||||||
|  |                         addx    vb,vf | ||||||
|  |                         add     vf,_vo                  '+53 | ||||||
|  |  | ||||||
|  |                         movi    vcfg,#%01100_000        '+1, set video configuration | ||||||
|  |  | ||||||
|  | :colors                 jmpret  taskptr,taskret         '+1=114/160, break and return later | ||||||
|  |  | ||||||
|  |                         mov     t1,#13                  'load next 13 colors into colortable | ||||||
|  | :loop                   mov     t2,:color               '5 times = 65 (all 64 colors loaded) | ||||||
|  |                         shr     t2,#9-2 | ||||||
|  |                         and     t2,#$FC | ||||||
|  |                         add     t2,_colors | ||||||
|  |                         rdlong  t2,t2 | ||||||
|  |                         and     t2,colormask | ||||||
|  |                         or      t2,hvbase | ||||||
|  | :color                  mov     colortable,t2 | ||||||
|  |                         add     :color,d0 | ||||||
|  |                         andn    :color,d6 | ||||||
|  |                         djnz    t1,#:loop               '+158 | ||||||
|  |  | ||||||
|  |                         jmp     #:colors                '+1, keep loading colors | ||||||
|  | ' | ||||||
|  | ' | ||||||
|  | ' Multiply t1 * t2 * 16 (t1, t2 = bytes) | ||||||
|  | ' | ||||||
|  | multiply                shl     t2,#8+4-1 | ||||||
|  |  | ||||||
|  |                         mov     tile,#8 | ||||||
|  | :loop                   shr     t1,#1           wc | ||||||
|  |         if_c            add     t1,t2 | ||||||
|  |                         djnz    tile,#:loop | ||||||
|  |  | ||||||
|  | multiply_ret            ret                             '+37 | ||||||
|  | ' | ||||||
|  | ' | ||||||
|  | ' Disabled - reset status, nap ~4ms, try again | ||||||
|  | ' | ||||||
|  | disabled                mov     ctra,#0                 'reset ctra | ||||||
|  |                         mov     vcfg,#0                 'reset video | ||||||
|  |  | ||||||
|  |                         wrlong  outa,par                'set status to disabled | ||||||
|  |  | ||||||
|  |                         rdlong  t1,#0                   'get CLKFREQ | ||||||
|  |                         shr     t1,#8                   'nap for ~4ms | ||||||
|  |                         min     t1,#3 | ||||||
|  |                         add     t1,cnt | ||||||
|  |                         waitcnt t1,#0 | ||||||
|  |  | ||||||
|  |                         jmp     #entry                  'reload parameters | ||||||
|  | ' | ||||||
|  | ' | ||||||
|  | ' Initialized data | ||||||
|  | ' | ||||||
|  | pllmin                  long    500_000                 'pll lowest output frequency | ||||||
|  | pllmax                  long    128_000_000             'pll highest output frequency | ||||||
|  | m8                      long    8_000_000               '*16 = 128MHz (pll vco max) | ||||||
|  | m4                      long    4_000_000               '*16 = 64MHz (pll vco min) | ||||||
|  | d0                      long    1 << 9 << 0 | ||||||
|  | d6                      long    1 << 9 << 6 | ||||||
|  | invisible               long    1 | ||||||
|  | visible                 long    2 | ||||||
|  | line                    long    $00060000 | ||||||
|  | lineinc                 long    $10000000 | ||||||
|  | linerot                 long    0 | ||||||
|  | vmask                   long    $01010101 | ||||||
|  | hmask                   long    $02020202 | ||||||
|  | colormask               long    $FCFCFCFC | ||||||
|  | ' | ||||||
|  | ' | ||||||
|  | ' Uninitialized data | ||||||
|  | ' | ||||||
|  | taskptr                 res     1                       'tasks | ||||||
|  | taskret                 res     1 | ||||||
|  | t1                      res     1 | ||||||
|  | t2                      res     1 | ||||||
|  |  | ||||||
|  | x                       res     1                       'display | ||||||
|  | y                       res     1 | ||||||
|  | hf                      res     1 | ||||||
|  | hb                      res     1 | ||||||
|  | vf                      res     1 | ||||||
|  | vb                      res     1 | ||||||
|  | hx                      res     1 | ||||||
|  | vx                      res     1 | ||||||
|  | hc2x                    res     1 | ||||||
|  | screen                  res     1 | ||||||
|  | tile                    res     1 | ||||||
|  | pixels                  res     1 | ||||||
|  | lineadd                 res     1 | ||||||
|  | interlace               res     1 | ||||||
|  | hv                      res     1 | ||||||
|  | hvbase                  res     1 | ||||||
|  | h1                      res     1 | ||||||
|  | h2                      res     1 | ||||||
|  | ' | ||||||
|  | ' | ||||||
|  | ' Parameter buffer | ||||||
|  | ' | ||||||
|  | _enable                 res     1       '0/non-0        read-only | ||||||
|  | _pins                   res     1       '%pppttt        read-only | ||||||
|  | _mode                   res     1       '%tihv          read-only | ||||||
|  | _screen                 res     1       '@word          read-only | ||||||
|  | _colors                 res     1       '@long          read-only | ||||||
|  | _ht                     res     1       '1+             read-only | ||||||
|  | _vt                     res     1       '1+             read-only | ||||||
|  | _hx                     res     1       '1+             read-only | ||||||
|  | _vx                     res     1       '1+             read-only | ||||||
|  | _ho                     res     1       '0+-            read-only | ||||||
|  | _vo                     res     1       '0+-            read-only | ||||||
|  | _hd                     res     1       '1+             read-only | ||||||
|  | _hf                     res     1       '1+             read-only | ||||||
|  | _hs                     res     1       '1+             read-only | ||||||
|  | _hb                     res     1       '1+             read-only | ||||||
|  | _vd                     res     1       '1+             read-only | ||||||
|  | _vf                     res     1       '1+             read-only | ||||||
|  | _vs                     res     1       '1+             read-only | ||||||
|  | _vb                     res     1       '2+             read-only | ||||||
|  | _rate                   res     1       '500_000+       read-only | ||||||
|  |  | ||||||
|  |                         fit     colortable              'fit underneath colortable ($180-$1BF) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | '' | ||||||
|  | ''___ | ||||||
|  | ''VAR                   'VGA parameters - 21 contiguous longs | ||||||
|  | '' | ||||||
|  | ''  long  vga_status    '0/1/2 = off/visible/invisible      read-only | ||||||
|  | ''  long  vga_enable    '0/non-0 = off/on                   write-only | ||||||
|  | ''  long  vga_pins      '%pppttt = pins                     write-only | ||||||
|  | ''  long  vga_mode      '%tihv = tile,interlace,hpol,vpol   write-only | ||||||
|  | ''  long  vga_screen    'pointer to screen (words)          write-only | ||||||
|  | ''  long  vga_colors    'pointer to colors (longs)          write-only             | ||||||
|  | ''  long  vga_ht        'horizontal tiles                   write-only | ||||||
|  | ''  long  vga_vt        'vertical tiles                     write-only | ||||||
|  | ''  long  vga_hx        'horizontal tile expansion          write-only | ||||||
|  | ''  long  vga_vx        'vertical tile expansion            write-only | ||||||
|  | ''  long  vga_ho        'horizontal offset                  write-only | ||||||
|  | ''  long  vga_vo        'vertical offset                    write-only | ||||||
|  | ''  long  vga_hd        'horizontal display ticks           write-only | ||||||
|  | ''  long  vga_hf        'horizontal front porch ticks       write-only | ||||||
|  | ''  long  vga_hs        'horizontal sync ticks              write-only | ||||||
|  | ''  long  vga_hb        'horizontal back porch ticks        write-only | ||||||
|  | ''  long  vga_vd        'vertical display lines             write-only | ||||||
|  | ''  long  vga_vf        'vertical front porch lines         write-only | ||||||
|  | ''  long  vga_vs        'vertical sync lines                write-only | ||||||
|  | ''  long  vga_vb        'vertical back porch lines          write-only | ||||||
|  | ''  long  vga_rate      'tick rate (Hz)                     write-only | ||||||
|  | '' | ||||||
|  | ''The preceding VAR section may be copied into your code. | ||||||
|  | ''After setting variables, do start(@vga_status) to start driver. | ||||||
|  | '' | ||||||
|  | ''All parameters are reloaded each superframe, allowing you to make live | ||||||
|  | ''changes. To minimize flicker, correlate changes with vga_status. | ||||||
|  | '' | ||||||
|  | ''Experimentation may be required to optimize some parameters. | ||||||
|  | '' | ||||||
|  | ''Parameter descriptions: | ||||||
|  | ''  __________ | ||||||
|  | ''  vga_status | ||||||
|  | '' | ||||||
|  | ''    driver sets this to indicate status: | ||||||
|  | ''      0: driver disabled (vga_enable = 0 or CLKFREQ < 16MHz) | ||||||
|  | ''      1: currently outputting invisible sync data | ||||||
|  | ''      2: currently outputting visible screen data | ||||||
|  | ''  __________ | ||||||
|  | ''  vga_enable | ||||||
|  | '' | ||||||
|  | ''        0: disable (pins will be driven low, reduces power) | ||||||
|  | ''    non-0: enable | ||||||
|  | ''  ________ | ||||||
|  | ''  vga_pins | ||||||
|  | '' | ||||||
|  | ''    bits 5..3 select pin group: | ||||||
|  | ''      %000: pins 7..0 | ||||||
|  | ''      %001: pins 15..8 | ||||||
|  | ''      %010: pins 23..16 | ||||||
|  | ''      %011: pins 31..24 | ||||||
|  | ''      %100: pins 39..32 | ||||||
|  | ''      %101: pins 47..40 | ||||||
|  | ''      %110: pins 55..48 | ||||||
|  | ''      %111: pins 63..56 | ||||||
|  | '' | ||||||
|  | ''    bits 2..0 select top pin within group | ||||||
|  | ''    for example: %01111 (15) will use pins %01000-%01111 (8-15) | ||||||
|  | ''  ________ | ||||||
|  | ''  vga_mode | ||||||
|  | '' | ||||||
|  | ''    bit 3 selects between 16x16 and 16x32 pixel tiles: | ||||||
|  | ''      0: 16x16 pixel tiles (tileheight = 16) | ||||||
|  | ''      1: 16x32 pixel tiles (tileheight = 32) | ||||||
|  | '' | ||||||
|  | ''    bit 2 controls interlace: | ||||||
|  | ''      0: progressive scan (less flicker, good for motion, required for LCD monitors) | ||||||
|  | ''      1: interlaced scan (allows you to double vga_vt, good for text) | ||||||
|  | '' | ||||||
|  | ''    bits 1 and 0 select horizontal and vertical sync polarity, respectively | ||||||
|  | ''      0: active low | ||||||
|  | ''      1: active high | ||||||
|  | ''  __________ | ||||||
|  | ''  vga_screen | ||||||
|  | '' | ||||||
|  | ''    pointer to words which define screen contents (left-to-right, top-to-bottom) | ||||||
|  | ''      number of words must be vga_ht * vga_vt | ||||||
|  | ''      each word has two bitfields: a 6-bit colorset ptr and a 10-bit pixelgroup ptr | ||||||
|  | ''        bits 15..10: select the colorset* for the associated pixel tile | ||||||
|  | ''        bits 9..0: select the pixelgroup** address %ppppppppppcccc00 (p=address, c=0..15) | ||||||
|  | '' | ||||||
|  | ''       * colorsets are longs which each define four 8-bit colors | ||||||
|  | '' | ||||||
|  | ''      ** pixelgroups are <tileheight> longs which define (left-to-right, top-to-bottom) the 2-bit | ||||||
|  | ''         (four color) pixels that make up a 16x16 or a 16x32 pixel tile | ||||||
|  | ''  __________ | ||||||
|  | ''  vga_colors | ||||||
|  | '' | ||||||
|  | ''    pointer to longs which define colorsets | ||||||
|  | ''      number of longs must be 1..64 | ||||||
|  | ''      each long has four 8-bit fields which define colors for 2-bit (four color) pixels | ||||||
|  | ''      first long's bottom color is also used as the screen background color | ||||||
|  | ''      8-bit color fields are as follows: | ||||||
|  | ''        bits 7..2: actual state of pins 7..2 within pin group* | ||||||
|  | ''        bits 1..0: don't care (used within driver for hsync and vsync) | ||||||
|  | '' | ||||||
|  | ''    * it is suggested that: | ||||||
|  | ''        bits/pins 7..6 are used for red | ||||||
|  | ''        bits/pins 5..4 are used for green | ||||||
|  | ''        bits/pins 3..2 are used for blue | ||||||
|  | ''      for each bit/pin set, sum 240 and 470-ohm resistors to form 75-ohm 1V signals | ||||||
|  | ''      connect signal sets to RED, GREEN, and BLUE on VGA connector | ||||||
|  | ''      always connect group pin 1 to HSYNC on VGA connector via 240-ohm resistor | ||||||
|  | ''      always connect group pin 0 to VSYNC on VGA connector via 240-ohm resistor | ||||||
|  | ''  ______ | ||||||
|  | ''  vga_ht | ||||||
|  | '' | ||||||
|  | ''    horizontal number of pixel tiles - must be at least 1 | ||||||
|  | ''  ______ | ||||||
|  | ''  vga_vt | ||||||
|  | '' | ||||||
|  | ''    vertical number of pixel tiles - must be at least 1 | ||||||
|  | ''  ______ | ||||||
|  | ''  vga_hx | ||||||
|  | '' | ||||||
|  | ''    horizontal tile expansion factor - must be at least 1 | ||||||
|  | '' | ||||||
|  | ''    make sure 16 * vga_ht * vga_hx + ||vga_ho is equal to or at least 16 less than vga_hd | ||||||
|  | ''  ______ | ||||||
|  | ''  vga_vx | ||||||
|  | '' | ||||||
|  | ''    vertical tile expansion factor - must be at least 1 | ||||||
|  | '' | ||||||
|  | ''    make sure <tileheight> * vga_vt * vga_vx + ||vga_vo does not exceed vga_vd | ||||||
|  | ''      (for interlace, use <tileheight> / 2 * vga_vt * vga_vx + ||vga_vo) | ||||||
|  | ''  ______ | ||||||
|  | ''  vga_ho | ||||||
|  | '' | ||||||
|  | ''    horizontal offset in ticks - pos/neg value (0 recommended) | ||||||
|  | ''    shifts the display right/left | ||||||
|  | ''  ______ | ||||||
|  | ''  vga_vo | ||||||
|  | '' | ||||||
|  | ''    vertical offset in lines - pos/neg value (0 recommended) | ||||||
|  | ''    shifts the display up/down | ||||||
|  | ''  ______ | ||||||
|  | ''  vga_hd | ||||||
|  | '' | ||||||
|  | ''    horizontal display ticks | ||||||
|  | ''  ______ | ||||||
|  | ''  vga_hf | ||||||
|  | '' | ||||||
|  | ''    horizontal front porch ticks | ||||||
|  | ''  ______ | ||||||
|  | ''  vga_hs | ||||||
|  | '' | ||||||
|  | ''    horizontal sync ticks | ||||||
|  | ''  ______ | ||||||
|  | ''  vga_hb | ||||||
|  | '' | ||||||
|  | ''    horizontal back porch ticks | ||||||
|  | ''  ______ | ||||||
|  | ''  vga_vd | ||||||
|  | '' | ||||||
|  | ''    vertical display lines | ||||||
|  | ''  ______ | ||||||
|  | ''  vga_vf | ||||||
|  | '' | ||||||
|  | ''    vertical front porch lines | ||||||
|  | ''  ______ | ||||||
|  | ''  vga_vs | ||||||
|  | '' | ||||||
|  | ''    vertical sync lines | ||||||
|  | ''  ______ | ||||||
|  | ''  vga_vb | ||||||
|  | '' | ||||||
|  | ''    vertical back porch lines | ||||||
|  | ''  ________ | ||||||
|  | ''  vga_rate | ||||||
|  | '' | ||||||
|  | ''    tick rate in Hz | ||||||
|  | '' | ||||||
|  | ''    driver will limit value to be within 500KHz and 128MHz | ||||||
|  | ''    pixel rate (vga_rate / vga_hx) should be no more than CLKFREQ / 4 | ||||||
|  |  | ||||||
|  | {{ | ||||||
|  |  | ||||||
|  | ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ | ||||||
|  | │                                                   TERMS OF USE: MIT License                                                  │                                                             | ||||||
|  | ├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ | ||||||
|  | │Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation    │  | ||||||
|  | │files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,    │ | ||||||
|  | │modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ | ||||||
|  | │is furnished to do so, subject to the following conditions:                                                                   │ | ||||||
|  | │                                                                                                                              │ | ||||||
|  | │The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ | ||||||
|  | │                                                                                                                              │ | ||||||
|  | │THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE          │ | ||||||
|  | │WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR         │ | ||||||
|  | │COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,   │ | ||||||
|  | │ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                         │ | ||||||
|  | └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ | ||||||
|  | }} | ||||||
							
								
								
									
										737
									
								
								samples/Propeller Spin/VocalTract.spin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										737
									
								
								samples/Propeller Spin/VocalTract.spin
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,737 @@ | |||||||
|  | {{ | ||||||
|  | ┌───────────────────────────────────────────┬────────────────┬───────────────────────────────────┬─────────────────┐ | ||||||
|  | │ Vocal Tract v1.1                          │ by Chip Gracey │ Copyright (c) 2006 Parallax, Inc. │ 28 October 2006 │ | ||||||
|  | ├───────────────────────────────────────────┴────────────────┴───────────────────────────────────┴─────────────────┤ | ||||||
|  | │                                                                                                                  │ | ||||||
|  | │ This object synthesizes a human vocal tract in real-time. It requires one cog and at least 80 MHz.               │ | ||||||
|  | │                                                                                                                  │ | ||||||
|  | │ The vocal tract is controlled via 13 single-byte parameters which must reside in the parent object:              │ | ||||||
|  | │                                                                                                                  │ | ||||||
|  | │ VAR byte aa,ga,gp,vp,vr,f1,f2,f3,f4,na,nf,fa,ff    'vocal tract parameters                                       │ | ||||||
|  | │                                                                                                                  │ | ||||||
|  | │                                                                                                                  │ | ||||||
|  | │                        aa                                                                                        │ | ||||||
|  | │                  ┌────────────┐                                                                                  │ | ||||||
|  | │                  │ ASPIRATION ├──┐                                                                              │ | ||||||
|  | │                  └────────────┘   │     f1       f2       f3       f4      na   nf                               │ | ||||||
|  | │                                      ┌────┐   ┌────┐   ┌────┐   ┌────┐   ┌───────┐                              │ | ||||||
|  | │                                  +┣──┤ F1 ├──┤ F2 ├──┤ F3 ├──┤ F4 ├──┤ NASAL ├──┐                          │ | ||||||
|  | │                       ga   gp        └────┘   └────┘   └────┘   └────┘   └───────┘   │                          │ | ||||||
|  | │                     ┌─────────┐   │                                                                             │ | ||||||
|  | │                     │ GLOTTAL ├──┘                                                  +┣── OUTPUT                │ | ||||||
|  | │                     └────┬────┘                                          fa   ff                                │ | ||||||
|  | │                                                                      ┌───────────┐   │                          │ | ||||||
|  | │                       vp │ vr                                         │ FRICATION ├──┘                          │ | ||||||
|  | │                     ┌────┴────┐                                       └───────────┘                              │ | ||||||
|  | │                     │ VIBRATO │                                                                                  │ | ||||||
|  | │                     └─────────┘                                                                                  │ | ||||||
|  | │                                                                                                                  │ | ||||||
|  | │                                                                                                                  │ | ||||||
|  | │       ┌───────────┬──────────────────────┬─────────────┬────────────────────────────────────────────────┐        │ | ||||||
|  | │       │ parameter │ description          │ unit        │ notes                                          │        │ | ||||||
|  | │       ├───────────┼──────────────────────┼─────────────┼────────────────────────────────────────────────┤        │ | ||||||
|  | │       │    aa     │ aspiration amplitude │ 0..255      │ breath volume: silent..loud, linear            │        │ | ||||||
|  | │       │    ga     │ glottal amplitude    │ 0..255      │ voice volume: silent..loud, linear             │        │ | ||||||
|  | │       │    gp     │ glottal pitch        │ 1/48 octave │ voice pitch: 100 ─ 110.00Hz (musical note A2) │        │ | ||||||
|  | │       │    vp     │ vibrato pitch        │ 1/48 octave │ voice vibrato pitch: 48 ─ ± 1/2 octave swing  │        │ | ||||||
|  | │       │    vr     │ vibrato rate         │ 0.0763 Hz   │ voice vibrato rate: 52 ─ 4 Hz                 │        │ | ||||||
|  | │       │    f1     │ formant1 frequency   │ 19.53 Hz    │ 1st resonator frequency: 40 ─ 781 Hz          │        │ | ||||||
|  | │       │    f2     │ formant2 frequency   │ 19.53 Hz    │ 2nd resonator frequency: 56 ─ 1094 Hz         │        │ | ||||||
|  | │       │    f3     │ formant3 frequency   │ 19.53 Hz    │ 3rd resonator frequency: 128 ─ 2500 Hz        │        │ | ||||||
|  | │       │    f4     │ formant4 frequency   │ 19.53 Hz    │ 4th resonator frequency: 179 ─ 3496 Hz        │        │ | ||||||
|  | │       │    na     │ nasal amplitude      │ 0..255      │ anti-resonator level: off..on, linear          │        │ | ||||||
|  | │       │    nf     │ nasal frequency      │ 19.53 Hz    │ anti-resonator frequency: 102 ─ 1992 Hz       │        │ | ||||||
|  | │       │    fa     │ frication amplitude  │ 0..255      │ white noise volume: silent..loud, linear       │        │ | ||||||
|  | │       │    ff     │ frication frequency  │ 39.06 Hz    │ white noise frequency: 60 ─ 2344 Hz ("Sh")    │        │ | ||||||
|  | │       └───────────┴──────────────────────┴─────────────┴────────────────────────────────────────────────┘        │ | ||||||
|  | │                                                                                                                  │ | ||||||
|  | │ The parent object alternately modifies one or more of these parameters and then calls the go(time) method to     │ | ||||||
|  | │ queue the entire 13-parameter frame for feeding to the vocal tract. The vocal tract will load one queued frame   │ | ||||||
|  | │ after another and smoothly interpolate between them over specified amounts of time without interruption. Up to   │ | ||||||
|  | │ eight frames will be queued in order to relax the frame-generation timing requirement of the parent object. If   │ | ||||||
|  | │ eight frames are queued, the parent must then wait to queue another frame. If the vocal tract runs out of        │ | ||||||
|  | │ frames, it will continue generating samples based on the last frame. When a new frame is queued, it will         │ | ||||||
|  | │ immediately load it and begin inter-polating towards it.                                                         │                                     | ||||||
|  | │                                                                                                                  │ | ||||||
|  | │ The vocal tract generates audio samples at a continuous rate of 20KHz. These samples can be output to pins via   │ | ||||||
|  | │ delta-modulation for RC filtering or direct transducer driving. An FM aural subcarrier can also be generated for │ | ||||||
|  | │ inclusion into a TV broadcast controlled by another cog. Regardless of any output mode, samples are always       │ | ||||||
|  | │ streamed into a special variable so that other objects can access them in real-time.                             │                                                            | ||||||
|  | │                                                                                                                  │ | ||||||
|  | │ In order to achieve optimal sound quality, it is worthwhile to maximize amplitudes such as 'ga' to the point     │ | ||||||
|  | │ just shy of numerical overflow. Numerical overflow results in high-amplitude noise bursts which are quite        │ | ||||||
|  | │ disruptive. The closeness of 'f1'-'f4' and their relationship to 'gp' can greatly influence the amount of 'ga'   │ | ||||||
|  | │ that can be applied before overflow occurs. You must determine through experimentation what the limits are. By   │ | ||||||
|  | │ pushing 'ga' close to the overflow point, you will maximize the signal-to-noise ratio of the vocal tract,        │ | ||||||
|  | │ resulting in the highest quality sound. Once your vocal tract programming is complete, the attenuation level     │ | ||||||
|  | │ can then be used to reduce the overall output in 3dB steps while preserving the signal-to-noise ratio.           │                                        | ||||||
|  | │                                                                                                                  │ | ||||||
|  | ├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ | ||||||
|  | │ Revision History                                                                   v1.0 released 26 October 2006 │ | ||||||
|  | │                                                                                                                  │ | ||||||
|  | │ v1.1  If the vocal tract runs out of frames, its internal parameters will now be brought all the way to the      │ | ||||||
|  | │       last frame's values. Before, they were left one interpolation point shy, and then set to the last frame's  │ | ||||||
|  | │       values at the start of the next frame. For continuous frames this was trivial, but it posed a problem      │ | ||||||
|  | │       during frame gaps because the internal parameters would get stalled at transition points just shy of the   │ | ||||||
|  | │       last frame's values. This change makes the vocal tract behave more sensibly during frame gaps.             │                                                                         | ||||||
|  | │                                                                                                                  │ | ||||||
|  | └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘                                      | ||||||
|  |                                                                                                                                              | ||||||
|  | }}                                                                                                                                           | ||||||
|  | CON                                                                                                                                          | ||||||
|  |                                                                                                                                              | ||||||
|  |   frame_buffers = 8                                     'frame buffers (2n)                                                                 | ||||||
|  |                                                                                                                                              | ||||||
|  |   frame_bytes = 3 {for stepsize} + 13 {for aa..ff}      '16 bytes per frame                                                                  | ||||||
|  |   frame_longs = frame_bytes / 4                         '4 longs per frame                                                                   | ||||||
|  |                                                                                                                                              | ||||||
|  |   frame_buffer_bytes = frame_bytes * frame_buffers                                                                                           | ||||||
|  |   frame_buffer_longs = frame_longs * frame_buffers                                                                                           | ||||||
|  |                                                                                                                                              | ||||||
|  |                                                                                                                                              | ||||||
|  | VAR                                                                                                                                          | ||||||
|  |                                                                                                                                              | ||||||
|  |   long  cog, tract, pace                                                                                                                     | ||||||
|  |                                                                                                                                              | ||||||
|  |   long  index, attenuation, sample                      '3 longs       ...must                                                               | ||||||
|  |   long  dira_, dirb_, ctra_, ctrb_, frqa_, cnt_         '6 longs       ...be                                                                 | ||||||
|  |   long  frames[frame_buffer_longs]                      'many longs    ...contiguous                                                         | ||||||
|  |                                                                                                                                              | ||||||
|  |                                                                                                                                              | ||||||
|  | PUB start(tract_ptr, pos_pin, neg_pin, fm_offset) : okay                                                                                     | ||||||
|  |                                                                                                                                              | ||||||
|  | '' Start vocal tract driver - starts a cog                                                                                                   | ||||||
|  | '' returns false if no cog available                                                                                                         | ||||||
|  | ''                                                                                                                                           | ||||||
|  | ''   tract_ptr = pointer to vocal tract parameters (13 bytes)                                                                                | ||||||
|  | ''     pos_pin = positive delta-modulation pin (-1 to disable)                                                                               | ||||||
|  | ''     neg_pin = negative delta-modulation pin (pos_pin must also be enabled, -1 to disable)                                                 | ||||||
|  | ''   fm_offset = offset frequency for fm aural subcarrier generation (-1 to disable, 4_500_000 for NTSC)                                     | ||||||
|  |                                                                                                                                              | ||||||
|  |   'Reset driver                                                                                                                              | ||||||
|  |   stop                                                                                                                                       | ||||||
|  |                                                                                                                                              | ||||||
|  |   'Remember vocal tract parameters pointer                                                                                                   | ||||||
|  |   tract := tract_ptr                                                                                                                         | ||||||
|  |                                                                                                                                              | ||||||
|  |   'Initialize pace to 100%                                                                                                                   | ||||||
|  |   pace := 100                                                                                                                                | ||||||
|  |                                                                                                                                              | ||||||
|  |   'If delta-modulation pin(s) enabled, ready output(s) and ready ctrb for duty mode                                                          | ||||||
|  |   if pos_pin > -1                                                                                                                            | ||||||
|  |     dira_[pos_pin >> 5 & 1] |= |< pos_pin                                                                                                    | ||||||
|  |     ctrb_ := $18000000 + pos_pin & $3F                                                                                                       | ||||||
|  |     if neg_pin > -1                                                                                                                          | ||||||
|  |       dira_[neg_pin >> 5 & 1] |= |< neg_pin                                                                                                  | ||||||
|  |       ctrb_ += $04000000 + (neg_pin & $3F) << 9                                                                                              | ||||||
|  |                                                                                                                                              | ||||||
|  |   'If fm offset is valid, ready ctra for pll mode with divide-by-16 (else disabled)                                                          | ||||||
|  |   if fm_offset > -1                                                                                                                          | ||||||
|  |     ctra_ := $05800000                                                                                                                       | ||||||
|  |                                                                                                                                              | ||||||
|  |   'Ready frqa value for fm offset                                                                                                            | ||||||
|  |   repeat 33                                                                                                                                  | ||||||
|  |     frqa_ <<= 1                                                                                                                              | ||||||
|  |     if fm_offset => clkfreq                                                                                                                  | ||||||
|  |       fm_offset -= clkfreq                                                                                                                   | ||||||
|  |       frqa_++                                                                                                                                | ||||||
|  |     fm_offset <<= 1                                                                                                                          | ||||||
|  |                                                                                                                                              | ||||||
|  |   'Ready 20KHz sample period                                                                                                                 | ||||||
|  |   cnt_ := clkfreq / 20_000                                                                                                                   | ||||||
|  |                                                                                                                                              | ||||||
|  |   'Launch vocal tract cog                                                                                                                    | ||||||
|  |   return cog := cognew(@entry, @attenuation) + 1                                                                                             | ||||||
|  |                                                                                                                                              | ||||||
|  |                                                                                                                                              | ||||||
|  | PUB stop                                                                                                                                     | ||||||
|  |                                                                                                                                              | ||||||
|  | '' Stop vocal tract driver - frees a cog                                                                                                     | ||||||
|  |                                                                                                                                              | ||||||
|  |   'If already running, stop vocal tract cog                                                                                                  | ||||||
|  |   if cog                                                                                                                                     | ||||||
|  |     cogstop(cog~ -  1)                                                                                                                       | ||||||
|  |                                                                                                                                              | ||||||
|  |   'Reset variables and buffers | ||||||
|  |   longfill(@index, 0, constant(3 + 6 + frame_buffer_longs)) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB set_attenuation(level) | ||||||
|  |  | ||||||
|  | '' Set master attenuation level (0..7, initially 0) | ||||||
|  |  | ||||||
|  |   attenuation := level | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB set_pace(percentage) | ||||||
|  |  | ||||||
|  | '' Set pace to some percentage (initially 100) | ||||||
|  |  | ||||||
|  |   pace := percentage | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB go(time) | ||||||
|  |  | ||||||
|  | '' Queue current parameters to transition over time | ||||||
|  | '' | ||||||
|  | ''   actual time = integer(time * 100 / pace) #> 2 * 700µs (at least 1400µs, see set_pace) | ||||||
|  |  | ||||||
|  |   'Wait until frame available (first long will be zeroed) | ||||||
|  |   repeat while frames[index] | ||||||
|  |  | ||||||
|  |   'Load parameters into frame | ||||||
|  |   bytemove(@frames[index] + 3, tract, 13) | ||||||
|  |  | ||||||
|  |   'Write stepsize into frame (non-0 alerts vocal tract that frame is ready) | ||||||
|  |   frames[index] |= $01000000 / (time * 100 / pace #> 2) | ||||||
|  |  | ||||||
|  |   'Increment frame index | ||||||
|  |   index := (index + frame_longs) & constant(frame_buffer_longs - 1) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB full : status | ||||||
|  |  | ||||||
|  | '' Returns true if the parameter queue is full | ||||||
|  | '' (useful for checking if "go" would have to wait)  | ||||||
|  |  | ||||||
|  |   return frames[index] | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PUB empty : status | i | ||||||
|  |  | ||||||
|  | '' Returns true if the parameter queue is empty | ||||||
|  | '' (useful for detecting when the vocal tract is finished) | ||||||
|  |  | ||||||
|  |   repeat i from 0 to constant(frame_buffers - 1) | ||||||
|  |     if frames[i * frame_longs] | ||||||
|  |       return {false} | ||||||
|  |   return true | ||||||
|  |    | ||||||
|  |   | ||||||
|  | PUB sample_ptr : ptr | ||||||
|  |  | ||||||
|  | '' Returns the address of the long which receives the audio samples in real-time | ||||||
|  | '' (signed 32-bit values updated at 20KHz) | ||||||
|  |  | ||||||
|  |   return @sample | ||||||
|  |    | ||||||
|  |  | ||||||
|  | PUB aural_id : id | ||||||
|  |  | ||||||
|  | '' Returns the id of the cog executing the vocal tract algorithm | ||||||
|  | '' (for connecting a broadcast tv driver with the aural subcarrier) | ||||||
|  |  | ||||||
|  |   return cog - 1 | ||||||
|  |  | ||||||
|  |  | ||||||
|  | DAT | ||||||
|  |  | ||||||
|  | ' ┌──────────────────┐ | ||||||
|  | ' │  Initialization  │ | ||||||
|  | ' └──────────────────┘ | ||||||
|  |  | ||||||
|  | entry                   org | ||||||
|  |  | ||||||
|  | :zero                   mov     reserves,#0             'zero all reserved data | ||||||
|  |                         add     :zero,d0 | ||||||
|  |                         djnz    clear_cnt,#:zero | ||||||
|  |  | ||||||
|  |                         mov     t1,#2*15                'assemble 15 multiply steps into reserves | ||||||
|  | :minst                  mov     mult_steps,mult_step    '(saves hub memory) | ||||||
|  |                         add     :minst,d0s0              | ||||||
|  |                         test    t1,#1           wc | ||||||
|  |         if_c            sub     :minst,#2 | ||||||
|  |                         djnz    t1,#:minst | ||||||
|  |                         mov     mult_ret,antilog_ret    'write 'ret' after last instruction | ||||||
|  |  | ||||||
|  |                         mov     t1,#13                  'assemble 13 cordic steps into reserves | ||||||
|  | :cstep                  mov     t2,#8                   '(saves hub memory) | ||||||
|  | :cinst                  mov     cordic_steps,cordic_step | ||||||
|  |                         add     :cinst,d0s0 | ||||||
|  |                         djnz    t2,#:cinst | ||||||
|  |                         sub     :cinst,#8 | ||||||
|  |                         add     cordic_dx,#1 | ||||||
|  |                         add     cordic_dy,#1 | ||||||
|  |                         add     cordic_a,#1 | ||||||
|  |                         djnz    t1,#:cstep                        | ||||||
|  |                         mov     cordic_ret,antilog_ret  'write 'ret' over last instruction | ||||||
|  |  | ||||||
|  |                         mov     t1,par                  'get dira/dirb/ctra/ctrb | ||||||
|  |                         add     t1,#2*4 | ||||||
|  |                         mov     t2,#4 | ||||||
|  | :regs                   rdlong  dira,t1 | ||||||
|  |                         add     t1,#4 | ||||||
|  |                         add     :regs,d0 | ||||||
|  |                         djnz    t2,#:regs | ||||||
|  |  | ||||||
|  |                         rdlong  frqa_center,t1          'get frqa center | ||||||
|  |                          | ||||||
|  |                         add     t1,#4                   'get cnt ticks | ||||||
|  |                         rdlong  cnt_ticks,t1 | ||||||
|  |                          | ||||||
|  |                         mov     cnt_value,cnt           'prepare for initial waitcnt | ||||||
|  |                         add     cnt_value,cnt_ticks | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ' ┌────────────────────┐ | ||||||
|  | ' │  Vocal Tract Loop  │ | ||||||
|  | ' └────────────────────┘ | ||||||
|  |  | ||||||
|  | ' Wait for next sample period, then output sample | ||||||
|  |  | ||||||
|  | loop                    waitcnt cnt_value,cnt_ticks     'wait for sample period | ||||||
|  |  | ||||||
|  |                         rdlong  t1,par                  'perform master attenuation | ||||||
|  |                         sar     x,t1                     | ||||||
|  |  | ||||||
|  |                         mov     t1,x                    'update fm aural subcarrier for tv broadcast | ||||||
|  |                         sar     t1,#10 | ||||||
|  |                         add     t1,frqa_center | ||||||
|  |                         mov     frqa,t1 | ||||||
|  |  | ||||||
|  |                         mov     t1,x                    'update duty cycle output for pin driving | ||||||
|  |                         add     t1,h80000000 | ||||||
|  |                         mov     frqb,t1 | ||||||
|  |  | ||||||
|  |                         mov     t1,par                  'update sample receiver in main memory | ||||||
|  |                         add     t1,#1*4 | ||||||
|  |                         wrlong  x,t1 | ||||||
|  |  | ||||||
|  | ' White noise source | ||||||
|  |  | ||||||
|  |                         test    lfsr,lfsr_taps  wc      'iterate lfsr three times | ||||||
|  |                         rcl     lfsr,#1 | ||||||
|  |                         test    lfsr,lfsr_taps  wc | ||||||
|  |                         rcl     lfsr,#1 | ||||||
|  |                         test    lfsr,lfsr_taps  wc | ||||||
|  |                         rcl     lfsr,#1 | ||||||
|  |  | ||||||
|  | ' Aspiration | ||||||
|  |  | ||||||
|  |                         mov     t1,aa                   'aspiration amplitude | ||||||
|  |                         mov     t2,lfsr | ||||||
|  |                         call    #mult | ||||||
|  |                          | ||||||
|  |                         sar     t1,#8                   'set x | ||||||
|  |                         mov     x,t1 | ||||||
|  |  | ||||||
|  | ' Vibrato | ||||||
|  |  | ||||||
|  |                         mov     t1,vr                   'vibrato rate | ||||||
|  |                         shr     t1,#10 | ||||||
|  |                         add     vphase,t1 | ||||||
|  |  | ||||||
|  |                         mov     t1,vp                   'vibrato pitch | ||||||
|  |                         mov     t2,vphase | ||||||
|  |                         call    #sine | ||||||
|  |                          | ||||||
|  |                         add     t1,gp                   'sum glottal pitch (+) into vibrato pitch (+/-) | ||||||
|  |  | ||||||
|  | ' Glottal pulse | ||||||
|  |  | ||||||
|  |                         shr     t1,#2                   'divide final pitch by 3 to mesh with                                                                    | ||||||
|  |                         mov     t2,t1                   '...12 notes/octave musical scale | ||||||
|  |                         shr     t2,#2                   '(multiply by %0.0101010101010101) | ||||||
|  |                         add     t1,t2                                                              | ||||||
|  |                         mov     t2,t1 | ||||||
|  |                         shr     t2,#4 | ||||||
|  |                         add     t1,t2 | ||||||
|  |                         mov     t2,t1 | ||||||
|  |                         shr     t2,#8 | ||||||
|  |                         add     t1,t2 | ||||||
|  |  | ||||||
|  |                         add     t1,tune                 'tune scale so that gp=100 produces 110.00Hz (A2) | ||||||
|  |  | ||||||
|  |                         call    #antilog                'convert pitch (log frequency) to phase delta | ||||||
|  |                         add     gphase,t2               | ||||||
|  |  | ||||||
|  |                         mov     t1,gphase               'convert phase to glottal pulse sample | ||||||
|  |                         call    #antilog     | ||||||
|  |                         sub     t2,h40000000 | ||||||
|  |                         mov     t1,ga | ||||||
|  |                         call    #sine | ||||||
|  |  | ||||||
|  |                         sar     t1,#6                   'add to x | ||||||
|  |                         add     x,t1 | ||||||
|  |  | ||||||
|  | ' Vocal tract formants | ||||||
|  |  | ||||||
|  |                         mov     y,#0                    'reset y | ||||||
|  |  | ||||||
|  |                         mov     a,f1                    'formant1, sum and rotate (x,y)  | ||||||
|  |                         add     x,f1x                    | ||||||
|  |                         add     y,f1y | ||||||
|  |                         call    #cordic | ||||||
|  |                         mov     f1x,x | ||||||
|  |                         mov     f1y,y | ||||||
|  |  | ||||||
|  |                         mov     a,f2                    'formant2, sum and rotate (x,y)  | ||||||
|  |                         add     x,f2x                    | ||||||
|  |                         add     y,f2y | ||||||
|  |                         call    #cordic | ||||||
|  |                         mov     f2x,x | ||||||
|  |                         mov     f2y,y | ||||||
|  |  | ||||||
|  |                         mov     a,f3                    'formant3, sum and rotate (x,y)  | ||||||
|  |                         add     x,f3x                   | ||||||
|  |                         add     y,f3y | ||||||
|  |                         call    #cordic | ||||||
|  |                         mov     f3x,x | ||||||
|  |                         mov     f3y,y | ||||||
|  |                 | ||||||
|  |                         mov     a,f4                    'formant4, sum and rotate (x,y)     | ||||||
|  |                         add     x,f4x                   | ||||||
|  |                         add     y,f4y | ||||||
|  |                         call    #cordic | ||||||
|  |                         mov     f4x,x | ||||||
|  |                         mov     f4y,y | ||||||
|  |  | ||||||
|  | ' Nasal anti-formant | ||||||
|  |  | ||||||
|  |                         add     nx,x                    'subtract from x (nx negated) | ||||||
|  |  | ||||||
|  |                         mov     a,nf                    'nasal frequency | ||||||
|  |                         call    #cordic | ||||||
|  |  | ||||||
|  |                         mov     t1,na                   'nasal amplitude | ||||||
|  |                         mov     t2,x | ||||||
|  |                         call    #mult | ||||||
|  |                          | ||||||
|  |                         mov     x,nx                    'restore x | ||||||
|  |                         neg     nx,t1                   'negate nx | ||||||
|  |                          | ||||||
|  | ' Frication | ||||||
|  |  | ||||||
|  |                         mov     t1,lfsr                 'phase noise | ||||||
|  |                         sar     t1,#3 | ||||||
|  |                         add     fphase,t1 | ||||||
|  |                         sar     t1,#1 | ||||||
|  |                         add     fphase,t1 | ||||||
|  |  | ||||||
|  |                         mov     t1,ff                   'frication frequency | ||||||
|  |                         shr     t1,#1 | ||||||
|  |                         add     fphase,t1 | ||||||
|  |  | ||||||
|  |                         mov     t1,fa                   'frication amplitude | ||||||
|  |                         mov     t2,fphase | ||||||
|  |                         call    #sine | ||||||
|  |                          | ||||||
|  |                         add     x,t1                    'add to x | ||||||
|  |  | ||||||
|  | ' Handle frame | ||||||
|  |  | ||||||
|  |                         jmp     :ret                    'run segment of frame handler, return to loop | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ' ┌─────────────────┐ | ||||||
|  | ' │  Frame Handler  │ | ||||||
|  | ' └─────────────────┘ | ||||||
|  |  | ||||||
|  | :ret                    long    :wait                   'pointer to next frame handler routine | ||||||
|  |  | ||||||
|  |  | ||||||
|  | :wait                   jmpret  :ret,#loop              '(6 or 17.5 cycles) | ||||||
|  |                         mov     frame_ptr,par           'check for next frame | ||||||
|  |                         add     frame_ptr,#8*4          'point past miscellaneous data | ||||||
|  |                         add     frame_ptr,frame_index   'point to start of frame | ||||||
|  |                         rdlong  step_size,frame_ptr     'get stepsize | ||||||
|  |                         and     step_size,h00FFFFFF  wz 'isolate stepsize and check if not 0 | ||||||
|  |         if_nz           jmp     #:next                  'if not 0, next frame ready | ||||||
|  |          | ||||||
|  |  | ||||||
|  |                         mov     :final1,:finali         'no frame ready, ready to finalize parameters | ||||||
|  |                         mov     frame_cnt,#13           'iterate aa..ff | ||||||
|  |  | ||||||
|  | :final                  jmpret  :ret,#loop              '(13.5 or 4 cycles) | ||||||
|  | :final1                 mov     par_curr,par_next       'current parameter = next parameter | ||||||
|  |                         add     :final1,d0s0            'update pointers | ||||||
|  |                         djnz    frame_cnt,#:final       'another parameter? | ||||||
|  |                          | ||||||
|  |                         jmp     #:wait                  'check for next frame | ||||||
|  |  | ||||||
|  |  | ||||||
|  | :next                   add     step_size,#1            'next frame ready, insure accurate accumulation | ||||||
|  |                         mov     step_acc,step_size      'initialize step accumulator                     | ||||||
|  |  | ||||||
|  |  | ||||||
|  |                         movs    :set1,#par_next         'ready to get parameters and steps for aa..ff | ||||||
|  |                         movd    :set2,#par_curr    | ||||||
|  |                         movd    :set3,#par_next | ||||||
|  |                         movd    :set4,#par_step | ||||||
|  |                         add     frame_ptr,#3            'point to first parameter | ||||||
|  |                         mov     frame_cnt,#13           'iterate aa..ff | ||||||
|  |  | ||||||
|  | :set                    jmpret  :ret,#loop              '(19.5 or 46.5 cycles) | ||||||
|  |                         rdbyte  t1,frame_ptr            'get new parameter | ||||||
|  |                         shl     t1,#24                  'msb justify | ||||||
|  | :set1                   mov     t2,par_next             'get next parameter | ||||||
|  | :set2                   mov     par_curr,t2             'current parameter = next parameter | ||||||
|  | :set3                   mov     par_next,t1             'next parameter = new parameter | ||||||
|  |                         sub     t1,t2           wc      'get next-current delta with sign in c             | ||||||
|  |                         negc    t1,t1                   'make delta absolute (by c, not msb) | ||||||
|  |                         rcl     vscl,#1         wz, nr  'save sign into nz (vscl unaffected) | ||||||
|  |  | ||||||
|  |                         mov     t2,#8                   'multiply delta by step size | ||||||
|  | :mult                   shl     t1,#1           wc | ||||||
|  |         if_c            add     t1,step_size | ||||||
|  |                         djnz    t2,#:mult | ||||||
|  |  | ||||||
|  | :set4                   negnz    par_step,t1            'set signed step | ||||||
|  |  | ||||||
|  |                         add     :set1,#1                'update pointers for next parameter+step | ||||||
|  |                         add     :set2,d0 | ||||||
|  |                         add     :set3,d0 | ||||||
|  |                         add     :set4,d0 | ||||||
|  |                         add     frame_ptr,#1 | ||||||
|  |                         djnz    frame_cnt,#:set         'another parameter? | ||||||
|  |  | ||||||
|  |  | ||||||
|  | :stepframe              jmpret  :ret,#loop              '(47.5 or 8 cycles) | ||||||
|  |                         mov     :step1,:stepi           'ready to step parameters | ||||||
|  |                         mov     frame_cnt,#13           'iterate aa..ff | ||||||
|  |                          | ||||||
|  | :step                   jmpret  :ret,#loop              '(3 or 4 cycles) | ||||||
|  | :step1                  add     par_curr,par_step       'step parameter | ||||||
|  |                         add     :step1,d0s0             'update pointers for next parameter+step | ||||||
|  |                         djnz    frame_cnt,#:step        'another parameter? | ||||||
|  |                          | ||||||
|  |                         add     step_acc,step_size      'accumulate frame steps | ||||||
|  |                         test    step_acc,h01000000  wc  'check for frame steps done | ||||||
|  |         if_nc           jmp     #:stepframe             'another frame step? | ||||||
|  |  | ||||||
|  |          | ||||||
|  |                         sub     frame_ptr,#frame_bytes  'zero stepsize in frame to signal frame done | ||||||
|  |                         wrlong  vscl,frame_ptr | ||||||
|  |  | ||||||
|  |                         add     frame_index,#frame_bytes'point to next frame | ||||||
|  |                         and     frame_index,#frame_buffer_bytes - 1 | ||||||
|  |                          | ||||||
|  |                         jmp     #:wait                  'check for next frame | ||||||
|  |  | ||||||
|  |  | ||||||
|  | :finali                 mov     par_curr,par_next       'instruction used to finalize parameters                  | ||||||
|  | :stepi                  add     par_curr,par_step       'instruction used to step parameters                | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ' ┌────────────────────┐ | ||||||
|  | ' │  Math Subroutines  │ | ||||||
|  | ' └────────────────────┘ | ||||||
|  |  | ||||||
|  | ' Antilog | ||||||
|  | ' | ||||||
|  | '   in:         t1 = log (top 4 bits = whole number, next 11 bits = fraction) | ||||||
|  | ' | ||||||
|  | '   out:        t2 = antilog ($00010000..$FFEA0000) | ||||||
|  |  | ||||||
|  | antilog                 mov     t2,t1                    | ||||||
|  |                         shr     t2,#16                  'position 11-bit fraction | ||||||
|  |                         shr     t1,#16+12               'position 4-bit whole number | ||||||
|  |                         and     t2,h00000FFE            'get table offset | ||||||
|  |                         or      t2,h0000D000            'get table base | ||||||
|  |                         rdword  t2,t2                   'lookup fractional antilog | ||||||
|  |                         or      t2,h00010000            'insert leading bit | ||||||
|  |                         shl     t2,t1                   'shift up by whole number | ||||||
|  |  | ||||||
|  | antilog_ret             ret | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ' Scaled sine | ||||||
|  | ' | ||||||
|  | '   in:         t1 = unsigned scale (15 top bits used) | ||||||
|  | '               t2 = angle (13 top bits used) | ||||||
|  | ' | ||||||
|  | '   out:        t1 = 17-bit * 15-bit scaled sine ($80014000..$7FFEC000) | ||||||
|  |  | ||||||
|  | sine                    shr     t2,#32-13               'get 13-bit angle | ||||||
|  |                         test    t2,h00001000    wz      'get sine quadrant 3|4 into nz | ||||||
|  |                         test    t2,h00000800    wc      'get sine quadrant 2|4 into c | ||||||
|  |                         negc    t2,t2                   'if sine quadrant 2|4, negate table offset | ||||||
|  |                         or      t2,h00007000            'insert sine table base address >> 1 | ||||||
|  |                         shl     t2,#1                   'shift left to get final word address | ||||||
|  |                         rdword  t2,t2                   'read sine word from table | ||||||
|  |                         negnz   t2,t2                   'if quadrant 3|4, negate word | ||||||
|  |                         shl     t2,#15                  'msb-justify result | ||||||
|  |                                                         'multiply follows... | ||||||
|  |  | ||||||
|  | ' Multiply | ||||||
|  | '                                                                                              | ||||||
|  | '   in:         t1 = unsigned multiplier (15 top bits used) | ||||||
|  | '               t2 = signed multiplicand (17 top bits used) | ||||||
|  | ' | ||||||
|  | '   out:        t1 = 32-bit signed product | ||||||
|  |  | ||||||
|  | mult                    shr     t1,#32-15               'position unsigned multiplier | ||||||
|  |  | ||||||
|  |                         sar     t2,#15                  'position signed multiplicand | ||||||
|  |                         shl     t2,#15-1 | ||||||
|  |  | ||||||
|  |                         jmp     #mult_steps             'do multiply steps | ||||||
|  |  | ||||||
|  |  | ||||||
|  | mult_step               sar     t1,#1           wc      'multiply step that gets assembled into reserves (x15) | ||||||
|  |         if_c            add     t1,t2                    | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ' Cordic rotation | ||||||
|  | ' | ||||||
|  | '   in:          a = 0 to <90 degree angle (~13 top bits used) | ||||||
|  | '              x,y = signed coordinates      | ||||||
|  | ' | ||||||
|  | '   out:       x,y = scaled and rotated signed coordinates | ||||||
|  |  | ||||||
|  | cordic                  sar     x,#1                    'multiply (x,y) by %0.10011001 (0.60725 * 0.984)                    | ||||||
|  |                         mov     t1,x                    '...for cordic pre-scaling and slight damping          | ||||||
|  |                         sar     t1,#3 | ||||||
|  |                         add     x,t1 | ||||||
|  |                         mov     t1,x | ||||||
|  |                         sar     t1,#4 | ||||||
|  |                         add     x,t1 | ||||||
|  |                          | ||||||
|  |                         sar     y,#1 | ||||||
|  |                         mov     t1,y | ||||||
|  |                         sar     t1,#3 | ||||||
|  |                         add     y,t1 | ||||||
|  |                         mov     t1,y | ||||||
|  |                         sar     t1,#4 | ||||||
|  |                         add     y,t1 | ||||||
|  |  | ||||||
|  |                         mov     t1,x                    'do first cordic step | ||||||
|  |                         sub     x,y | ||||||
|  |                         add     y,t1 | ||||||
|  |                         sub     a,h80000000     wc | ||||||
|  |  | ||||||
|  |                         jmp     #cordic_steps+1         'do subsequent cordic steps (skip first instruction) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | cordic_step             mov     a,a             wc      'cordic step that gets assembled into reserves (x13) | ||||||
|  |                         mov     t1,y                     | ||||||
|  | cordic_dx               sar     t1,#1                   '(source incremented for each step) | ||||||
|  |                         mov     t2,x | ||||||
|  | cordic_dy               sar     t2,#1                   '(source incremented for each step) | ||||||
|  |                         sumnc   x,t1 | ||||||
|  |                         sumc    y,t2 | ||||||
|  | cordic_a                sumnc   a,cordic_delta          '(source incremented for each step) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ' ┌────────────────┐ | ||||||
|  | ' │  Defined Data  │ | ||||||
|  | ' └────────────────┘ | ||||||
|  |  | ||||||
|  | tune                    long    $66920000               'scale tuned to 110.00Hz at gp=100 (manually calibrated) | ||||||
|  |  | ||||||
|  | lfsr                    long    1                       'linear feedback shift register for noise generation | ||||||
|  | lfsr_taps               long    $80061000 | ||||||
|  |  | ||||||
|  | cordic_delta            long    $4B901476               'cordic angle deltas (first is h80000000) | ||||||
|  |                         long    $27ECE16D | ||||||
|  |                         long    $14444750 | ||||||
|  |                         long    $0A2C350C | ||||||
|  |                         long    $05175F85 | ||||||
|  |                         long    $028BD879                                        | ||||||
|  |                         long    $0145F154 | ||||||
|  |                         long    $00A2F94D | ||||||
|  |                         long    $00517CBB | ||||||
|  |                         long    $0028BE60 | ||||||
|  |                         long    $00145F30 | ||||||
|  |                         long    $000A2F98 | ||||||
|  |  | ||||||
|  | h80000000               long    $80000000               'miscellaneous constants greater than 9 bits | ||||||
|  | h40000000               long    $40000000 | ||||||
|  | h01000000               long    $01000000 | ||||||
|  | h00FFFFFF               long    $00FFFFFF | ||||||
|  | h00010000               long    $00010000         | ||||||
|  | h0000D000               long    $0000D000 | ||||||
|  | h00007000               long    $00007000 | ||||||
|  | h00001000               long    $00001000 | ||||||
|  | h00000FFE               long    $00000FFE | ||||||
|  | h00000800               long    $00000800 | ||||||
|  |  | ||||||
|  | d0                      long    $00000200               'destination/source field increments | ||||||
|  | d0s0                    long    $00000201 | ||||||
|  |  | ||||||
|  | clear_cnt               long    $1F0 - reserves         'number of reserved registers to clear on startup | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ' ┌──────────────────────────────────────────────────┐ | ||||||
|  | ' │  Undefined Data (zeroed by initialization code)  │ | ||||||
|  | ' └──────────────────────────────────────────────────┘ | ||||||
|  |  | ||||||
|  | reserves | ||||||
|  |  | ||||||
|  | frqa_center             res     1                       'reserved registers that get cleared on startup | ||||||
|  |  | ||||||
|  | cnt_ticks               res     1 | ||||||
|  | cnt_value               res     1 | ||||||
|  |  | ||||||
|  | frame_index             res     1 | ||||||
|  | frame_ptr               res     1 | ||||||
|  | frame_cnt               res     1 | ||||||
|  |  | ||||||
|  | step_size               res     1 | ||||||
|  | step_acc                res     1 | ||||||
|  |                                                  | ||||||
|  | vphase                  res     1 | ||||||
|  | gphase                  res     1 | ||||||
|  | fphase                  res     1 | ||||||
|  |  | ||||||
|  | f1x                     res     1 | ||||||
|  | f1y                     res     1 | ||||||
|  | f2x                     res     1 | ||||||
|  | f2y                     res     1 | ||||||
|  | f3x                     res     1 | ||||||
|  | f3y                     res     1 | ||||||
|  | f4x                     res     1 | ||||||
|  | f4y                     res     1 | ||||||
|  | nx                      res     1 | ||||||
|  |  | ||||||
|  | a                       res     1 | ||||||
|  | x                       res     1 | ||||||
|  | y                       res     1 | ||||||
|  |  | ||||||
|  | t1                      res     1 | ||||||
|  | t2                      res     1 | ||||||
|  |  | ||||||
|  | par_curr                                                '*** current parameters | ||||||
|  | aa                      res     1                       'aspiration amplitude | ||||||
|  | ga                      res     1                       'glottal amplitude        | ||||||
|  | gp                      res     1                       'glottal pitch | ||||||
|  | vp                      res     1                       'vibrato pitch            | ||||||
|  | vr                      res     1                       'vibrato rate             | ||||||
|  | f1                      res     1                       'formant1 frequency       | ||||||
|  | f2                      res     1                       'formant2 frequency | ||||||
|  | f3                      res     1                       'formant3 frequency | ||||||
|  | f4                      res     1                       'formant4 frequency | ||||||
|  | na                      res     1                       'nasal amplitude | ||||||
|  | nf                      res     1                       'nasal frequency | ||||||
|  | fa                      res     1                       'frication amplitude | ||||||
|  | ff                      res     1                       'frication frequency | ||||||
|  |  | ||||||
|  | par_next                res     13                      '*** next parameters | ||||||
|  | par_step                res     13                      '*** parameter steps | ||||||
|  |  | ||||||
|  |  | ||||||
|  | mult_steps              res     2 * 15                  'assembly area for multiply steps w/ret | ||||||
|  | mult_ret | ||||||
|  | sine_ret                res     1 | ||||||
|  |  | ||||||
|  | cordic_steps            res     8 * 13 - 1              'assembly area for cordic steps w/ret | ||||||
|  | cordic_ret              res     1 | ||||||
|  |  | ||||||
|  | {{ | ||||||
|  |  | ||||||
|  | ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ | ||||||
|  | │                                                   TERMS OF USE: MIT License                                                  │                                                             | ||||||
|  | ├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ | ||||||
|  | │Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation    │  | ||||||
|  | │files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,    │ | ||||||
|  | │modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ | ||||||
|  | │is furnished to do so, subject to the following conditions:                                                                   │ | ||||||
|  | │                                                                                                                              │ | ||||||
|  | │The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ | ||||||
|  | │                                                                                                                              │ | ||||||
|  | │THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE          │ | ||||||
|  | │WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR         │ | ||||||
|  | │COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,   │ | ||||||
|  | │ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                         │ | ||||||
|  | └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ | ||||||
|  | }} | ||||||
							
								
								
									
										63
									
								
								samples/Python/AdditiveWave.pyde
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								samples/Python/AdditiveWave.pyde
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,63 @@ | |||||||
|  | """ | ||||||
|  | Additive Wave | ||||||
|  | by Daniel Shiffman.  | ||||||
|  |  | ||||||
|  | Create a more complex wave by adding two waves together.  | ||||||
|  | """ | ||||||
|  |  | ||||||
|  | xspacing = 8    # How far apart should each horizontal location be spaced | ||||||
|  | maxwaves = 4    # total # of waves to add together | ||||||
|  | theta = 0.0 | ||||||
|  |  | ||||||
|  | amplitude = []  # Height of wave | ||||||
|  | # Value for incrementing X, to be calculated as a function of period and | ||||||
|  | # xspacing | ||||||
|  | dx = [] | ||||||
|  | yvalues = [] | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def setup(): | ||||||
|  |     size(640, 360) | ||||||
|  |     frameRate(30) | ||||||
|  |     colorMode(RGB, 255, 255, 255, 100) | ||||||
|  |     w = width + 16 | ||||||
|  |     for i in range(maxwaves): | ||||||
|  |         amplitude.append(random(10, 30)) | ||||||
|  |         period = random(100, 300)  # How many pixels before the wave repeats | ||||||
|  |         dx.append((TWO_PI / period) * xspacing) | ||||||
|  |     for _ in range(w / xspacing + 1): | ||||||
|  |         yvalues.append(0.0) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def draw(): | ||||||
|  |     background(0) | ||||||
|  |     calcWave() | ||||||
|  |     renderWave() | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def calcWave(): | ||||||
|  |     # Increment theta (try different values for 'angular velocity' here | ||||||
|  |     theta += 0.02 | ||||||
|  |     # Set all height values to zero | ||||||
|  |     for i in range(len(yvalues)): | ||||||
|  |         yvalues[i] = 0 | ||||||
|  |     # Accumulate wave height values | ||||||
|  |     for j in range(maxwaves): | ||||||
|  |         x = theta | ||||||
|  |         for i in range(len(yvalues)): | ||||||
|  |             # Every other wave is cosine instead of sine | ||||||
|  |             if j % 2 == 0: | ||||||
|  |                 yvalues[i] += sin(x) * amplitude[j] | ||||||
|  |             else: | ||||||
|  |                 yvalues[i] += cos(x) * amplitude[j] | ||||||
|  |             x += dx[j] | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def renderWave(): | ||||||
|  |     # A simple way to draw the wave with an ellipse at each location | ||||||
|  |     noStroke() | ||||||
|  |     fill(255, 50) | ||||||
|  |     ellipseMode(CENTER) | ||||||
|  |     for x, v in enumerate(yvalues): | ||||||
|  |         ellipse(x * xspacing, height / 2 + v, 16, 16) | ||||||
|  |  | ||||||
							
								
								
									
										241
									
								
								samples/Python/Cinema4DPythonPlugin.pyp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										241
									
								
								samples/Python/Cinema4DPythonPlugin.pyp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,241 @@ | |||||||
|  | # | ||||||
|  | # Cinema 4D Python Plugin Source file | ||||||
|  | # https://github.com/nr-plugins/nr-xpresso-alignment-tools | ||||||
|  | # | ||||||
|  |  | ||||||
|  | # coding: utf-8 | ||||||
|  | # | ||||||
|  | # Copyright (C) 2012, Niklas Rosenstein | ||||||
|  | # Licensed under the GNU General Public License | ||||||
|  | # | ||||||
|  | # XPAT - XPresso Alignment Tools | ||||||
|  | # ============================== | ||||||
|  | # | ||||||
|  | # The XPAT plugin provides tools for aligning nodes in the Cinema 4D | ||||||
|  | # XPresso Editor, improving readability of complex XPresso set-ups | ||||||
|  | # immensively. | ||||||
|  | # | ||||||
|  | # Requirements: | ||||||
|  | # - MAXON Cinema 4D R13+ | ||||||
|  | # - Python `c4dtools` library. Get it from | ||||||
|  | #   http://github.com/NiklasRosenstein/c4dtools | ||||||
|  | # | ||||||
|  | # Author:  Niklas Rosenstein <rosensteinniklas@gmail.com> | ||||||
|  | # Version: 1.1 (01/06/2012) | ||||||
|  |  | ||||||
|  | import os | ||||||
|  | import sys | ||||||
|  | import json | ||||||
|  | import c4d | ||||||
|  | import c4dtools | ||||||
|  | import itertools | ||||||
|  |  | ||||||
|  | from c4d.modules import graphview as gv | ||||||
|  | from c4dtools.misc import graphnode | ||||||
|  |  | ||||||
|  | res, importer = c4dtools.prepare(__file__, __res__) | ||||||
|  | settings = c4dtools.helpers.Attributor({ | ||||||
|  |     'options_filename': res.file('config.json'), | ||||||
|  | }) | ||||||
|  |  | ||||||
|  | def align_nodes(nodes, mode, spacing): | ||||||
|  |     r""" | ||||||
|  |     Aligns the passed nodes horizontally and apply the minimum spacing | ||||||
|  |     between them. | ||||||
|  |     """ | ||||||
|  |  | ||||||
|  |     modes = ['horizontal', 'vertical'] | ||||||
|  |     if not nodes: | ||||||
|  |         return | ||||||
|  |     if mode not in modes: | ||||||
|  |         raise ValueError('invalid mode, choices are: ' + ', '.join(modes)) | ||||||
|  |  | ||||||
|  |     get_0 = lambda x: x.x | ||||||
|  |     get_1 = lambda x: x.y | ||||||
|  |     set_0 = lambda x, v: setattr(x, 'x', v) | ||||||
|  |     set_1 = lambda x, v: setattr(x, 'y', v) | ||||||
|  |  | ||||||
|  |     if mode == 'vertical': | ||||||
|  |         get_0, get_1 = get_1, get_0 | ||||||
|  |         set_0, set_1 = set_1, set_0 | ||||||
|  |  | ||||||
|  |     nodes = [graphnode.GraphNode(n) for n in nodes] | ||||||
|  |     nodes.sort(key=lambda n: get_0(n.position)) | ||||||
|  |     midpoint = graphnode.find_nodes_mid(nodes) | ||||||
|  |  | ||||||
|  |     # Apply the spacing between the nodes relative to the coordinate-systems | ||||||
|  |     # origin. We can offset them later because we now the nodes' midpoint | ||||||
|  |     # already. | ||||||
|  |     first_position = nodes[0].position | ||||||
|  |     new_positions = [] | ||||||
|  |     prev_offset = 0 | ||||||
|  |     for node in nodes: | ||||||
|  |         # Compute the relative position of the node. | ||||||
|  |         position = node.position | ||||||
|  |         set_0(position, get_0(position) - get_0(first_position)) | ||||||
|  |  | ||||||
|  |         # Obtain it's size and check if the node needs to be re-placed. | ||||||
|  |         size = node.size | ||||||
|  |         if get_0(position) < prev_offset: | ||||||
|  |             set_0(position, prev_offset) | ||||||
|  |             prev_offset += spacing + get_0(size) | ||||||
|  |         else: | ||||||
|  |             prev_offset = get_0(position) + get_0(size) + spacing | ||||||
|  |  | ||||||
|  |         set_1(position, get_1(midpoint)) | ||||||
|  |         new_positions.append(position) | ||||||
|  |  | ||||||
|  |     # Center the nodes again. | ||||||
|  |     bbox_size = prev_offset - spacing | ||||||
|  |     bbox_size_2 = bbox_size * 0.5 | ||||||
|  |     for node, position in itertools.izip(nodes, new_positions): | ||||||
|  |         # TODO: Here is some issue with offsetting the nodes. Some value | ||||||
|  |         # dependent on the spacing must be added here to not make the nodes | ||||||
|  |         # move horizontally/vertically although they have already been | ||||||
|  |         # aligned. | ||||||
|  |         set_0(position, get_0(midpoint) + get_0(position) - bbox_size_2 + spacing) | ||||||
|  |         node.position = position | ||||||
|  |  | ||||||
|  | def align_nodes_shortcut(mode, spacing): | ||||||
|  |     master = gv.GetMaster(0) | ||||||
|  |     if not master: | ||||||
|  |         return | ||||||
|  |  | ||||||
|  |     root = master.GetRoot() | ||||||
|  |     if not root: | ||||||
|  |         return | ||||||
|  |  | ||||||
|  |     nodes = graphnode.find_selected_nodes(root) | ||||||
|  |     if nodes: | ||||||
|  |         master.AddUndo() | ||||||
|  |         align_nodes(nodes, mode, spacing) | ||||||
|  |         c4d.EventAdd() | ||||||
|  |  | ||||||
|  |     return True | ||||||
|  |  | ||||||
|  | class XPAT_Options(c4dtools.helpers.Attributor): | ||||||
|  |     r""" | ||||||
|  |     This class organizes the options for the XPAT plugin, i.e. | ||||||
|  |     validating, loading and saving. | ||||||
|  |     """ | ||||||
|  |  | ||||||
|  |     defaults = { | ||||||
|  |         'hspace': 50, | ||||||
|  |         'vspace': 20, | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     def __init__(self, filename=None): | ||||||
|  |         super(XPAT_Options, self).__init__() | ||||||
|  |         self.load(filename) | ||||||
|  |  | ||||||
|  |     def load(self, filename=None): | ||||||
|  |         r""" | ||||||
|  |         Load the options from file pointed to by filename. If filename | ||||||
|  |         is None, it defaults to the filename defined in options in the | ||||||
|  |         global scope. | ||||||
|  |         """ | ||||||
|  |  | ||||||
|  |         if filename is None: | ||||||
|  |             filename = settings.options_filename | ||||||
|  |  | ||||||
|  |         if os.path.isfile(filename): | ||||||
|  |             self.dict_ = self.defaults.copy() | ||||||
|  |             with open(filename, 'rb') as fp: | ||||||
|  |                 self.dict_.update(json.load(fp)) | ||||||
|  |         else: | ||||||
|  |             self.dict_ = self.defaults.copy() | ||||||
|  |             self.save() | ||||||
|  |  | ||||||
|  |     def save(self, filename=None): | ||||||
|  |         r""" | ||||||
|  |         Save the options defined in XPAT_Options instance to HD. | ||||||
|  |         """ | ||||||
|  |  | ||||||
|  |         if filename is None: | ||||||
|  |             filename = settings.options_filename | ||||||
|  |  | ||||||
|  |         values = dict((k, v) for k, v in self.dict_.iteritems() | ||||||
|  |                       if k in self.defaults) | ||||||
|  |         with open(filename, 'wb') as fp: | ||||||
|  |             json.dump(values, fp) | ||||||
|  |  | ||||||
|  | class XPAT_OptionsDialog(c4d.gui.GeDialog): | ||||||
|  |     r""" | ||||||
|  |     This class implements the behavior of the XPAT options dialog, | ||||||
|  |     taking care of storing the options on the HD and loading them | ||||||
|  |     again on startup. | ||||||
|  |     """ | ||||||
|  |  | ||||||
|  |     # c4d.gui.GeDialog | ||||||
|  |  | ||||||
|  |     def CreateLayout(self): | ||||||
|  |         return self.LoadDialogResource(res.DLG_OPTIONS) | ||||||
|  |  | ||||||
|  |     def InitValues(self): | ||||||
|  |         self.SetLong(res.EDT_HSPACE, options.hspace) | ||||||
|  |         self.SetLong(res.EDT_VSPACE, options.vspace) | ||||||
|  |         return True | ||||||
|  |  | ||||||
|  |     def Command(self, id, msg): | ||||||
|  |         if id == res.BTN_SAVE: | ||||||
|  |             options.hspace = self.GetLong(res.EDT_HSPACE) | ||||||
|  |             options.vspace = self.GetLong(res.EDT_VSPACE) | ||||||
|  |             options.save() | ||||||
|  |             self.Close() | ||||||
|  |         return True | ||||||
|  |  | ||||||
|  | class XPAT_Command_OpenOptionsDialog(c4dtools.plugins.Command): | ||||||
|  |     r""" | ||||||
|  |     This Cinema 4D CommandData plugin opens the XPAT options dialog | ||||||
|  |     when being executed. | ||||||
|  |     """ | ||||||
|  |  | ||||||
|  |     def __init__(self): | ||||||
|  |         super(XPAT_Command_OpenOptionsDialog, self).__init__() | ||||||
|  |         self._dialog = None | ||||||
|  |  | ||||||
|  |     @property | ||||||
|  |     def dialog(self): | ||||||
|  |         if not self._dialog: | ||||||
|  |             self._dialog = XPAT_OptionsDialog() | ||||||
|  |         return self._dialog | ||||||
|  |  | ||||||
|  |     # c4dtools.plugins.Command | ||||||
|  |  | ||||||
|  |     PLUGIN_ID = 1029621 | ||||||
|  |     PLUGIN_NAME = res.string.XPAT_COMMAND_OPENOPTIONSDIALOG() | ||||||
|  |     PLUGIN_HELP = res.string.XPAT_COMMAND_OPENOPTIONSDIALOG_HELP() | ||||||
|  |  | ||||||
|  |     # c4d.gui.CommandData | ||||||
|  |  | ||||||
|  |     def Execute(self, doc): | ||||||
|  |         return self.dialog.Open(c4d.DLG_TYPE_MODAL) | ||||||
|  |  | ||||||
|  | class XPAT_Command_AlignHorizontal(c4dtools.plugins.Command): | ||||||
|  |  | ||||||
|  |     PLUGIN_ID = 1029538 | ||||||
|  |     PLUGIN_NAME = res.string.XPAT_COMMAND_ALIGNHORIZONTAL() | ||||||
|  |     PLUGIN_ICON = res.file('xpresso-align-h.png') | ||||||
|  |     PLUGIN_HELP = res.string.XPAT_COMMAND_ALIGNHORIZONTAL_HELP() | ||||||
|  |  | ||||||
|  |     def Execute(self, doc): | ||||||
|  |         align_nodes_shortcut('horizontal', options.hspace) | ||||||
|  |         return True | ||||||
|  |  | ||||||
|  | class XPAT_Command_AlignVertical(c4dtools.plugins.Command): | ||||||
|  |  | ||||||
|  |     PLUGIN_ID = 1029539 | ||||||
|  |     PLUGIN_NAME = res.string.XPAT_COMMAND_ALIGNVERTICAL() | ||||||
|  |     PLUGIN_ICON = res.file('xpresso-align-v.png') | ||||||
|  |     PLUGIN_HELP = res.string.XPAT_COMMAND_ALIGNVERTICAL_HELP() | ||||||
|  |  | ||||||
|  |     def Execute(self, doc): | ||||||
|  |         align_nodes_shortcut('vertical', options.vspace) | ||||||
|  |         return True | ||||||
|  |  | ||||||
|  | options = XPAT_Options() | ||||||
|  |  | ||||||
|  | if __name__ == '__main__': | ||||||
|  |     c4dtools.plugins.main() | ||||||
|  |  | ||||||
|  |  | ||||||
							
								
								
									
										29
									
								
								samples/Python/MoveEye.pyde
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								samples/Python/MoveEye.pyde
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | |||||||
|  | """ | ||||||
|  |  * Move Eye.  | ||||||
|  |  * by Simon Greenwold. | ||||||
|  |  *  | ||||||
|  |  * The camera lifts up (controlled by mouseY) while looking at the same point. | ||||||
|  |  """ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def setup(): | ||||||
|  |     size(640, 360, P3D) | ||||||
|  |     fill(204) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def draw(): | ||||||
|  |     lights() | ||||||
|  |     background(0) | ||||||
|  |  | ||||||
|  |     # Change height of the camera with mouseY | ||||||
|  |     camera(30.0, mouseY, 220.0,  # eyeX, eyeY, eyeZ | ||||||
|  |            0.0, 0.0, 0.0,        # centerX, centerY, centerZ | ||||||
|  |            0.0, 1.0, 0.0)        # upX, upY, upZ | ||||||
|  |  | ||||||
|  |     noStroke() | ||||||
|  |     box(90) | ||||||
|  |     stroke(255) | ||||||
|  |     line(-100, 0, 0, 100, 0, 0) | ||||||
|  |     line(0, -100, 0, 0, 100, 0) | ||||||
|  |     line(0, 0, -100, 0, 0, 100) | ||||||
|  |  | ||||||
							
								
								
									
										30
									
								
								samples/QMake/complex.pro
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								samples/QMake/complex.pro
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | |||||||
|  | # This QMake file is complex, as it usese | ||||||
|  | # boolean operators and function calls | ||||||
|  |  | ||||||
|  | QT += core gui | ||||||
|  | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets | ||||||
|  |  | ||||||
|  | # We could use some OpenGL right now | ||||||
|  | contains(QT_CONFIG, opengl) | contains(QT_CONFIG, opengles2) { | ||||||
|  |    QT += opengl | ||||||
|  | } else { | ||||||
|  |    DEFINES += QT_NO_OPENGL | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEMPLATE = app | ||||||
|  | win32 { | ||||||
|  |     TARGET = BlahApp | ||||||
|  |     RC_FILE = Resources/winres.rc | ||||||
|  | } | ||||||
|  | !win32 { TARGET = blahapp } | ||||||
|  |  | ||||||
|  | # Let's add a PRI file! | ||||||
|  | include(functions.pri) | ||||||
|  |  | ||||||
|  | SOURCES += file.cpp | ||||||
|  |  | ||||||
|  | HEADERS  += file.h | ||||||
|  |  | ||||||
|  | FORMS    += file.ui | ||||||
|  |  | ||||||
|  | RESOURCES += res.qrc | ||||||
							
								
								
									
										8
									
								
								samples/QMake/functions.pri
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								samples/QMake/functions.pri
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  | # QMake include file that calls some functions | ||||||
|  | # and does nothing else... | ||||||
|  |  | ||||||
|  | exists(.git/HEAD) { | ||||||
|  |     system(git rev-parse HEAD >rev.txt) | ||||||
|  | } else { | ||||||
|  |     system(echo ThisIsNotAGitRepo >rev.txt) | ||||||
|  | } | ||||||
							
								
								
									
										2
									
								
								samples/QMake/qmake.script!
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								samples/QMake/qmake.script!
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | #!/usr/bin/qmake | ||||||
|  | message(This is QMake.) | ||||||
							
								
								
									
										17
									
								
								samples/QMake/simple.pro
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								samples/QMake/simple.pro
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | |||||||
|  | # Simple QMake file | ||||||
|  |  | ||||||
|  | CONFIG += qt | ||||||
|  | QT += core gui | ||||||
|  | TEMPLATE = app | ||||||
|  | TARGET = simpleapp | ||||||
|  |  | ||||||
|  | SOURCES += file.cpp \ | ||||||
|  |     file2.c \ | ||||||
|  |     This/Is/Folder/file3.cpp | ||||||
|  |  | ||||||
|  | HEADERS += file.h \ | ||||||
|  |     file2.h \ | ||||||
|  |     This/Is/Folder/file3.h | ||||||
|  |  | ||||||
|  | FORMS += This/Is/Folder/file3.ui \ | ||||||
|  |     Test.ui | ||||||
							
								
								
									
										101
									
								
								samples/R/filenames/expr-dist
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										101
									
								
								samples/R/filenames/expr-dist
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,101 @@ | |||||||
|  | #!/usr/bin/env Rscript | ||||||
|  |  | ||||||
|  | # Copyright (c) 2013 Daniel S. Standage, released under MIT license | ||||||
|  | # | ||||||
|  | # expr-dist: plot distributions of expression values before and after | ||||||
|  | #            normalization; visually confirm that normalization worked | ||||||
|  | #            as expected | ||||||
|  | # | ||||||
|  | # Program input is a matrix of expression values, each row corresponding to a | ||||||
|  | # molecule (gene, transcript, etc) and each row corresponding to that molecule's | ||||||
|  | # expression level or abundance. The program expects the rows and columns to be | ||||||
|  | # named, and was tested primarily on output produced by the | ||||||
|  | # 'rsem-generate-data-matrix' script distributed with the RSEM package. | ||||||
|  | # | ||||||
|  | # The program plots the distributions of the logged expression values by sample | ||||||
|  | # as provided, then normalizes the values, and finally plots the distribution of | ||||||
|  | # the logged normalized expression values by sample. The expectation is that all | ||||||
|  | # samples' distributions will have a similar shape but different medians prior | ||||||
|  | # to normalization, and that post normalization they will all have an identical | ||||||
|  | # median to facilitate cross-sample comparison. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | # MedianNorm function borrowed from the EBSeq library version 1.1.6 | ||||||
|  | # See http://www.bioconductor.org/packages/devel/bioc/html/EBSeq.html | ||||||
|  | MedianNorm <- function(data) | ||||||
|  | { | ||||||
|  |   geomeans <- exp( rowMeans(log(data)) ) | ||||||
|  |   apply(data, 2, function(cnts) median((cnts/geomeans)[geomeans > 0])) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | library("getopt") | ||||||
|  | print_usage <- function(file=stderr()) | ||||||
|  | { | ||||||
|  |   cat(" | ||||||
|  | expr-dist: see source code for full description | ||||||
|  | Usage: expr-dist [options] < expr-matrix.txt | ||||||
|  |   Options: | ||||||
|  |     -h|--help:          print this help message and exit | ||||||
|  |     -o|--out: STRING    prefix for output files; default is 'expr-dist' | ||||||
|  |     -r|--res: INT       resolution (dpi) of generated graphics; default is 150 | ||||||
|  |     -t|--height: INT    height (pixels) of generated graphics; default is 1200 | ||||||
|  |     -w|--width: INT     width (pixels) of generated graphics; default is 1200 | ||||||
|  |     -y|--ylim: REAL     the visible range of the Y axis depends on the first | ||||||
|  |                         distribution plotted; if other distributions are getting | ||||||
|  |                         cut off, use this setting to override the default\n\n") | ||||||
|  | } | ||||||
|  |  | ||||||
|  | spec <- matrix( c("help",   'h', 0, "logical", | ||||||
|  |                   "out",    'o', 1, "character", | ||||||
|  |                   "res",    'r', 1, "integer", | ||||||
|  |                   "height", 't', 1, "integer", | ||||||
|  |                   "width",  'w', 1, "integer", | ||||||
|  |                   "ylim",   'y', 1, "double"), | ||||||
|  |                 byrow=TRUE, ncol=4) | ||||||
|  | opt  <- getopt(spec) | ||||||
|  | if(!is.null(opt$help)) | ||||||
|  | { | ||||||
|  |   print_usage(file=stdout()) | ||||||
|  |   q(status=1) | ||||||
|  | } | ||||||
|  | if(is.null(opt$height)) { opt$height <- 1200           } | ||||||
|  | if(is.null(opt$out))    { opt$out    <- "expr-dist"    } | ||||||
|  | if(is.null(opt$res))    { opt$res    <- 150            } | ||||||
|  | if(is.null(opt$width))  { opt$width  <- 1200           } | ||||||
|  | if(!is.null(opt$ylim))  { opt$ylim   <- c(0, opt$ylim) } | ||||||
|  |  | ||||||
|  | # Load data, determine number of samples | ||||||
|  | data  <- read.table(file("stdin"), header=TRUE, sep="\t", quote="") | ||||||
|  | nsamp <- dim(data)[2] - 1 | ||||||
|  | data  <- data[,1:nsamp+1] | ||||||
|  |  | ||||||
|  | # Plot distribution of expression values before normalization | ||||||
|  | outfile <- sprintf("%s-median.png", opt$out) | ||||||
|  | png(outfile, height=opt$height, width=opt$width, res=opt$res) | ||||||
|  | h <- hist(log(data[,1]), plot=FALSE) | ||||||
|  | plot(h$mids, h$density, type="l", col=rainbow(nsamp)[1], main="", | ||||||
|  |      xlab="Log expression value", ylab="Proportion of molecules", ylim=opt$ylim) | ||||||
|  | for(i in 2:nsamp) | ||||||
|  | { | ||||||
|  |   h <- hist(log(data[,i]), plot=FALSE) | ||||||
|  |   lines(h$mids, h$density, col=rainbow(nsamp)[i]) | ||||||
|  | } | ||||||
|  | devnum <- dev.off() | ||||||
|  |  | ||||||
|  | # Normalize by median | ||||||
|  | size.factors <- MedianNorm(data.matrix(data)) | ||||||
|  | data.norm <- t(apply(data, 1, function(x){ x / size.factors })) | ||||||
|  |  | ||||||
|  | # Plot distribution of normalized expression values | ||||||
|  | outfile <- sprintf("%s-median-norm.png", opt$out) | ||||||
|  | png(outfile, height=opt$height, width=opt$width, res=opt$res) | ||||||
|  | h <- hist(log(data.norm[,1]), plot=FALSE) | ||||||
|  | plot(h$mids, h$density, type="l", col=rainbow(nsamp)[1], main="", | ||||||
|  |      xlab="Log normalized expression value", ylab="Proportion of molecules", | ||||||
|  |      ylim=opt$ylim) | ||||||
|  | for(i in 2:nsamp) | ||||||
|  | { | ||||||
|  |   h <- hist(log(data.norm[,i]), plot=FALSE) | ||||||
|  |   lines(h$mids, h$density, col=rainbow(nsamp)[i]) | ||||||
|  | } | ||||||
|  | devnum <- dev.off() | ||||||
							
								
								
									
										201
									
								
								samples/R/import.r
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										201
									
								
								samples/R/import.r
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,201 @@ | |||||||
|  | #' Import a module into the current scope | ||||||
|  | #' | ||||||
|  | #' \code{module = import('module')} imports a specified module and makes its | ||||||
|  | #' code available via the environment-like object it returns. | ||||||
|  | #' | ||||||
|  | #' @param module an identifier specifying the full module path | ||||||
|  | #' @param attach if \code{TRUE}, attach the newly loaded module to the object | ||||||
|  | #'      search path (see \code{Details}) | ||||||
|  | #' @param attach_operators if \code{TRUE}, attach operators of module to the | ||||||
|  | #'      object search path, even if \code{attach} is \code{FALSE} | ||||||
|  | #' @return the loaded module environment (invisible) | ||||||
|  | #' | ||||||
|  | #' @details Modules are loaded in an isolated environment which is returned, and | ||||||
|  | #' optionally attached to the object search path of the current scope (if | ||||||
|  | #' argument \code{attach} is \code{TRUE}). | ||||||
|  | #' \code{attach} defaults to \code{FALSE}. However, in interactive code it is | ||||||
|  | #' often helpful to attach packages by default. Therefore, in interactive code | ||||||
|  | #' invoked directly from the terminal only (i.e. not within modules), | ||||||
|  | #' \code{attach} defaults to the value of \code{options('import.attach')}, which | ||||||
|  | #' can be set to \code{TRUE} or \code{FALSE} depending on the user’s preference. | ||||||
|  | #' | ||||||
|  | #' \code{attach_operators} causes \emph{operators} to be attached by default, | ||||||
|  | #' because operators can only be invoked in R if they re found in the search | ||||||
|  | #' path. Not attaching them therefore drastically limits a module’s usefulness. | ||||||
|  | #' | ||||||
|  | #' Modules are searched in the module search path \code{options('import.path')}. | ||||||
|  | #' This is a vector of paths to consider, from the highest to the lowest | ||||||
|  | #' priority. The current directory is \emph{always} considered first. That is, | ||||||
|  | #' if a file \code{a.r} exists both in the current directory and in a module | ||||||
|  | #' search path, the local file \code{./a.r} will be loaded. | ||||||
|  | #' | ||||||
|  | #' Module names can be fully qualified to refer to nested paths. See | ||||||
|  | #' \code{Examples}. | ||||||
|  | #' | ||||||
|  | #' @note Unlike for packages, attaching happens \emph{locally}: if | ||||||
|  | #' \code{import} is executed in the global environment, the effect is the same. | ||||||
|  | #' Otherwise, the imported module is inserted as the parent of the current | ||||||
|  | #' \code{environment()}. When used (globally) \emph{inside} a module, the newly | ||||||
|  | #' imported module is only available inside the module’s search path, not | ||||||
|  | #' outside it (nor in other modules which might be loaded). | ||||||
|  | #' | ||||||
|  | #' @examples | ||||||
|  | #' # `a.r` is a file in the local directory containing a function `f`. | ||||||
|  | #' a = import('a') | ||||||
|  | #' a$f() | ||||||
|  | #' | ||||||
|  | #' # b/c.r is a file in path `b`, containing a function `g`. | ||||||
|  | #' import('b/c', attach = TRUE) | ||||||
|  | #' g() # No module name qualification necessary | ||||||
|  | #' | ||||||
|  | #' @seealso \code{unload} | ||||||
|  | #' @seealso \code{reload} | ||||||
|  | #' @seealso \code{module_name} | ||||||
|  | #' @export | ||||||
|  | import = function (module, attach, attach_operators = TRUE) { | ||||||
|  |     module = substitute(module) | ||||||
|  |     stopifnot(inherits(module, 'name')) | ||||||
|  |  | ||||||
|  |     if (missing(attach)) { | ||||||
|  |         attach = if (interactive() && is.null(module_name())) | ||||||
|  |             getOption('import.attach', FALSE) | ||||||
|  |         else | ||||||
|  |             FALSE | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     stopifnot(class(attach) == 'logical' && length(attach) == 1) | ||||||
|  |  | ||||||
|  |     module_path = try(find_module(module), silent = TRUE) | ||||||
|  |  | ||||||
|  |     if (inherits(module_path, 'try-error')) | ||||||
|  |         stop(attr(module_path, 'condition')$message) | ||||||
|  |  | ||||||
|  |     containing_modules = module_init_files(module, module_path) | ||||||
|  |     mapply(do_import, names(containing_modules), containing_modules) | ||||||
|  |  | ||||||
|  |     mod_ns = do_import(as.character(module), module_path) | ||||||
|  |     module_parent = parent.frame() | ||||||
|  |     mod_env = exhibit_namespace(mod_ns, as.character(module), module_parent) | ||||||
|  |  | ||||||
|  |     if (attach) { | ||||||
|  |         if (identical(module_parent, .GlobalEnv)) | ||||||
|  |             attach(mod_env, name = environmentName(mod_env)) | ||||||
|  |         else | ||||||
|  |             parent.env(module_parent) = mod_env | ||||||
|  |     } | ||||||
|  |     else if (attach_operators) | ||||||
|  |         export_operators(mod_ns, module_parent) | ||||||
|  |  | ||||||
|  |     invisible(mod_env) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | do_import = function (module_name, module_path) { | ||||||
|  |     if (is_module_loaded(module_path)) | ||||||
|  |         return(get_loaded_module(module_path)) | ||||||
|  |  | ||||||
|  |     # The namespace contains a module’s content. This schema is very much like | ||||||
|  |     # R package organisation. | ||||||
|  |     # A good resource for this is: | ||||||
|  |     # <http://obeautifulcode.com/R/How-R-Searches-And-Finds-Stuff/> | ||||||
|  |     namespace = structure(new.env(parent = .BaseNamespaceEnv), | ||||||
|  |                           name = paste('namespace', module_name, sep = ':'), | ||||||
|  |                           path = module_path, | ||||||
|  |                           class = c('namespace', 'environment')) | ||||||
|  |     local(source(attr(environment(), 'path'), chdir = TRUE, local = TRUE), | ||||||
|  |           envir = namespace) | ||||||
|  |     cache_module(namespace) | ||||||
|  |     namespace | ||||||
|  | } | ||||||
|  |  | ||||||
|  | exhibit_namespace = function (namespace, name, parent) { | ||||||
|  |     exported_functions = lsf.str(namespace) | ||||||
|  |     # Skip one parent environment because this module is hooked into the chain | ||||||
|  |     # between the calling environment and its ancestor, thus sitting in its | ||||||
|  |     # local object search path. | ||||||
|  |     structure(list2env(sapply(exported_functions, get, envir = namespace), | ||||||
|  |                        parent = parent.env(parent)), | ||||||
|  |               name = paste('module', name, sep = ':'), | ||||||
|  |               path = module_path(namespace), | ||||||
|  |               class = c('module', 'environment')) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export_operators = function (namespace, parent) { | ||||||
|  |     # `$` cannot be overwritten, but it is generic so S3 variants of it can be | ||||||
|  |     # defined. We therefore test it as well. | ||||||
|  |     ops = c('+', '-', '*', '/', '^', '**', '&', '|', ':', '::', ':::', '$', '=', | ||||||
|  |             '<-', '<<-', '==', '<', '<=', '>', '>=', '!=', '~', '&&', '||') | ||||||
|  |  | ||||||
|  |     is_predefined = function (f) f %in% ops | ||||||
|  |  | ||||||
|  |     is_op = function (f) { | ||||||
|  |         prefix = strsplit(f, '\\.')[[1]][1] | ||||||
|  |         is_predefined(prefix) || grepl('^%.*%$', prefix) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     operators = Filter(is_op, lsf.str(namespace)) | ||||||
|  |     name = module_name(namespace) | ||||||
|  |     # Skip one parent environment because this module is hooked into the chain | ||||||
|  |     # between the calling environment and its ancestor, thus sitting in its | ||||||
|  |     # local object search path. | ||||||
|  |     op_env = structure(list2env(sapply(operators, get, envir = namespace), | ||||||
|  |                                 parent = parent.env(parent)), | ||||||
|  |                        name = paste('operators', name, sep = ':'), | ||||||
|  |                        path = module_path(namespace), | ||||||
|  |                        class = c('module', 'environment')) | ||||||
|  |  | ||||||
|  |     if (identical(parent, .GlobalEnv)) | ||||||
|  |         attach(op_env, name = environmentName(op_env)) | ||||||
|  |     else | ||||||
|  |         parent.env(parent) = op_env | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #' Unload a given module | ||||||
|  | #' | ||||||
|  | #' Unset the module variable that is being passed as a parameter, and remove the | ||||||
|  | #' loaded module from cache. | ||||||
|  | #' @param module reference to the module which should be unloaded | ||||||
|  | #' @note Any other references to the loaded modules remain unchanged, and will | ||||||
|  | #' still work. However, subsequently importing the module again will reload its | ||||||
|  | #' source files, which would not have happened without \code{unload}. | ||||||
|  | #' Unloading modules is primarily useful for testing during development, and | ||||||
|  | #' should not be used in production code. | ||||||
|  | #' | ||||||
|  | #' \code{unload} does not currently detach environments. | ||||||
|  | #' @seealso \code{import} | ||||||
|  | #' @seealso \code{reload} | ||||||
|  | #' @export | ||||||
|  | unload = function (module) { | ||||||
|  |     stopifnot(inherits(module, 'module')) | ||||||
|  |     module_ref = as.character(substitute(module)) | ||||||
|  |     rm(list = module_path(module), envir = .loaded_modules) | ||||||
|  |     # unset the module reference in its scope, i.e. the caller’s environment or | ||||||
|  |     # some parent thereof. | ||||||
|  |     rm(list = module_ref, envir = parent.frame(), inherits = TRUE) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #' Reload a given module | ||||||
|  | #' | ||||||
|  | #' Remove the loaded module from the cache, forcing a reload. The newly reloaded | ||||||
|  | #' module is assigned to the module reference in the calling scope. | ||||||
|  | #' @param module reference to the module which should be unloaded | ||||||
|  | #' @note Any other references to the loaded modules remain unchanged, and will | ||||||
|  | #' still work. Reloading modules is primarily useful for testing during | ||||||
|  | #' development, and should not be used in production code. | ||||||
|  | #' | ||||||
|  | #' \code{reload} does not work correctly with attached environments. | ||||||
|  | #' @seealso \code{import} | ||||||
|  | #' @seealso \code{unload} | ||||||
|  | #' @export | ||||||
|  | reload = function (module) { | ||||||
|  |     stopifnot(inherits(module, 'module')) | ||||||
|  |     module_ref = as.character(substitute(module)) | ||||||
|  |     module_path = module_path(module) | ||||||
|  |     module_name = module_name(module) | ||||||
|  |     rm(list = module_path, envir = .loaded_modules) | ||||||
|  |     #' @TODO Once we have `attach`, need also to take care of the search path | ||||||
|  |     #' and whatnot. | ||||||
|  |     mod_ns = do_import(module_name, module_path) | ||||||
|  |     module_parent = parent.frame() | ||||||
|  |     mod_env = exhibit_namespace(mod_ns, module_ref, module_parent) | ||||||
|  |     assign(module_ref, mod_env, envir = module_parent, inherits = TRUE) | ||||||
|  | } | ||||||
							
								
								
									
										25
									
								
								samples/R/scholar.Rd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								samples/R/scholar.Rd
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | |||||||
|  | \docType{package} | ||||||
|  | \name{scholar} | ||||||
|  | \alias{scholar} | ||||||
|  | \alias{scholar-package} | ||||||
|  | \title{scholar} | ||||||
|  | \source{ | ||||||
|  |   The package reads data from | ||||||
|  |   \url{http://scholar.google.com}.  Dates and citation | ||||||
|  |   counts are estimated and are determined automatically by | ||||||
|  |   a computer program. Use at your own risk. | ||||||
|  | } | ||||||
|  | \description{ | ||||||
|  |   The \code{scholar} package provides functions to extract | ||||||
|  |   citation data from Google Scholar.  There are also | ||||||
|  |   convenience functions for comparing multiple scholars and | ||||||
|  |   predicting h-index scores based on past publication | ||||||
|  |   records. | ||||||
|  | } | ||||||
|  | \note{ | ||||||
|  |   A complementary set of Google Scholar functions can be | ||||||
|  |   found at | ||||||
|  |   \url{http://biostat.jhsph.edu/~jleek/code/googleCite.r}. | ||||||
|  |   The \code{scholar} package was developed independently. | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										257
									
								
								samples/Red/example.red
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										257
									
								
								samples/Red/example.red
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,257 @@ | |||||||
|  | Red [ | ||||||
|  |     Title:  "Red console" | ||||||
|  |     Author: ["Nenad Rakocevic" "Kaj de Vos"] | ||||||
|  |     File:   %console.red | ||||||
|  |     Tabs:   4 | ||||||
|  |     Rights: "Copyright (C) 2012-2013 Nenad Rakocevic. All rights reserved." | ||||||
|  |     License: { | ||||||
|  |         Distributed under the Boost Software License, Version 1.0. | ||||||
|  |         See https://github.com/dockimbel/Red/blob/master/BSL-License.txt | ||||||
|  |     } | ||||||
|  |     Purpose:    "Just some code for testing Pygments colorizer" | ||||||
|  |     Language:   http://www.red-lang.org/ | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | #system-global [ | ||||||
|  |     #either OS = 'Windows [ | ||||||
|  |         #import [ | ||||||
|  |             "kernel32.dll" stdcall [ | ||||||
|  |                 AttachConsole:   "AttachConsole" [ | ||||||
|  |                     processID       [integer!] | ||||||
|  |                     return:         [integer!] | ||||||
|  |                 ] | ||||||
|  |                 SetConsoleTitle: "SetConsoleTitleA" [ | ||||||
|  |                     title           [c-string!] | ||||||
|  |                     return:         [integer!] | ||||||
|  |                 ] | ||||||
|  |                 ReadConsole:     "ReadConsoleA" [ | ||||||
|  |                     consoleInput    [integer!] | ||||||
|  |                     buffer          [byte-ptr!] | ||||||
|  |                     charsToRead     [integer!] | ||||||
|  |                     numberOfChars   [int-ptr!] | ||||||
|  |                     inputControl    [int-ptr!] | ||||||
|  |                     return:         [integer!] | ||||||
|  |                 ] | ||||||
|  |             ] | ||||||
|  |         ] | ||||||
|  |         line-buffer-size: 16 * 1024 | ||||||
|  |         line-buffer: allocate line-buffer-size | ||||||
|  |     ][ | ||||||
|  |         #switch OS [ | ||||||
|  |             MacOSX [ | ||||||
|  |                 #define ReadLine-library "libreadline.dylib" | ||||||
|  |             ] | ||||||
|  |             #default [ | ||||||
|  |                 #define ReadLine-library "libreadline.so.6" | ||||||
|  |                 #define History-library  "libhistory.so.6" | ||||||
|  |             ] | ||||||
|  |         ] | ||||||
|  |         #import [ | ||||||
|  |             ReadLine-library cdecl [ | ||||||
|  |                 read-line: "readline" [  ; Read a line from the console. | ||||||
|  |                     prompt          [c-string!] | ||||||
|  |                     return:         [c-string!] | ||||||
|  |                 ] | ||||||
|  |                 rl-bind-key: "rl_bind_key" [ | ||||||
|  |                     key             [integer!] | ||||||
|  |                     command         [integer!] | ||||||
|  |                     return:         [integer!] | ||||||
|  |                 ] | ||||||
|  |                 rl-insert:   "rl_insert" [ | ||||||
|  |                     count           [integer!] | ||||||
|  |                     key             [integer!] | ||||||
|  |                     return:         [integer!] | ||||||
|  |                 ] | ||||||
|  |             ] | ||||||
|  |             #if OS <> 'MacOSX [ | ||||||
|  |                 History-library cdecl [ | ||||||
|  |                     add-history: "add_history" [  ; Add line to the history. | ||||||
|  |                         line        [c-string!] | ||||||
|  |                     ] | ||||||
|  |                 ] | ||||||
|  |             ] | ||||||
|  |         ] | ||||||
|  |  | ||||||
|  |         rl-insert-wrapper: func [ | ||||||
|  |             [cdecl] | ||||||
|  |             count   [integer!] | ||||||
|  |             key     [integer!] | ||||||
|  |             return: [integer!] | ||||||
|  |         ][ | ||||||
|  |             rl-insert count key | ||||||
|  |         ] | ||||||
|  |          | ||||||
|  |     ] | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | Windows?: system/platform = 'Windows | ||||||
|  |  | ||||||
|  | read-argument: routine [ | ||||||
|  |     /local | ||||||
|  |         args [str-array!] | ||||||
|  |         str  [red-string!] | ||||||
|  | ][ | ||||||
|  |     if system/args-count <> 2 [ | ||||||
|  |         SET_RETURN(none-value) | ||||||
|  |         exit | ||||||
|  |     ] | ||||||
|  |     args: system/args-list + 1                          ;-- skip binary filename | ||||||
|  |     str: simple-io/read-txt args/item | ||||||
|  |     SET_RETURN(str) | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | init-console: routine [ | ||||||
|  |     str [string!] | ||||||
|  |     /local | ||||||
|  |         ret | ||||||
|  | ][ | ||||||
|  |     #either OS = 'Windows [ | ||||||
|  |         ;ret: AttachConsole -1 | ||||||
|  |         ;if zero? ret [print-line "ReadConsole failed!" halt] | ||||||
|  |          | ||||||
|  |         ret: SetConsoleTitle as c-string! string/rs-head str | ||||||
|  |         if zero? ret [print-line "SetConsoleTitle failed!" halt] | ||||||
|  |     ][ | ||||||
|  |         rl-bind-key as-integer tab as-integer :rl-insert-wrapper | ||||||
|  |     ] | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | input: routine [ | ||||||
|  |     prompt [string!] | ||||||
|  |     /local | ||||||
|  |         len ret str buffer line | ||||||
|  | ][ | ||||||
|  |     #either OS = 'Windows [ | ||||||
|  |         len: 0 | ||||||
|  |         print as c-string! string/rs-head prompt | ||||||
|  |         ret: ReadConsole stdin line-buffer line-buffer-size :len null | ||||||
|  |         if zero? ret [print-line "ReadConsole failed!" halt] | ||||||
|  |         len: len + 1 | ||||||
|  |         line-buffer/len: null-byte | ||||||
|  |         str: string/load as c-string! line-buffer len | ||||||
|  |     ][ | ||||||
|  |         line: read-line as c-string! string/rs-head prompt | ||||||
|  |         if line = null [halt]  ; EOF | ||||||
|  |  | ||||||
|  |          #if OS <> 'MacOSX [add-history line] | ||||||
|  |  | ||||||
|  |         str: string/load line  1 + length? line | ||||||
|  | ;       free as byte-ptr! line | ||||||
|  |     ] | ||||||
|  |     SET_RETURN(str) | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | count-delimiters: function [ | ||||||
|  |     buffer  [string!] | ||||||
|  |     return: [block!] | ||||||
|  | ][ | ||||||
|  |     list: copy [0 0] | ||||||
|  |     c: none | ||||||
|  |      | ||||||
|  |     foreach c buffer [ | ||||||
|  |         case [ | ||||||
|  |             escaped? [ | ||||||
|  |                 escaped?: no | ||||||
|  |             ] | ||||||
|  |             in-comment? [ | ||||||
|  |                 switch c [ | ||||||
|  |                     #"^/" [in-comment?: no] | ||||||
|  |                 ] | ||||||
|  |             ] | ||||||
|  |             'else [ | ||||||
|  |                 switch c [ | ||||||
|  |                     #"^^" [escaped?: yes] | ||||||
|  |                     #";"  [if zero? list/2 [in-comment?: yes]] | ||||||
|  |                     #"["  [list/1: list/1 + 1] | ||||||
|  |                     #"]"  [list/1: list/1 - 1] | ||||||
|  |                     #"{"  [list/2: list/2 + 1] | ||||||
|  |                     #"}"  [list/2: list/2 - 1] | ||||||
|  |                 ] | ||||||
|  |             ] | ||||||
|  |         ] | ||||||
|  |     ] | ||||||
|  |     list | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | do-console: function [][ | ||||||
|  |     buffer: make string! 10000 | ||||||
|  |     prompt: red-prompt: "red>> " | ||||||
|  |     mode:  'mono | ||||||
|  |      | ||||||
|  |     switch-mode: [ | ||||||
|  |         mode: case [ | ||||||
|  |             cnt/1 > 0 ['block] | ||||||
|  |             cnt/2 > 0 ['string] | ||||||
|  |             'else     [ | ||||||
|  |                 prompt: red-prompt | ||||||
|  |                 do eval | ||||||
|  |                 'mono | ||||||
|  |             ] | ||||||
|  |         ] | ||||||
|  |         prompt: switch mode [ | ||||||
|  |             block  ["[^-"] | ||||||
|  |             string ["{^-"] | ||||||
|  |             mono   [red-prompt] | ||||||
|  |         ] | ||||||
|  |     ] | ||||||
|  |      | ||||||
|  |     eval: [ | ||||||
|  |         code: load/all buffer | ||||||
|  |          | ||||||
|  |         unless tail? code [ | ||||||
|  |             set/any 'result do code | ||||||
|  |              | ||||||
|  |             unless unset? :result [ | ||||||
|  |                 if 67 = length? result: mold/part :result 67 [  ;-- optimized for width = 72 | ||||||
|  |                     clear back tail result | ||||||
|  |                     append result "..." | ||||||
|  |                 ] | ||||||
|  |                 print ["==" result] | ||||||
|  |             ] | ||||||
|  |         ] | ||||||
|  |         clear buffer | ||||||
|  |     ] | ||||||
|  |  | ||||||
|  |     while [true][ | ||||||
|  |         unless tail? line: input prompt [ | ||||||
|  |             append buffer line | ||||||
|  |             cnt: count-delimiters buffer | ||||||
|  |  | ||||||
|  |             either Windows? [ | ||||||
|  |                 remove skip tail buffer -2          ;-- clear extra CR (Windows) | ||||||
|  |             ][ | ||||||
|  |                 append buffer lf                    ;-- Unix | ||||||
|  |             ] | ||||||
|  |              | ||||||
|  |             switch mode [ | ||||||
|  |                 block  [if cnt/1 <= 0 [do switch-mode]] | ||||||
|  |                 string [if cnt/2 <= 0 [do switch-mode]] | ||||||
|  |                 mono   [do either any [cnt/1 > 0 cnt/2 > 0][switch-mode][eval]] | ||||||
|  |             ] | ||||||
|  |         ] | ||||||
|  |     ] | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | q: :quit | ||||||
|  |  | ||||||
|  | if script: read-argument [ | ||||||
|  |     script: load script | ||||||
|  |     either any [ | ||||||
|  |         script/1 <> 'Red | ||||||
|  |         not block? script/2  | ||||||
|  |     ][ | ||||||
|  |         print "*** Error: not a Red program!" | ||||||
|  |     ][ | ||||||
|  |         do skip script 2 | ||||||
|  |     ] | ||||||
|  |     quit | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | init-console "Red Console" | ||||||
|  |  | ||||||
|  | print { | ||||||
|  | -=== Red Console alpha version ===- | ||||||
|  | (only ASCII input supported) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | do-console | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user