The first cut of a talk on the R&D process in software development, including taking an invention to patent.
Includes two sets of code examples. One is Forth implemented in a 1980s dialect of Basic.
The other introduces evolutionary prototyping using a hybrid ruby/bash methodology.
This document presents new general methods for constructing doubly even magic squares of order n=4k, where k is a positive integer. For each order n, the methods generate (n^2 - 2n/4)n/2 new magic squares that were previously unknown. An auxiliary matrix L of order n is defined, from which the new magic squares can be derived through a series of row and column swaps. Several examples of the auxiliary matrix L and resultant magic squares are provided for orders n=4 and n=8.
This document contains 10 multiple choice questions covering various math and statistics topics, including functions, geometry, probability, percentages, sequences, trigonometry, ellipses, and bank interest. It also contains 5 more difficult problems involving arithmetic sequences, trigonometric equations, modeling bacterial growth, finding distances on an ellipse, and comparing interest earned at different banks over 10 years. The questions range from easy to more challenging high school level math.
5 10c exercise_index the aluminum tilt series_ex on saed do not know cell parsJoke Hadermann
This is a tutorial on how to index single crystal (electron) diffraction patterns when the cell parameters are not yet known. This follows after another tutorial for the case of known cell parameters, 5.10a.
The document discusses network modeling and analysis, specifically covering minimum spanning tree problems, shortest path problems, and maximum flow problems. It provides examples of Kruskal's algorithm to find minimum spanning trees and Floyd's algorithm to find shortest paths between nodes in a network. The document contains examples applying these algorithms to sample network graphs.
Self-managed and automatically reconfigurable stream processingVasia Kalavri
With its superior state management and savepoint mechanism, Apache Flink is unique among modern stream processors in supporting minimal-effort job reconfiguration. Savepoints are being extensively used to enable dynamic scaling, bug fixing, upgrades, and numerous other reconfiguration use-cases, all while preserving exactly-once semantics. However, when it comes to dynamic scaling, the burden of reconfiguration decisions -when and how much to scale- is currently placed on the user.
In this talk, I share our recent work at ETH Zurich on providing support for self-managed and automatically reconfigurable stream processing. I present SnailTrail (NSDI’18), an online critical path analysis module that detects bottlenecks and provides insights on streaming application performance, and DS2 (OSDI’18), an automatic scaling controller which identifies optimal backpressure-free configurations and operates reactively online. Both SnailTrail and DS2 are integrated with Apache Flink and publicly available. I conclude with evaluation results, ongoing work, and and future challenges in this area.
With its superior state management and savepoint mechanism, Apache Flink is unique among modern stream processors in supporting minimal-effort job reconfiguration. Savepoints are being extensively used to enable dynamic scaling, bug fixing, upgrades, and numerous other reconfiguration use-cases, all while preserving exactly-once semantics. However, when it comes to dynamic scaling, the burden of reconfiguration decisions -when and how much to scale- is currently placed on the user.
In this talk, I will share our recent work at ETH Zurich on providing support for self-managed and automatically reconfigurable stream processing. I will present SnailTrail (NSDI’18), an online critical path analysis module that detects bottlenecks and provides insights on streaming application performance, and DS2 (OSDI’18), an automatic scaling controller which identifies optimal backpressure-free configurations and operates reactively online. Both SnailTrail and DS2 are integrated with Apache Flink and publicly available. I will conclude with evaluation results, ongoing work, and and future challenges in this area.
- The document discusses Shor's algorithm, which can be used to factor large numbers.
- It introduces the quantum Fourier transform (QFT), which forms the core of Shor's algorithm. The QFT transforms the probability amplitudes of a quantum state.
- RSA encryption relies on the difficulty of factoring large numbers for its security. However, Shor's algorithm, using a quantum computer, could factorize numbers efficiently and break RSA encryption.
This document presents new general methods for constructing doubly even magic squares of order n=4k, where k is a positive integer. For each order n, the methods generate (n^2 - 2n/4)n/2 new magic squares that were previously unknown. An auxiliary matrix L of order n is defined, from which the new magic squares can be derived through a series of row and column swaps. Several examples of the auxiliary matrix L and resultant magic squares are provided for orders n=4 and n=8.
This document contains 10 multiple choice questions covering various math and statistics topics, including functions, geometry, probability, percentages, sequences, trigonometry, ellipses, and bank interest. It also contains 5 more difficult problems involving arithmetic sequences, trigonometric equations, modeling bacterial growth, finding distances on an ellipse, and comparing interest earned at different banks over 10 years. The questions range from easy to more challenging high school level math.
5 10c exercise_index the aluminum tilt series_ex on saed do not know cell parsJoke Hadermann
This is a tutorial on how to index single crystal (electron) diffraction patterns when the cell parameters are not yet known. This follows after another tutorial for the case of known cell parameters, 5.10a.
The document discusses network modeling and analysis, specifically covering minimum spanning tree problems, shortest path problems, and maximum flow problems. It provides examples of Kruskal's algorithm to find minimum spanning trees and Floyd's algorithm to find shortest paths between nodes in a network. The document contains examples applying these algorithms to sample network graphs.
Self-managed and automatically reconfigurable stream processingVasia Kalavri
With its superior state management and savepoint mechanism, Apache Flink is unique among modern stream processors in supporting minimal-effort job reconfiguration. Savepoints are being extensively used to enable dynamic scaling, bug fixing, upgrades, and numerous other reconfiguration use-cases, all while preserving exactly-once semantics. However, when it comes to dynamic scaling, the burden of reconfiguration decisions -when and how much to scale- is currently placed on the user.
In this talk, I share our recent work at ETH Zurich on providing support for self-managed and automatically reconfigurable stream processing. I present SnailTrail (NSDI’18), an online critical path analysis module that detects bottlenecks and provides insights on streaming application performance, and DS2 (OSDI’18), an automatic scaling controller which identifies optimal backpressure-free configurations and operates reactively online. Both SnailTrail and DS2 are integrated with Apache Flink and publicly available. I conclude with evaluation results, ongoing work, and and future challenges in this area.
With its superior state management and savepoint mechanism, Apache Flink is unique among modern stream processors in supporting minimal-effort job reconfiguration. Savepoints are being extensively used to enable dynamic scaling, bug fixing, upgrades, and numerous other reconfiguration use-cases, all while preserving exactly-once semantics. However, when it comes to dynamic scaling, the burden of reconfiguration decisions -when and how much to scale- is currently placed on the user.
In this talk, I will share our recent work at ETH Zurich on providing support for self-managed and automatically reconfigurable stream processing. I will present SnailTrail (NSDI’18), an online critical path analysis module that detects bottlenecks and provides insights on streaming application performance, and DS2 (OSDI’18), an automatic scaling controller which identifies optimal backpressure-free configurations and operates reactively online. Both SnailTrail and DS2 are integrated with Apache Flink and publicly available. I will conclude with evaluation results, ongoing work, and and future challenges in this area.
- The document discusses Shor's algorithm, which can be used to factor large numbers.
- It introduces the quantum Fourier transform (QFT), which forms the core of Shor's algorithm. The QFT transforms the probability amplitudes of a quantum state.
- RSA encryption relies on the difficulty of factoring large numbers for its security. However, Shor's algorithm, using a quantum computer, could factorize numbers efficiently and break RSA encryption.
1) The document discusses using integral calculus to calculate the area between two curves or the volume of solids obtained by rotating an area about an axis.
2) It introduces the disk method for finding volumes by slicing a solid into thin circular disks and summing their volumes. This is used to calculate the volume of a cone.
3) The washer method is also introduced, which is used when the cross-sectional slices have a hole in the center, resembling a washer. This method subtracts the inner circular area from the outer area.
Numerical Methods: curve fitting and interpolationNikolai Priezjev
This document discusses curve fitting and interpolation techniques. It covers linear regression using the least squares method to fit data to a straight line model. It also discusses fitting data to other functions like exponential, logarithmic and polynomial models. For polynomial regression, a second order polynomial is presented which requires solving a system of equations to determine the coefficients that minimize the residual errors between measured and modeled data. An example demonstrates applying these methods to find the coefficients for a straight line and second order polynomial fit to sample data sets.
The document discusses solving the 8 queens problem using backtracking. It begins by explaining backtracking as an algorithm that builds partial candidates for solutions incrementally and abandons any partial candidate that cannot be completed to a valid solution. It then provides more details on the 8 queens problem itself - the goal is to place 8 queens on a chessboard so that no two queens attack each other. Backtracking is well-suited for solving this problem by attempting to place queens one by one and backtracking when an invalid placement is found.
- Maintain a 2D array P of size V×V along with the distance array D
- P[i][j] stores the intermediate vertex on the shortest path from i to j
- During each iteration of k, if an updated shortest path is found via k, store k in P[i][j]
- To extract the path, start from P[i][j] and follow the chain of intermediate vertices stored in P until reaching i
- This allows tracing the shortest path after the algorithm terminates in O(1) time per path
The modification requires storing only the
This document contains multiple questions related to programming, geometry, probability, and other topics. It provides the questions, solutions, and explanations for the following:
1) A question about the number of lines of code that can be written by a certain number of programmers in a given time period.
2) A geometry question about the minimum number of "1-sets" (points separated from others by a line) for 5 points in a plane.
3) A question about the number of times a particular number appears when labeling items with a numeric system of a certain base.
4) A question regarding the angle between the hands of a clock on the planet Oz, which has different timekeeping conventions than
1) Complex analysis is used in many areas including physics, engineering, integrals, asymptotics, conformal mapping, and radiation physics.
2) A complex number z can be represented as an ordered pair (x,y) of real numbers or in polar form as r(cosθ + i sinθ).
3) Basic operations like addition, subtraction, multiplication, and division can be performed on complex numbers by treating them as vectors or using their polar representations.
4) Euler's formula relates complex exponents to trigonometric functions and allows trigonometric identities to be derived using complex analysis.
Classically, the point particle and the string exhibit the same kind of motion. For instance in flat space both of them move in straight lines albeit for string oscillations which occur because it has to obey the wave equation.
When we put it in AdS3 space both the point particle and the string move as if they are in a potential well. However, coordinate singularities arise in the numerical computation of the string so motion beyond ρ = 0 becomes computationally inac- cessible. Physically the string should still move beyond this point in empty AdS3 spacetime. This singularity is an artefact because coordinate systems in general are not physical. The behaviour of the string in the vicinity of a black hole background in AdS3 spacetime is well defined a fair bit away from the horizon. It moves in the same manner as in the AdS3 spacetime in the absence of the background. Un- fortunately, when the string approaches the horizon part of the string overshoots into the horizon. The solutions become divergent and the numerical solution fails before we can observe anything interesting.
This document discusses complex variables and their applications. It introduces complex numbers using the form z = x + iy and defines complex arithmetic operations like addition, multiplication, and conjugation. Euler's formula e^{i\theta} = cos(\theta) + i\sin(\theta) is presented and used to derive trigonometric identities. De Moivre's theorem and finding roots of complex numbers are also covered.
Derivada aplicada en la carrera de electrónica y automatización.DANIELAXIOMARAANDRAN
This document discusses the applications of derivatives in electronics and automation careers. It provides three examples of optimization problems involving maximizing or minimizing a function using derivatives. The first example involves finding the maximum volume of a cardboard box. The second finds the maximum power output when connecting a resistor to a battery. The third maximizes data transmission speed based on the number of computers. In each case, the document derives the function, takes the derivative, sets it equal to zero to find critical points, and determines the maximum or minimum values.
This document contains information about a computer aided engineering drawing examination, including instructions, questions, and diagrams. Question 1 involves drawing projections of points and lines. Question 2 involves drawing projections of hexagonal and frustum pyramids. Question 3 involves drawing isometric projections of a pentagonal pyramid or reducing a frustum of a square pyramid to development of its lateral surfaces. The examination tests skills in technical drawing, geometry, and spatial visualization.
- 1-2 significant figures are used for things like grades, ages described in decades, cooking measurements, distances, areas, weights, temperatures.
- 3 significant figures are used for more precise measurements like heights, biological works, accurate measurements with a ruler.
- 4 or more significant figures are used for things like trigonometric ratios, logarithms, and highly precise scientific works.
- In general, fewer significant figures are used for less precise measurements and descriptions, while more are used for highly accurate scientific or technical contexts.
The document discusses the binomial theorem, which provides a formula for expanding binomial expressions of the form (a + b)^n. It explains that the theorem allows calculating terms of the expansion without using repeated FOIL multiplication. Pascal's triangle is introduced as a way to determine the coefficients of each term. The key points of the binomial theorem are defined, including that the sum of the exponents in each term equals n. An example expansion is shown. Proofs of properties like the coefficients when r=0, 1, n-1, n are provided.
HW 5-RSA/ascii2str.m
function str = ascii2str(ascii)
% Convert to string
str = char(ascii);
HW 5-RSA/bigmod.m
function remainder = bigmod (number, power, modulo)
% modulo function for large numbers, -> number^power(mod modulo)
% by bennyboss / 2005-06-24 / Matlab 7
% I used algorithm from this webpage:
% http://www.disappearing-inc.com/ciphers/rsa.html
% binary decomposition
binary(1,1) = 1;
col = 2;
while ( binary(1, col-1) <= power-binary(1, col-1) )
binary(1, col) = 2*binary(1, col-1);
col = col + 1;
end
% flip matrix
binary = fliplr(binary);
% extract binary decomposition from number
result = power;
cols = length(binary);
extracted_binary = zeros(1, cols);
index = zeros(1, cols);
for ( col=1 : cols )
if( result-binary(1, col) > 0 )
result = result - binary(1, col);
extracted_binary(1, col) = binary(1, col);
index(1, col) = col;
elseif ( result-binary(1, col) == 0 )
extracted_binary(1, col) = binary(1, col);
index(1, col) = col;
break;
end
end
% flip matrix
binary = fliplr(binary);
% doubling the powers by squaring the numbers
cols2 = length(extracted_binary);
rem_sqr = zeros(1, cols);
rem_sqr(1, 1) = mod(number^1, modulo);
if ( cols2 > 1 )
for ( col=2 : cols)
rem_sqr(1, col) = mod(rem_sqr(1, col-1)^2, modulo);
end
end
% flip matrix
rem_sqr = fliplr(rem_sqr);
% compute reminder
index = find(index);
remainder = rem_sqr(1, index(1, 1));
cols = length(index);
for (col=2 : cols)
remainder = mod(remainder*rem_sqr(1, index(1, col)), modulo);
end
HW 5-RSA/EGCP447-Lecture No 10.pdf
RSA Encryption
RSA = Rivest, Shamir, and Adelman (MIT), 1978
Underlying hard problem
– Number theory – determining prime factors of a given
(large) number
e.g., factoring of small #: 5 -) 5, 6 -) 2 *3
– Arithmetic modulo n
How secure is RSA?
– So far remains secure (after all these years...)
– Will somebody propose a quick algorithm to factor
large numbers?
– Will quantum computing break it? -) TBD
RSA Encryption
In RSA:
– P = E (D(P)) = D(E(P)) (order of D/E does not matter)
– More precisely: P = E(kE, D(kD, P)) = D(kD, E(kE, P))
Encryption: C = Pe mod n KE = e
– n is the key length
– Note, P is turned into an integer using a padding
scheme
– Given C, it is very difficult to find P without knowing
KD
Decryption: P = Cd mod n KD = d
We will look at this algorithm in detail next time
RSA Algorithm
1. Key Generation
– A key generation algorithm
2. RSA Function Evaluation
– A function F, that takes as an input a point x and a
key k and produces either an encrypted result or
plaintext, depending on the input and the key
Key Generation
The key generation algorithm is the most
complex part of RSA
The aim of the key generation algorithm is to
generate both th ...
This document provides a review of various algebra and trigonometry concepts including exponents, radicals, functions, polynomials, factoring, rational expressions, graphing, equations, inequalities, trigonometric functions and identities, inverse trigonometric functions, and solving trigonometric equations. It includes over a dozen practice problems for each topic to help reinforce the concepts and formulas through worked examples.
Differential geometry three dimensional spaceSolo Hermelin
This presentation describes the mathematics of curves and surfaces in a 3 dimensional (Euclidean) space.
The presentation is at an Undergraduate in Science (Math, Physics, Engineering) level.
Plee send comments and suggestions to improvements to solo.hermelin@gmail.com. Thanks/
More presentations can be found at my website http://www.solohermelin.com.
In this work we discuss how to compute KLE with complexity O(k n log n), how to approximate large covariance matrices (in H-matrix format), how to use the Lanczos method.
We solve elliptic PDE with uncertain coefficients. We apply Karhunen-Loeve expansion to separate stochastic part from spatial part. The corresponding eigenvalue problem with covariance function is solved via the Hierarchical Matrix technique. We also demonstrate how low-rank tensor method can be applied for high-dimensional problems (e.g., to compute higher order statistical moments) . We provide explicit formulas to compute statistical moments of order k with linear complexity.
Generics, Reflection, and Efficient CollectionsEleanor McHugh
This is a talk about how we structure and collate information so as to effectively process it, the language tools Go provides to help us do this, and the sometimes frustrating tradeoffs we must make when marry the real world with the digital.
We'll start by looking at basic collection types in Go: array, slice, map, and channel. These will then be used as the basis for our own user defined types with methods for processing the collected items.
These methods will then be expanded to take functions as parameters (the higher order functional style popularised by languages such as Ruby) and by using Go's Reflection package we will generalise them for a variety of tasks and uses cases.
Reflection adds an interpreted element to our programs with a resulting performance cost. Careful design can often minimise this cost and it may well amortise to zero on a sufficiently large collection however there is always greater code complexity to manage. When the data to be contained in a user defined collection is homogenous we can reduce much of this complexity by using Generics and our next set of examples will demonstrate this.
At the end of this talk you should have some useful ideas for designing your own collection types in Go as well as a reasonable base from which to explore Reflection, Generics, and the Higher-Order Functional style of programming.
1) The document discusses using integral calculus to calculate the area between two curves or the volume of solids obtained by rotating an area about an axis.
2) It introduces the disk method for finding volumes by slicing a solid into thin circular disks and summing their volumes. This is used to calculate the volume of a cone.
3) The washer method is also introduced, which is used when the cross-sectional slices have a hole in the center, resembling a washer. This method subtracts the inner circular area from the outer area.
Numerical Methods: curve fitting and interpolationNikolai Priezjev
This document discusses curve fitting and interpolation techniques. It covers linear regression using the least squares method to fit data to a straight line model. It also discusses fitting data to other functions like exponential, logarithmic and polynomial models. For polynomial regression, a second order polynomial is presented which requires solving a system of equations to determine the coefficients that minimize the residual errors between measured and modeled data. An example demonstrates applying these methods to find the coefficients for a straight line and second order polynomial fit to sample data sets.
The document discusses solving the 8 queens problem using backtracking. It begins by explaining backtracking as an algorithm that builds partial candidates for solutions incrementally and abandons any partial candidate that cannot be completed to a valid solution. It then provides more details on the 8 queens problem itself - the goal is to place 8 queens on a chessboard so that no two queens attack each other. Backtracking is well-suited for solving this problem by attempting to place queens one by one and backtracking when an invalid placement is found.
- Maintain a 2D array P of size V×V along with the distance array D
- P[i][j] stores the intermediate vertex on the shortest path from i to j
- During each iteration of k, if an updated shortest path is found via k, store k in P[i][j]
- To extract the path, start from P[i][j] and follow the chain of intermediate vertices stored in P until reaching i
- This allows tracing the shortest path after the algorithm terminates in O(1) time per path
The modification requires storing only the
This document contains multiple questions related to programming, geometry, probability, and other topics. It provides the questions, solutions, and explanations for the following:
1) A question about the number of lines of code that can be written by a certain number of programmers in a given time period.
2) A geometry question about the minimum number of "1-sets" (points separated from others by a line) for 5 points in a plane.
3) A question about the number of times a particular number appears when labeling items with a numeric system of a certain base.
4) A question regarding the angle between the hands of a clock on the planet Oz, which has different timekeeping conventions than
1) Complex analysis is used in many areas including physics, engineering, integrals, asymptotics, conformal mapping, and radiation physics.
2) A complex number z can be represented as an ordered pair (x,y) of real numbers or in polar form as r(cosθ + i sinθ).
3) Basic operations like addition, subtraction, multiplication, and division can be performed on complex numbers by treating them as vectors or using their polar representations.
4) Euler's formula relates complex exponents to trigonometric functions and allows trigonometric identities to be derived using complex analysis.
Classically, the point particle and the string exhibit the same kind of motion. For instance in flat space both of them move in straight lines albeit for string oscillations which occur because it has to obey the wave equation.
When we put it in AdS3 space both the point particle and the string move as if they are in a potential well. However, coordinate singularities arise in the numerical computation of the string so motion beyond ρ = 0 becomes computationally inac- cessible. Physically the string should still move beyond this point in empty AdS3 spacetime. This singularity is an artefact because coordinate systems in general are not physical. The behaviour of the string in the vicinity of a black hole background in AdS3 spacetime is well defined a fair bit away from the horizon. It moves in the same manner as in the AdS3 spacetime in the absence of the background. Un- fortunately, when the string approaches the horizon part of the string overshoots into the horizon. The solutions become divergent and the numerical solution fails before we can observe anything interesting.
This document discusses complex variables and their applications. It introduces complex numbers using the form z = x + iy and defines complex arithmetic operations like addition, multiplication, and conjugation. Euler's formula e^{i\theta} = cos(\theta) + i\sin(\theta) is presented and used to derive trigonometric identities. De Moivre's theorem and finding roots of complex numbers are also covered.
Derivada aplicada en la carrera de electrónica y automatización.DANIELAXIOMARAANDRAN
This document discusses the applications of derivatives in electronics and automation careers. It provides three examples of optimization problems involving maximizing or minimizing a function using derivatives. The first example involves finding the maximum volume of a cardboard box. The second finds the maximum power output when connecting a resistor to a battery. The third maximizes data transmission speed based on the number of computers. In each case, the document derives the function, takes the derivative, sets it equal to zero to find critical points, and determines the maximum or minimum values.
This document contains information about a computer aided engineering drawing examination, including instructions, questions, and diagrams. Question 1 involves drawing projections of points and lines. Question 2 involves drawing projections of hexagonal and frustum pyramids. Question 3 involves drawing isometric projections of a pentagonal pyramid or reducing a frustum of a square pyramid to development of its lateral surfaces. The examination tests skills in technical drawing, geometry, and spatial visualization.
- 1-2 significant figures are used for things like grades, ages described in decades, cooking measurements, distances, areas, weights, temperatures.
- 3 significant figures are used for more precise measurements like heights, biological works, accurate measurements with a ruler.
- 4 or more significant figures are used for things like trigonometric ratios, logarithms, and highly precise scientific works.
- In general, fewer significant figures are used for less precise measurements and descriptions, while more are used for highly accurate scientific or technical contexts.
The document discusses the binomial theorem, which provides a formula for expanding binomial expressions of the form (a + b)^n. It explains that the theorem allows calculating terms of the expansion without using repeated FOIL multiplication. Pascal's triangle is introduced as a way to determine the coefficients of each term. The key points of the binomial theorem are defined, including that the sum of the exponents in each term equals n. An example expansion is shown. Proofs of properties like the coefficients when r=0, 1, n-1, n are provided.
HW 5-RSA/ascii2str.m
function str = ascii2str(ascii)
% Convert to string
str = char(ascii);
HW 5-RSA/bigmod.m
function remainder = bigmod (number, power, modulo)
% modulo function for large numbers, -> number^power(mod modulo)
% by bennyboss / 2005-06-24 / Matlab 7
% I used algorithm from this webpage:
% http://www.disappearing-inc.com/ciphers/rsa.html
% binary decomposition
binary(1,1) = 1;
col = 2;
while ( binary(1, col-1) <= power-binary(1, col-1) )
binary(1, col) = 2*binary(1, col-1);
col = col + 1;
end
% flip matrix
binary = fliplr(binary);
% extract binary decomposition from number
result = power;
cols = length(binary);
extracted_binary = zeros(1, cols);
index = zeros(1, cols);
for ( col=1 : cols )
if( result-binary(1, col) > 0 )
result = result - binary(1, col);
extracted_binary(1, col) = binary(1, col);
index(1, col) = col;
elseif ( result-binary(1, col) == 0 )
extracted_binary(1, col) = binary(1, col);
index(1, col) = col;
break;
end
end
% flip matrix
binary = fliplr(binary);
% doubling the powers by squaring the numbers
cols2 = length(extracted_binary);
rem_sqr = zeros(1, cols);
rem_sqr(1, 1) = mod(number^1, modulo);
if ( cols2 > 1 )
for ( col=2 : cols)
rem_sqr(1, col) = mod(rem_sqr(1, col-1)^2, modulo);
end
end
% flip matrix
rem_sqr = fliplr(rem_sqr);
% compute reminder
index = find(index);
remainder = rem_sqr(1, index(1, 1));
cols = length(index);
for (col=2 : cols)
remainder = mod(remainder*rem_sqr(1, index(1, col)), modulo);
end
HW 5-RSA/EGCP447-Lecture No 10.pdf
RSA Encryption
RSA = Rivest, Shamir, and Adelman (MIT), 1978
Underlying hard problem
– Number theory – determining prime factors of a given
(large) number
e.g., factoring of small #: 5 -) 5, 6 -) 2 *3
– Arithmetic modulo n
How secure is RSA?
– So far remains secure (after all these years...)
– Will somebody propose a quick algorithm to factor
large numbers?
– Will quantum computing break it? -) TBD
RSA Encryption
In RSA:
– P = E (D(P)) = D(E(P)) (order of D/E does not matter)
– More precisely: P = E(kE, D(kD, P)) = D(kD, E(kE, P))
Encryption: C = Pe mod n KE = e
– n is the key length
– Note, P is turned into an integer using a padding
scheme
– Given C, it is very difficult to find P without knowing
KD
Decryption: P = Cd mod n KD = d
We will look at this algorithm in detail next time
RSA Algorithm
1. Key Generation
– A key generation algorithm
2. RSA Function Evaluation
– A function F, that takes as an input a point x and a
key k and produces either an encrypted result or
plaintext, depending on the input and the key
Key Generation
The key generation algorithm is the most
complex part of RSA
The aim of the key generation algorithm is to
generate both th ...
This document provides a review of various algebra and trigonometry concepts including exponents, radicals, functions, polynomials, factoring, rational expressions, graphing, equations, inequalities, trigonometric functions and identities, inverse trigonometric functions, and solving trigonometric equations. It includes over a dozen practice problems for each topic to help reinforce the concepts and formulas through worked examples.
Differential geometry three dimensional spaceSolo Hermelin
This presentation describes the mathematics of curves and surfaces in a 3 dimensional (Euclidean) space.
The presentation is at an Undergraduate in Science (Math, Physics, Engineering) level.
Plee send comments and suggestions to improvements to solo.hermelin@gmail.com. Thanks/
More presentations can be found at my website http://www.solohermelin.com.
In this work we discuss how to compute KLE with complexity O(k n log n), how to approximate large covariance matrices (in H-matrix format), how to use the Lanczos method.
We solve elliptic PDE with uncertain coefficients. We apply Karhunen-Loeve expansion to separate stochastic part from spatial part. The corresponding eigenvalue problem with covariance function is solved via the Hierarchical Matrix technique. We also demonstrate how low-rank tensor method can be applied for high-dimensional problems (e.g., to compute higher order statistical moments) . We provide explicit formulas to compute statistical moments of order k with linear complexity.
Generics, Reflection, and Efficient CollectionsEleanor McHugh
This is a talk about how we structure and collate information so as to effectively process it, the language tools Go provides to help us do this, and the sometimes frustrating tradeoffs we must make when marry the real world with the digital.
We'll start by looking at basic collection types in Go: array, slice, map, and channel. These will then be used as the basis for our own user defined types with methods for processing the collected items.
These methods will then be expanded to take functions as parameters (the higher order functional style popularised by languages such as Ruby) and by using Go's Reflection package we will generalise them for a variety of tasks and uses cases.
Reflection adds an interpreted element to our programs with a resulting performance cost. Careful design can often minimise this cost and it may well amortise to zero on a sufficiently large collection however there is always greater code complexity to manage. When the data to be contained in a user defined collection is homogenous we can reduce much of this complexity by using Generics and our next set of examples will demonstrate this.
At the end of this talk you should have some useful ideas for designing your own collection types in Go as well as a reasonable base from which to explore Reflection, Generics, and the Higher-Order Functional style of programming.
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]Eleanor McHugh
The document discusses using Sinatra and Ruby to build web applications that utilize asynchronous JavaScript and XMLHttpRequest (AJAX) techniques. It demonstrates how to make HTTP requests to a Sinatra backend from JavaScript using XMLHttpRequest, Fetch API promises, and DOM manipulation. Various timing functions like setInterval and setTimeout are also explored. The document contains sample code for building a basic Sinatra API and incrementally enhancing the frontend JavaScript code to retrieve and display responses asynchronously.
The Browser Environment - A Systems Programmer's PerspectiveEleanor McHugh
The document discusses asynchronous JavaScript and XML (AJAX) techniques for making asynchronous HTTP requests from the browser. It provides code examples using XMLHttpRequest and the newer Fetch API to make requests to server-side handlers written in Go. The code sets up a simple page that displays buttons for different asynchronous actions, and uses JavaScript functions to make requests on button click, printing the responses to a log on the page. This demonstrates asynchronous interactivity between the browser and server.
Go for the paranoid network programmer, 3rd editionEleanor McHugh
Draft third edition of my #golang network programming and cryptography talk given to the Belfast Gophers Meetup. Now with an introduction to websockets.
An introduction to functional programming with goEleanor McHugh
A crash course in functional programming concepts using Go. Heavy on code, light on theory.
You can find the examples at https://github.com/feyeleanor/intro_to_fp_in_go
Implementing virtual machines in go & c 2018 reduxEleanor McHugh
An updated version of my talk on virtual machine cores comparing techniques in C and Go for implementing dispatch loops, stacks & hash maps.
Lots of tested and debugged code is provided as well as references to some useful/interesting books.
Digital Identity talk from Strange Loop 2018 and Build Stuff Lithuania 2018 including walkthrough of the uPass system and the design principles behind it.
Don't Ask, Don't Tell - The Virtues of Privacy By DesignEleanor McHugh
This document discusses privacy by design and identity. It describes how Eleanor McHugh has worked on privacy and security issues for decades, developing technologies like encrypted DNS and national digital identities. The document outlines principles of privacy like knowing only what is necessary. It discusses tools for trust like hashing, encryption, and blockchains. It provides a case study of uPass, McHugh's technology for private identity verification and age validation using mobile devices, selfies, and secure stores. uPass allows for anonymous or pseudonymous transactions with receipts to prove occurrences.
Don't ask, don't tell the virtues of privacy by designEleanor McHugh
This document discusses privacy by design and the virtues of not asking for or revealing unnecessary personal information. It provides a biography of Eleanor McHugh, an expert in privacy architecture, cryptography, and security. It then defines paranoia and discusses how justified suspicion of others is important in information security.
An overview of the uPass digital identity system. Covers the core problem domain and the end-to-end stack from liveness to black-box transaction store. Lots of diagrams, references to all the relevant patent applications and so forth.
Going Loopy - Adventures in Iteration with Google GoEleanor McHugh
The document discusses loops and iteration in Google Go. It covers for loops, infinite loops, the range keyword, functions, closures, and type assertions. Code examples are provided to demonstrate conditional loops, printing slice elements with a for loop and range, passing slices to functions, asserting the type within a function, and using closures to pass a slice to a function.
Distributed Ledgers: Anonymity & Immutability at ScaleEleanor McHugh
This document discusses distributed ledgers and their ability to provide anonymity and immutability at scale. It lists the professional experience of Eleanor McHugh including work with InterClear CA, ENUM, Telnic, Malta E-ID, and HSBC GC from 1998 to 2012. It also notes her background as a cryptographer, physicist, and in system architecture. Contact information is provided through websites slideshare, leanpub, and inidsol.uk. The document ends by mentioning anonymity and pseudonymity.
An introduction to Go from basics to web through the lens of "Hello World", extracted from the Book "A Go Developer's Notebook" available from http://leanpub.com/GoNotebook
Going Loopy: Adventures in Iteration with GoEleanor McHugh
The document describes iterations and loops in Go using for loops and the range keyword. It discusses iterating over slices, using closures to iterate, and asserting types. Code examples are provided to demonstrate iterating over a slice of integers using a for loop with len() and indexing, using range to iterate, passing functions as arguments to iterate generically, and ensuring the type is correct when the argument is an interface.
Finding a useful outlet for my many Adventures in goEleanor McHugh
This document discusses using Leanpub to write and publish a living book. It explains that a living book is inspired by Neal Stephenson's A Young Lady's Illustrated Primer, where each chapter has a theme and pushes the subject matter to new problems. The author aims to write such a living book on Leanpub about a topic of interest, by continually adding new material until running out of content. Each chapter will be structured as an adventure to not only teach solutions to existing problems, but how to solve new ones. The document provides examples of chapter content from a Hello World book that introduces network encryption.
An interpreter for a stack-based virtual machine is implemented in both Go and C. The document discusses different approaches to implementing virtual machines and interpreters, including using stacks, registers, direct threading, and just-in-time compilation. Both direct and indirect interpretation techniques are demonstrated with examples in Go and C.
UiPath Test Automation using UiPath Test Suite series, part 6DianaGray10
Welcome to UiPath Test Automation using UiPath Test Suite series part 6. In this session, we will cover Test Automation with generative AI and Open AI.
UiPath Test Automation with generative AI and Open AI webinar offers an in-depth exploration of leveraging cutting-edge technologies for test automation within the UiPath platform. Attendees will delve into the integration of generative AI, a test automation solution, with Open AI advanced natural language processing capabilities.
Throughout the session, participants will discover how this synergy empowers testers to automate repetitive tasks, enhance testing accuracy, and expedite the software testing life cycle. Topics covered include the seamless integration process, practical use cases, and the benefits of harnessing AI-driven automation for UiPath testing initiatives. By attending this webinar, testers, and automation professionals can gain valuable insights into harnessing the power of AI to optimize their test automation workflows within the UiPath ecosystem, ultimately driving efficiency and quality in software development processes.
What will you get from this session?
1. Insights into integrating generative AI.
2. Understanding how this integration enhances test automation within the UiPath platform
3. Practical demonstrations
4. Exploration of real-world use cases illustrating the benefits of AI-driven test automation for UiPath
Topics covered:
What is generative AI
Test Automation with generative AI and Open AI.
UiPath integration with generative AI
Speaker:
Deepak Rai, Automation Practice Lead, Boundaryless Group and UiPath MVP
Have you ever been confused by the myriad of choices offered by AWS for hosting a website or an API?
Lambda, Elastic Beanstalk, Lightsail, Amplify, S3 (and more!) can each host websites + APIs. But which one should we choose?
Which one is cheapest? Which one is fastest? Which one will scale to meet our needs?
Join me in this session as we dive into each AWS hosting service to determine which one is best for your scenario and explain why!
Fueling AI with Great Data with Airbyte WebinarZilliz
This talk will focus on how to collect data from a variety of sources, leveraging this data for RAG and other GenAI use cases, and finally charting your course to productionalization.
HCL Notes and Domino License Cost Reduction in the World of DLAUpanagenda
Webinar Recording: https://www.panagenda.com/webinars/hcl-notes-and-domino-license-cost-reduction-in-the-world-of-dlau/
The introduction of DLAU and the CCB & CCX licensing model caused quite a stir in the HCL community. As a Notes and Domino customer, you may have faced challenges with unexpected user counts and license costs. You probably have questions on how this new licensing approach works and how to benefit from it. Most importantly, you likely have budget constraints and want to save money where possible. Don’t worry, we can help with all of this!
We’ll show you how to fix common misconfigurations that cause higher-than-expected user counts, and how to identify accounts which you can deactivate to save money. There are also frequent patterns that can cause unnecessary cost, like using a person document instead of a mail-in for shared mailboxes. We’ll provide examples and solutions for those as well. And naturally we’ll explain the new licensing model.
Join HCL Ambassador Marc Thomas in this webinar with a special guest appearance from Franz Walder. It will give you the tools and know-how to stay on top of what is going on with Domino licensing. You will be able lower your cost through an optimized configuration and keep it low going forward.
These topics will be covered
- Reducing license cost by finding and fixing misconfigurations and superfluous accounts
- How do CCB and CCX licenses really work?
- Understanding the DLAU tool and how to best utilize it
- Tips for common problem areas, like team mailboxes, functional/test users, etc
- Practical examples and best practices to implement right away
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?Speck&Tech
ABSTRACT: A prima vista, un mattoncino Lego e la backdoor XZ potrebbero avere in comune il fatto di essere entrambi blocchi di costruzione, o dipendenze di progetti creativi e software. La realtà è che un mattoncino Lego e il caso della backdoor XZ hanno molto di più di tutto ciò in comune.
Partecipate alla presentazione per immergervi in una storia di interoperabilità, standard e formati aperti, per poi discutere del ruolo importante che i contributori hanno in una comunità open source sostenibile.
BIO: Sostenitrice del software libero e dei formati standard e aperti. È stata un membro attivo dei progetti Fedora e openSUSE e ha co-fondato l'Associazione LibreItalia dove è stata coinvolta in diversi eventi, migrazioni e formazione relativi a LibreOffice. In precedenza ha lavorato a migrazioni e corsi di formazione su LibreOffice per diverse amministrazioni pubbliche e privati. Da gennaio 2020 lavora in SUSE come Software Release Engineer per Uyuni e SUSE Manager e quando non segue la sua passione per i computer e per Geeko coltiva la sua curiosità per l'astronomia (da cui deriva il suo nickname deneb_alpha).
Building Production Ready Search Pipelines with Spark and MilvusZilliz
Spark is the widely used ETL tool for processing, indexing and ingesting data to serving stack for search. Milvus is the production-ready open-source vector database. In this talk we will show how to use Spark to process unstructured data to extract vector representations, and push the vectors to Milvus vector database for search serving.
OpenID AuthZEN Interop Read Out - AuthorizationDavid Brossard
During Identiverse 2024 and EIC 2024, members of the OpenID AuthZEN WG got together and demoed their authorization endpoints conforming to the AuthZEN API
How to Get CNIC Information System with Paksim Ga.pptxdanishmna97
Pakdata Cf is a groundbreaking system designed to streamline and facilitate access to CNIC information. This innovative platform leverages advanced technology to provide users with efficient and secure access to their CNIC details.
Ocean lotus Threat actors project by John Sitima 2024 (1).pptxSitimaJohn
Ocean Lotus cyber threat actors represent a sophisticated, persistent, and politically motivated group that poses a significant risk to organizations and individuals in the Southeast Asian region. Their continuous evolution and adaptability underscore the need for robust cybersecurity measures and international cooperation to identify and mitigate the threats posed by such advanced persistent threat groups.
5th LF Energy Power Grid Model Meet-up SlidesDanBrown980551
5th Power Grid Model Meet-up
It is with great pleasure that we extend to you an invitation to the 5th Power Grid Model Meet-up, scheduled for 6th June 2024. This event will adopt a hybrid format, allowing participants to join us either through an online Mircosoft Teams session or in person at TU/e located at Den Dolech 2, Eindhoven, Netherlands. The meet-up will be hosted by Eindhoven University of Technology (TU/e), a research university specializing in engineering science & technology.
Power Grid Model
The global energy transition is placing new and unprecedented demands on Distribution System Operators (DSOs). Alongside upgrades to grid capacity, processes such as digitization, capacity optimization, and congestion management are becoming vital for delivering reliable services.
Power Grid Model is an open source project from Linux Foundation Energy and provides a calculation engine that is increasingly essential for DSOs. It offers a standards-based foundation enabling real-time power systems analysis, simulations of electrical power grids, and sophisticated what-if analysis. In addition, it enables in-depth studies and analysis of the electrical power grid’s behavior and performance. This comprehensive model incorporates essential factors such as power generation capacity, electrical losses, voltage levels, power flows, and system stability.
Power Grid Model is currently being applied in a wide variety of use cases, including grid planning, expansion, reliability, and congestion studies. It can also help in analyzing the impact of renewable energy integration, assessing the effects of disturbances or faults, and developing strategies for grid control and optimization.
What to expect
For the upcoming meetup we are organizing, we have an exciting lineup of activities planned:
-Insightful presentations covering two practical applications of the Power Grid Model.
-An update on the latest advancements in Power Grid -Model technology during the first and second quarters of 2024.
-An interactive brainstorming session to discuss and propose new feature requests.
-An opportunity to connect with fellow Power Grid Model enthusiasts and users.
In the rapidly evolving landscape of technologies, XML continues to play a vital role in structuring, storing, and transporting data across diverse systems. The recent advancements in artificial intelligence (AI) present new methodologies for enhancing XML development workflows, introducing efficiency, automation, and intelligent capabilities. This presentation will outline the scope and perspective of utilizing AI in XML development. The potential benefits and the possible pitfalls will be highlighted, providing a balanced view of the subject.
We will explore the capabilities of AI in understanding XML markup languages and autonomously creating structured XML content. Additionally, we will examine the capacity of AI to enrich plain text with appropriate XML markup. Practical examples and methodological guidelines will be provided to elucidate how AI can be effectively prompted to interpret and generate accurate XML markup.
Further emphasis will be placed on the role of AI in developing XSLT, or schemas such as XSD and Schematron. We will address the techniques and strategies adopted to create prompts for generating code, explaining code, or refactoring the code, and the results achieved.
The discussion will extend to how AI can be used to transform XML content. In particular, the focus will be on the use of AI XPath extension functions in XSLT, Schematron, Schematron Quick Fixes, or for XML content refactoring.
The presentation aims to deliver a comprehensive overview of AI usage in XML development, providing attendees with the necessary knowledge to make informed decisions. Whether you’re at the early stages of adopting AI or considering integrating it in advanced XML development, this presentation will cover all levels of expertise.
By highlighting the potential advantages and challenges of integrating AI with XML development tools and languages, the presentation seeks to inspire thoughtful conversation around the future of XML development. We’ll not only delve into the technical aspects of AI-powered XML development but also discuss practical implications and possible future directions.
Introduction of Cybersecurity with OSS at Code Europe 2024Hiroshi SHIBATA
I develop the Ruby programming language, RubyGems, and Bundler, which are package managers for Ruby. Today, I will introduce how to enhance the security of your application using open-source software (OSS) examples from Ruby and RubyGems.
The first topic is CVE (Common Vulnerabilities and Exposures). I have published CVEs many times. But what exactly is a CVE? I'll provide a basic understanding of CVEs and explain how to detect and handle vulnerabilities in OSS.
Next, let's discuss package managers. Package managers play a critical role in the OSS ecosystem. I'll explain how to manage library dependencies in your application.
I'll share insights into how the Ruby and RubyGems core team works to keep our ecosystem safe. By the end of this talk, you'll have a better understanding of how to safeguard your code.
1. 1
Eleanor McHugh
co-founder @ InIdSol
https://inidsol.uk
https://shayk.online
x://@feyeleanor
leanpub://GoNotebook
slideshare://feyeleanor
linkedin://in/eleanormchugh
putting the R! in
R&D
Rough Cut
2. 2
solving puzzles the hard way
Elric sent his mind into twisting tunnels of logic, across
endless plains of ideas, through mountains of symbolism and
endless universes of alternate truths; he sent his mind out
further and further and as it went he sent with it the words
[...] words that few of his contemporaries would
understand...
- Elric of Melniboné, Michael Moorcock
3. 3
solving puzzles the hard way:
the ratio of squares
inscribe a circle inside a square ao
the circle touches the sides at their midpoint
inscribe a square ai inside the circle
its vertices touch the circumference
ai
ao
4. 4
2r
2πr
2r
ai
ao
solving puzzles the hard way:
the ratio of squares
we know a lot about circles
their diameter is twice their radius r
and their circumference is 2πr
5. 5
y
πd
d
x
ai = (2y)2
ao = d2
ai
ao
solving puzzles the hard way:
the ratio of squares
and we know a lot about squares
such as their area being the square of the
length of one side
this allows us to express the areas of the
two squares in terms of d and y
7. 7
y
πd
d
x
ai = 4y2
ao = (2x + 2y)2
ai
ao
solving puzzles the hard way:
the ratio of squares
8. 8
y
πd
d
x
ai = 4y2
ao = 4x2 + 8xy + 4y2
ai
ao
solving puzzles the hard way:
the ratio of squares
9. 9
y
πd
d
x
ai = 4y2
ao = 4x2 + 8xy + 4y2
ai
ao
solving puzzles the hard way:
the ratio of squares
note that the calculation of ao includes ai
which is interesting but not directly helpful in
calculating the ratio of ao to ai
however this still leaves us to figure out both
x and y which isn't particularly useful
10. 10
y
πd
d
x
ai
ao
solving puzzles the hard way:
the ratio of squares
however we can reframe this problem
if we bisect ai along the line formed by
opposing vertices we find that this has
shares the length d - the circle diameter
d
11. 11
y
πd
d
x
h2 = o2 + a2
d2 = (2y)2 + (2y)2
ai
ao
solving puzzles the hard way:
the ratio of squares
and by applying the pythagorean theorem
we can calculate d in terms of y
d
12. 12
y
πd
d
x
h2 = o2 + a2
d2 = 4y2 + 4y2
ai
ao
solving puzzles the hard way:
the ratio of squares
d
13. 13
y
πd
d
x
h2 = o2 + a2
d2 = 8y2
ai
ao
solving puzzles the hard way:
the ratio of squares
d
18. 18
*blink*:
the ratio of squares
algebra is a rational tool that can solve many
problems by brute force
however when you study a problem domain
in depth you start to develop intuitions -
ways of identifying shortcuts to the answer
you're after
ai
ao
d
19. 19
*blink*:
the ratio of squares
algebra is a rational tool that can solve many
problems by brute force
however when you study a problem domain
in depth you start to develop intuitions -
ways of identifying shortcuts to the answer
you're after
ai
ao
d
21. 21
*blink*:
the ratio of squares
we can see that the area of ao must be twice
the area of ai
ao
ai
22. 22
*blink*:
the ratio of squares
a
y
y
d 2 2
Y 6 842
I s d from
d 2 24
g
a
e
12 4 2
84 442
v
using
8112 4 2
84 442
Sino
I 242 42 2 4 42
x 2 4 42 0
Cos
ay
Sino sin450
sin450
tano
Ia
seco
ha I E ai y
coseco
to ay de di 442
14472 242
12 8,2
do de
90 8 2
Sin
II
do
Cos
450
I g 2
tan450 1
sin900 1
Cos
900 0
tango
undefined
25. 25
● for a particle with few
degrees of freedom, its
position x and its
momentum p cannot
both be determined at
the same time
● Schrödinger's cat sums
up the weirdness of this
Uncertain Quanta
Heisenberg
Schrödinger
26. 26
● at the smallest scale
things behave as if
distance doesn't exist
● at the largest scale
nothing can move faster
then the speed of light
● which is more true?
● wormholes!
● time travel!
● (and conspiracies!!!)
Locality & The Real
Bell
Einstein, Rosen, Podolsky
29. 29
● Turing-Church
● robot reads infinite tape
● applies rules that can
overwrite the tape then
moves the tape one
step left or right
● can compute anything
which can be computed
● physical analogue of
the Lambda Calculus
Universal Machines
The input value to be bound
to the argument x
Substitute the value into the body
The body becomes the return value
λ x . x
( ) 2
λ 2 . x
( )
λ 2 . 2
( )
2
Turing
Church
30. 30
● the study of causal
processes and
feedback loops
● these loops regulate or
control the operation of
a system
● feedback can be
positive or negative
● used to steer a system
towards desired goals
Cybernetic Noise
31. 31
● entropy describes the
information contained in
a system
● the higher the entropy,
the more information
that can be contained
● applications in
cryptography and
telecommunications
Information Overload
32. 32
Loose Lips Save Ships
● Bletchley Park GC&CS
● traffic analysis
● Enigma and the Turing
electro-mechanical
bombe
● Lorenz stream cipher
and Colossus, the
world's first electronic
programmable
computer
Flowers
33. 33
● the Memex, an electro-
mechanical platform for
managing deeply
interlinked knowledge
● Project Xanadu a
platform for publishing
hypertext & hypermedia
● WWW adds typesetting
and programmability to
hypertext
Webs of Meaning
Ted Nelson
Berners-Lee
34. 34
● algorithms are tractable
to rigorous analysis
● Big O notation - how
long an algorithm runs
● or how much memory
an algorithm uses
● O(logx n)
● O(nx)
● O(n!)
Beyond the Machine
in programming, simplicity and
clarity ... are not a dispensable luxury,
but a crucial matter that decides
between success and failure
Dijkstra
Knuth
35. 35
● falsifiability as the test
of empirical study
● constructivism - the
pursuit of knowledge is
shaped by social
factors
● the methods of one
paradigm do not
necessarily translate
into another paradigm
All Life is Problem Solving
In so far as a scientific statement speaks about
reality, it must be falsifiable; and in so far as it is
not falsifiable it does not speak about reality
Kuhn
Popper
36. 36
that first deep-dive into insanity
Love is the ghost haunting your head
Love is the killer you thought was your friend
Love is the creature who lives in the dark
Sneaks up, will stick you
And painfully pick you apart
- The Beast, Concrete Blonde
41. 41
● stack-based
● programs compose
word definitions from a
threaded dictionary
● limited type system
● ASM versions are great
for embedded systems
● Open Firmware
● gforth
● Factor (functional)
Forth
42. 5 2 3 56 76 23 65 .s <7> 5 2 3 56 76 23 65 ok
5 4 + . 9 ok
13 2 / . 6 ok
13 2 mod . 1 ok
3 dup - . 0 ok
2 5 swap / . 2 ok
6 4 5 rot .s <3> 4 5 6 ok
4 0 drop 2 / . 2 ok
1 2 3 nip .s <2> 1 3 ok
: square ( n -- n ) dup * ; ok
5 square . 25 ok
see square : square dup * ; ok
42 42 = . -1 ok
12 53 = . 0 ok
: ?>64 dup 64 > if ." More than" else ." Less than" then ." 64!" ; ok
100 ?>64 More than 64! ok
20 ?>64 Less than 64! ok
: squares ( n -- ) 1 do i square loop ; ok
5 squares .s <4> 1 4 9 16 ok
: threes ( n n -- ) ?do i . 3 +loop ; ok
15 0 threes 0 3 6 9 12 ok
0 0 threes ok
variable age ok
21 age ! ok
age @ . 21 ok
age ? 21 ok
100 constant WATER-BOILING-POINT ok
WATER-BOILING-POINT . 100 ok
variable num-array 2 cells allot ok
num-array 3 cells erase ok
num-array 3 cells 0 fill ok
create num-array 64 , 9001 , 1337 , ok
0 cells num-array + ? 64 ok
1 cells num-array + ? 9001 ok
: of-arr ( n n -- n ) cells + ; ok
num-array 2 of-arr ? 1337 ok
20 num-array 1 of-arr ! ok
num-array 1 of-arr ? 20 ok
: i-from-rstack ( -- ) 4 0 do r@ . loop ; ok
i-from-rstack 0 1 2 3 ok
5 6 4 >r swap r> .s 6 5 4 ok
5 6 4 clearstack ok
bye
42
see https://learnxinyminutes.com/docs/forth/
43. 5 2 3 56 76 23 65 .s
<7> 5 2 3 56 76 23 65 ok
5 4 + .
9 ok
13 2 / .
6 ok
13 2 mod .
1 ok
3 dup .s cr - .
<2> 3 3
0 ok
43
44. 2 5 swap .s
<2> 5 2 ok
6 4 5 rot .
<3> 4 5 6 ok
4 0 drop 2 / .
2 ok
1 2 3 nip .s
<2> 1 3 ok
4 5 6 clearstack .s
<0> ok
44
45. : square ( n -- n ) dup * ;
ok
5 square .
25 ok
see square
: square dup * ; ok
45
46. : print-result . cr .s ;
12 42 42 42 = print-result cr = print-result
-1
<2> 12 42
0
<0> ok
: ?>64
dup 64 >
if ." More than"
else ." Less than"
then ." 64!" ;
100 ?>64
More than 64! ok
20 ?>64
Less than 64! ok
46
47. : squares ( n -- ) 1 do i square loop ;
5 .s .cr squares .s
<1> 5
<4> 1 4 9 16 ok
: threes ( n n -- ) ?do i 3 +loop ;
: reverse-stack ( n*x -- n*x') depth 1 do i roll loop ;
: print-stack ( n -- ) depth 0 do . cr loop ;
15 0 threes cr .s cr reverse-stack .s cr print-stack
<5> 0 3 6 9 12 ok
<5> 12 9 6 3 0 ok
0
3
6
9
12
ok
0 0 threes
ok
47
54. 54
● tokenised interpreter
● running on Zilog Z80
● unstructured code with
GOTO and GOSUB
● no UDTs
● simple line editor
● painfully slow execution
● if you can code in this
you can probably code
in anything
Locomotive BASIC
55. 1 REM ******************
2 REM * Amstrad Forth *
3 REM * by *
4 REM * Stephen Devine *
5 REM ******************
6 REM
10 REM (c) Computing with the Amstrad
100 REM Initialisation
110 MODE 2:BORDER 13:INK 1,0:INK 0,13
120 forth$=CHR$(12)+"Fred Forth V1.1"
130 OPENOUT "dummy":MEMORY HIMEM-1:CLOSEOUT
140 temp=0:DEFINT a-z
150 DIM w$(130),p(130),beg(40),ff(40),df(40),loop(40),ll(40),li(40)
160 er$(0)="OK":er$(1)="Stack Underflow":er$(2)="Empty Stack"
170 er$(3)=" already defined":er$(4)=" - Illegal variable name":er$(5)=" - Bad Word":er$(6)="Stack
Full":er$(7)="Return Stack Full"
180 spmax=100:DIM s(spmax):sp=-1
190 cvn=58:DIM cvoc$(cvn),dsp(cvn,1)
200 FOR i=0 TO cvn:READ cvoc$(i),dsp(i,0),dsp(i,1):NEXT
210 cvoc$(5)="."+CHR$(34)
220 umax=100:vmax=100:DIM uvoc$(umax),uvex$(umax),var$(vmax),var(vmax)
230 uvn=-1:vrn=-1:PRINT forth$:PRINT:PRINT er$(0)
240 ON ERROR GOTO 2530
250 REM Input Commands
260 w$="":er=0:LINE INPUT ln$:IF ln$="" THEN 690 ELSE IF LEN(ln$)>240 THEN PRINT"Line too
long":GOTO 260
270 WHILE ASC(ln$)=32:IF LEN(ln$)>1 THEN ln$=RIGHT$(ln$,LEN(ln$)-1):WEND ELSE 690
280 WHILE RIGHT$(ln$,1)=CHR$(32):ln$=LEFT$(ln$,LEN(ln$)-1):WEND
290 ln$=UPPER$(ln$):IF ASC(ln$)=ASC("*") THEN IF LEN(ln$)>1 AND LEFT$(ln$,2)<>"* " THEN GOSUB
1700:IF er THEN 260 ELSE w$="":G$
300 ln$=ln$+CHR$(32):x$="":q=1:wn=-1:comp=0
310 WHILE q<LEN(ln$)
320 p=q:WHILE MID$(ln$,q,1)<>" ":q=q+1:WEND
330 w$=MID$(ln$,p,q-p):IF w$=":" THEN IF wn=-1 AND RIGHT$(ln$,2)="; " THEN comp=-1:GOTO 640 ELSE
PRINT"Bad definition":GOTO 260
340 FOR i=cvn TO 0 STEP-1:IF cvoc$(i)<>w$ THEN NEXT:GOTO 400
350 IF comp THEN IF wn=0 THEN er=3:GOTO 690
360 IF wn>=0 THEN IF w$(wn)="VARIABLE" THEN er=4:GOTO 690
370 x$=x$+CHR$(0)+CHR$(i+14):IF w$<>"."+CHR$(34) THEN 640
55
https://www.cpcwiki.eu/index.php/CWTA_Issue_17_-_May_1986_-_Type-Ins
Used under Fair Use for purpose of review and critique
56. 56
1 REM ******************
2 REM * Amstrad Forth *
3 REM * by *
4 REM * Stephen Devine *
5 REM ******************
6 REM
10 REM (c) Computing with the Amstrad
100 REM Initialisation
250 REM Input Commands
680 REM Error Routine
710 REM Compile New Word
750 REM Execute Commands
1080 REM Command List
1690 REM Process Editing Commands
2540 REM Data for Core Words
Outer Interpreter (tokeniser & parser)
Word Compiler (adds entry to dictionary)
Inner Interpreter (invoke entries from dictionary)
Implemented Primitives
Implementation extension words
Primitive tokens and stack behaviour
57. 57
100 REM Initialisation
110 MODE 2:BORDER 13:INK 1,0:INK 0,13
120 forth$=CHR$(12)+"Fred Forth V1.1"
130 OPENOUT "dummy":MEMORY HIMEM-1:CLOSEOUT
140 temp=0:DEFINT a-z
150 DIM w$(130),p(130),beg(40),ff(40),df(40),loop(40),ll(40),li(40)
160 er$(0)="OK":er$(1)="Stack Underflow":er$(2)="Empty Stack"
170 er$(3)=" already defined":er$(4)=" - Illegal variable name":er$(5)=" - Bad Word":er$(6)="Stack
Full":er$(7)="Return Stack Full"
180 spmax=100:DIM s(spmax):sp=-1
190 cvn=58:DIM cvoc$(cvn),dsp(cvn,1)
200 FOR i=0 TO cvn:READ cvoc$(i),dsp(i,0),dsp(i,1):NEXT
210 cvoc$(5)="."+CHR$(34)
220 umax=100:vmax=100:DIM uvoc$(umax),uvex$(umax),var$(vmax),var(vmax)
230 uvn=-1:vrn=-1:PRINT forth$:PRINT:PRINT er$(0)
240 ON ERROR GOTO 2530
2530 er=6:IF sp>100 THEN sp=100:RESUME NEXT ELSE w$="":RESUME 690
2540 REM Data for Core Words
2550 DATA "!",2,-2,"*",2,-1,"+",2,-1,"-",2,-1,".",0,-1,"?",0,0,"/",2,-1,"/
MOD",2,0,"0<",1,0,"0=",1,0,"<",2,-1
2560 DATA
"=",2,-1,">",2,-1,"?",1,-1,"@",1,0,"ABS",1,0,"AND",2,-1,"C@",1,0,"CR",0,0,"DROP",1,-1,"DUP",1,1
2570 DATA "EMIT",1,-1,"KEY",0,1,"MAX",2,-1,"MIN",2,-1,"MINUS",1,0,"MOD",2,-1,"OR",2,-1,"OVER",2,1
2580 DATA "SPACE",0,0,"SPACES",1,-1,"SWAP",2,0,"VARIABLE",1,-1,"XOR",2,-1,"BEGIN",0,0,"UNTIL",1,-1
2590 DATA
"WHILE",1,-1,"REPEAT",0,0,"IF",1,-1,"THEN",0,0,"ELSE",0,0,"FORTH",0,0,"CLEAR",0,0,"ROT",3,0,"DO",2,
-2,"LOOP",0,0,"I",0,+1
2600 REM Data for Amstrad Words
2610 DATA "CLG",1,-1,"DRAW",2,-2,"DRAWR",2,-2,"FRE",0,1,"MOVE",2,-2,"MOVER",2,-2
2620 DATA "PLOT",2,-2,"PLOTR",2,-2,"RND",0,1,"TEST",2,-1,"TESTR",2,-1,"GRAPEN",1,-1
58. 58
100 REM Initialisation
110 MODE 2:BORDER 13:INK 1,0:INK 0,13
120 forth$=CHR$(12)+"Fred Forth V1.1"
130 OPENOUT "dummy":MEMORY HIMEM-1:CLOSEOUT
140 temp=0:DEFINT a-z
150 DIM w$(130),p(130),beg(40),ff(40),df(40),loop(40),ll(40),li(40)
160 er$(0)="OK":er$(1)="Stack Underflow":er$(2)="Empty Stack"
170 er$(3)=" already defined":er$(4)=" - Illegal variable name":er$(5)=" - Bad Word":er$(6)="Stack
Full":er$(7)="Return Stack Full"
180 spmax=100:DIM s(spmax):sp=-1
190 cvn=58:DIM cvoc$(cvn),dsp(cvn,1)
200 FOR i=0 TO cvn:READ cvoc$(i),dsp(i,0),dsp(i,1):NEXT
210 cvoc$(5)="."+CHR$(34)
220 umax=100:vmax=100:DIM uvoc$(umax),uvex$(umax),var$(vmax),var(vmax)
230 uvn=-1:vrn=-1:PRINT forth$:PRINT:PRINT er$(0)
240 ON ERROR GOTO 2530
2530 er=6:IF sp>100 THEN sp=100:RESUME NEXT ELSE w$="":RESUME 690
2540 REM Data for Core Words
2550 DATA "!",2,-2,"*",2,-1,"+",2,-1,"-",2,-1,".",0,-1,"?",0,0,"/",2,-1,"/
MOD",2,0,"0<",1,0,"0=",1,0,"<",2,-1
2560 DATA
"=",2,-1,">",2,-1,"?",1,-1,"@",1,0,"ABS",1,0,"AND",2,-1,"C@",1,0,"CR",0,0,"DROP",1,-1,"DUP",1,1
2570 DATA "EMIT",1,-1,"KEY",0,1,"MAX",2,-1,"MIN",2,-1,"MINUS",1,0,"MOD",2,-1,"OR",2,-1,"OVER",2,1
2580 DATA "SPACE",0,0,"SPACES",1,-1,"SWAP",2,0,"VARIABLE",1,-1,"XOR",2,-1,"BEGIN",0,0,"UNTIL",1,-1
2590 DATA
"WHILE",1,-1,"REPEAT",0,0,"IF",1,-1,"THEN",0,0,"ELSE",0,0,"FORTH",0,0,"CLEAR",0,0,"ROT",3,0,"DO",2,
-2,"LOOP",0,0,"I",0,+1
2600 REM Data for Amstrad Words
2610 DATA "CLG",1,-1,"DRAW",2,-2,"DRAWR",2,-2,"FRE",0,1,"MOVE",2,-2,"MOVER",2,-2
2620 DATA "PLOT",2,-2,"PLOTR",2,-2,"RND",0,1,"TEST",2,-1,"TESTR",2,-1,"GRAPEN",1,-1
59. 59
100 REM Initialisation
110 MODE 2:BORDER 13:INK 1,0:INK 0,13
120 forth$=CHR$(12)+"Fred Forth V1.1"
130 OPENOUT "dummy":MEMORY HIMEM-1:CLOSEOUT
140 temp=0:DEFINT a-z
150 DIM w$(130),p(130),beg(40),ff(40),df(40),loop(40),ll(40),li(40)
160 er$(0)="OK":er$(1)="Stack Underflow":er$(2)="Empty Stack"
170 er$(3)=" already defined":er$(4)=" - Illegal variable name":er$(5)=" - Bad Word":er$(6)="Stack
Full":er$(7)="Return Stack Full"
180 spmax=100:DIM s(spmax):sp=-1
190 cvn=58:DIM cvoc$(cvn),dsp(cvn,1)
200 FOR i=0 TO cvn:READ cvoc$(i),dsp(i,0),dsp(i,1):NEXT
210 cvoc$(5)="."+CHR$(34)
220 umax=100:vmax=100:DIM uvoc$(umax),uvex$(umax),var$(vmax),var(vmax)
230 uvn=-1:vrn=-1:PRINT forth$:PRINT:PRINT er$(0)
240 ON ERROR GOTO 2530
2530 er=6:IF sp>100 THEN sp=100:RESUME NEXT ELSE w$="":RESUME 690
2540 REM Data for Core Words
2550 DATA "!",2,-2,"*",2,-1,"+",2,-1,"-",2,-1,".",0,-1,"?",0,0,"/",2,-1,"/
MOD",2,0,"0<",1,0,"0=",1,0,"<",2,-1
2560 DATA
"=",2,-1,">",2,-1,"?",1,-1,"@",1,0,"ABS",1,0,"AND",2,-1,"C@",1,0,"CR",0,0,"DROP",1,-1,"DUP",1,1
2570 DATA "EMIT",1,-1,"KEY",0,1,"MAX",2,-1,"MIN",2,-1,"MINUS",1,0,"MOD",2,-1,"OR",2,-1,"OVER",2,1
2580 DATA "SPACE",0,0,"SPACES",1,-1,"SWAP",2,0,"VARIABLE",1,-1,"XOR",2,-1,"BEGIN",0,0,"UNTIL",1,-1
2590 DATA
"WHILE",1,-1,"REPEAT",0,0,"IF",1,-1,"THEN",0,0,"ELSE",0,0,"FORTH",0,0,"CLEAR",0,0,"ROT",3,0,"DO",2,
-2,"LOOP",0,0,"I",0,+1
2600 REM Data for Amstrad Words
2610 DATA "CLG",1,-1,"DRAW",2,-2,"DRAWR",2,-2,"FRE",0,1,"MOVE",2,-2,"MOVER",2,-2
2620 DATA "PLOT",2,-2,"PLOTR",2,-2,"RND",0,1,"TEST",2,-1,"TESTR",2,-1,"GRAPEN",1,-1
60. 60
100 REM Initialisation
110 MODE 2:BORDER 13:INK 1,0:INK 0,13
120 forth$=CHR$(12)+"Fred Forth V1.1"
130 OPENOUT "dummy":MEMORY HIMEM-1:CLOSEOUT
140 temp=0:DEFINT a-z
150 DIM w$(130),p(130),beg(40),ff(40),df(40),loop(40),ll(40),li(40)
160 er$(0)="OK":er$(1)="Stack Underflow":er$(2)="Empty Stack"
170 er$(3)=" already defined":er$(4)=" - Illegal variable name":er$(5)=" - Bad Word":er$(6)="Stack
Full":er$(7)="Return Stack Full"
180 spmax=100:DIM s(spmax):sp=-1
190 cvn=58:DIM cvoc$(cvn),dsp(cvn,1)
200 FOR i=0 TO cvn:READ cvoc$(i),dsp(i,0),dsp(i,1):NEXT
210 cvoc$(5)="."+CHR$(34)
220 umax=100:vmax=100:DIM uvoc$(umax),uvex$(umax),var$(vmax),var(vmax)
230 uvn=-1:vrn=-1:PRINT forth$:PRINT:PRINT er$(0)
240 ON ERROR GOTO 2530
2530 er=6:IF sp>100 THEN sp=100:RESUME NEXT ELSE w$="":RESUME 690
2540 REM Data for Core Words
2550 DATA "!",2,-2,"*",2,-1,"+",2,-1,"-",2,-1,".",0,-1,"?",0,0,"/",2,-1,"/
MOD",2,0,"0<",1,0,"0=",1,0,"<",2,-1
2560 DATA
"=",2,-1,">",2,-1,"?",1,-1,"@",1,0,"ABS",1,0,"AND",2,-1,"C@",1,0,"CR",0,0,"DROP",1,-1,"DUP",1,1
2570 DATA "EMIT",1,-1,"KEY",0,1,"MAX",2,-1,"MIN",2,-1,"MINUS",1,0,"MOD",2,-1,"OR",2,-1,"OVER",2,1
2580 DATA "SPACE",0,0,"SPACES",1,-1,"SWAP",2,0,"VARIABLE",1,-1,"XOR",2,-1,"BEGIN",0,0,"UNTIL",1,-1
2590 DATA
"WHILE",1,-1,"REPEAT",0,0,"IF",1,-1,"THEN",0,0,"ELSE",0,0,"FORTH",0,0,"CLEAR",0,0,"ROT",3,0,"DO",2,
-2,"LOOP",0,0,"I",0,+1
2600 REM Data for Amstrad Words
2610 DATA "CLG",1,-1,"DRAW",2,-2,"DRAWR",2,-2,"FRE",0,1,"MOVE",2,-2,"MOVER",2,-2
2620 DATA "PLOT",2,-2,"PLOTR",2,-2,"RND",0,1,"TEST",2,-1,"TESTR",2,-1,"GRAPEN",1,-1
61. 61
100 REM Initialisation
110 MODE 2:BORDER 13:INK 1,0:INK 0,13
120 forth$=CHR$(12)+"Fred Forth V1.1"
130 OPENOUT "dummy":MEMORY HIMEM-1:CLOSEOUT
140 temp=0:DEFINT a-z
150 DIM w$(130),p(130),beg(40),ff(40),df(40),loop(40),ll(40),li(40)
160 er$(0)="OK":er$(1)="Stack Underflow":er$(2)="Empty Stack"
170 er$(3)=" already defined":er$(4)=" - Illegal variable name":er$(5)=" - Bad Word":er$(6)="Stack
Full":er$(7)="Return Stack Full"
180 spmax=100:DIM s(spmax):sp=-1
190 cvn=58:DIM cvoc$(cvn),dsp(cvn,1)
200 FOR i=0 TO cvn:READ cvoc$(i),dsp(i,0),dsp(i,1):NEXT
210 cvoc$(5)="."+CHR$(34)
220 umax=100:vmax=100:DIM uvoc$(umax),uvex$(umax),var$(vmax),var(vmax)
230 uvn=-1:vrn=-1:PRINT forth$:PRINT:PRINT er$(0)
240 ON ERROR GOTO 2530
2530 er=6:IF sp>100 THEN sp=100:RESUME NEXT ELSE w$="":RESUME 690
2540 REM Data for Core Words
2550 DATA "!",2,-2,"*",2,-1,"+",2,-1,"-",2,-1,".",0,-1,"?",0,0,"/",2,-1,"/
MOD",2,0,"0<",1,0,"0=",1,0,"<",2,-1
2560 DATA
"=",2,-1,">",2,-1,"?",1,-1,"@",1,0,"ABS",1,0,"AND",2,-1,"C@",1,0,"CR",0,0,"DROP",1,-1,"DUP",1,1
2570 DATA "EMIT",1,-1,"KEY",0,1,"MAX",2,-1,"MIN",2,-1,"MINUS",1,0,"MOD",2,-1,"OR",2,-1,"OVER",2,1
2580 DATA "SPACE",0,0,"SPACES",1,-1,"SWAP",2,0,"VARIABLE",1,-1,"XOR",2,-1,"BEGIN",0,0,"UNTIL",1,-1
2590 DATA
"WHILE",1,-1,"REPEAT",0,0,"IF",1,-1,"THEN",0,0,"ELSE",0,0,"FORTH",0,0,"CLEAR",0,0,"ROT",3,0,"DO",2,
-2,"LOOP",0,0,"I",0,+1
2600 REM Data for Amstrad Words
2610 DATA "CLG",1,-1,"DRAW",2,-2,"DRAWR",2,-2,"FRE",0,1,"MOVE",2,-2,"MOVER",2,-2
2620 DATA "PLOT",2,-2,"PLOTR",2,-2,"RND",0,1,"TEST",2,-1,"TESTR",2,-1,"GRAPEN",1,-1
62. 62
100 REM Initialisation
110 MODE 2:BORDER 13:INK 1,0:INK 0,13
120 forth$=CHR$(12)+"Fred Forth V1.1"
130 OPENOUT "dummy":MEMORY HIMEM-1:CLOSEOUT
140 temp=0:DEFINT a-z
150 DIM w$(130),p(130),beg(40),ff(40),df(40),loop(40),ll(40),li(40)
160 er$(0)="OK":er$(1)="Stack Underflow":er$(2)="Empty Stack"
170 er$(3)=" already defined":er$(4)=" - Illegal variable name":er$(5)=" - Bad Word":er$(6)="Stack
Full":er$(7)="Return Stack Full"
180 spmax=100:DIM s(spmax):sp=-1
190 cvn=58:DIM cvoc$(cvn),dsp(cvn,1)
200 FOR i=0 TO cvn:READ cvoc$(i),dsp(i,0),dsp(i,1):NEXT
210 cvoc$(5)="."+CHR$(34)
220 umax=100:vmax=100:DIM uvoc$(umax),uvex$(umax),var$(vmax),var(vmax)
230 uvn=-1:vrn=-1:PRINT forth$:PRINT:PRINT er$(0)
240 ON ERROR GOTO 2530
2530 er=6:IF sp>100 THEN sp=100:RESUME NEXT ELSE w$="":RESUME 690
2540 REM Data for Core Words
2550 DATA "!",2,-2,"*",2,-1,"+",2,-1,"-",2,-1,".",0,-1,"?",0,0,"/",2,-1,"/
MOD",2,0,"0<",1,0,"0=",1,0,"<",2,-1
2560 DATA
"=",2,-1,">",2,-1,"?",1,-1,"@",1,0,"ABS",1,0,"AND",2,-1,"C@",1,0,"CR",0,0,"DROP",1,-1,"DUP",1,1
2570 DATA "EMIT",1,-1,"KEY",0,1,"MAX",2,-1,"MIN",2,-1,"MINUS",1,0,"MOD",2,-1,"OR",2,-1,"OVER",2,1
2580 DATA "SPACE",0,0,"SPACES",1,-1,"SWAP",2,0,"VARIABLE",1,-1,"XOR",2,-1,"BEGIN",0,0,"UNTIL",1,-1
2590 DATA
"WHILE",1,-1,"REPEAT",0,0,"IF",1,-1,"THEN",0,0,"ELSE",0,0,"FORTH",0,0,"CLEAR",0,0,"ROT",3,0,"DO",2,
-2,"LOOP",0,0,"I",0,+1
2600 REM Data for Amstrad Words
2610 DATA "CLG",1,-1,"DRAW",2,-2,"DRAWR",2,-2,"FRE",0,1,"MOVE",2,-2,"MOVER",2,-2
2620 DATA "PLOT",2,-2,"PLOTR",2,-2,"RND",0,1,"TEST",2,-1,"TESTR",2,-1,"GRAPEN",1,-1
63. 63
100 REM Initialisation
110 MODE 2:BORDER 13:INK 1,0:INK 0,13
120 forth$=CHR$(12)+"Fred Forth V1.1"
130 OPENOUT "dummy":MEMORY HIMEM-1:CLOSEOUT
140 temp=0:DEFINT a-z
150 DIM w$(130),p(130),beg(40),ff(40),df(40),loop(40),ll(40),li(40)
160 er$(0)="OK":er$(1)="Stack Underflow":er$(2)="Empty Stack"
170 er$(3)=" already defined":er$(4)=" - Illegal variable name":er$(5)=" - Bad Word":er$(6)="Stack
Full":er$(7)="Return Stack Full"
180 spmax=100:DIM s(spmax):sp=-1
190 cvn=58:DIM cvoc$(cvn),dsp(cvn,1)
200 FOR i=0 TO cvn:READ cvoc$(i),dsp(i,0),dsp(i,1):NEXT
210 cvoc$(5)="."+CHR$(34)
220 umax=100:vmax=100:DIM uvoc$(umax),uvex$(umax),var$(vmax),var(vmax)
230 uvn=-1:vrn=-1:PRINT forth$:PRINT:PRINT er$(0)
240 ON ERROR GOTO 2530
2530 er=6:IF sp>100 THEN sp=100:RESUME NEXT ELSE w$="":RESUME 690
2540 REM Data for Core Words
2550 DATA "!",2,-2,"*",2,-1,"+",2,-1,"-",2,-1,".",0,-1,"?",0,0,"/",2,-1,"/
MOD",2,0,"0<",1,0,"0=",1,0,"<",2,-1
2560 DATA
"=",2,-1,">",2,-1,"?",1,-1,"@",1,0,"ABS",1,0,"AND",2,-1,"C@",1,0,"CR",0,0,"DROP",1,-1,"DUP",1,1
2570 DATA "EMIT",1,-1,"KEY",0,1,"MAX",2,-1,"MIN",2,-1,"MINUS",1,0,"MOD",2,-1,"OR",2,-1,"OVER",2,1
2580 DATA "SPACE",0,0,"SPACES",1,-1,"SWAP",2,0,"VARIABLE",1,-1,"XOR",2,-1,"BEGIN",0,0,"UNTIL",1,-1
2590 DATA
"WHILE",1,-1,"REPEAT",0,0,"IF",1,-1,"THEN",0,0,"ELSE",0,0,"FORTH",0,0,"CLEAR",0,0,"ROT",3,0,"DO",2,
-2,"LOOP",0,0,"I",0,+1
2600 REM Data for Amstrad Words
2610 DATA "CLG",1,-1,"DRAW",2,-2,"DRAWR",2,-2,"FRE",0,1,"MOVE",2,-2,"MOVER",2,-2
2620 DATA "PLOT",2,-2,"PLOTR",2,-2,"RND",0,1,"TEST",2,-1,"TESTR",2,-1,"GRAPEN",1,-1
64. 64
100 REM Initialisation
110 MODE 2:BORDER 13:INK 1,0:INK 0,13
120 forth$=CHR$(12)+"Fred Forth V1.1"
130 OPENOUT "dummy":MEMORY HIMEM-1:CLOSEOUT
140 temp=0:DEFINT a-z
150 DIM w$(130),p(130),beg(40),ff(40),df(40),loop(40),ll(40),li(40)
160 er$(0)="OK":er$(1)="Stack Underflow":er$(2)="Empty Stack"
170 er$(3)=" already defined":er$(4)=" - Illegal variable name":er$(5)=" - Bad Word":er$(6)="Stack
Full":er$(7)="Return Stack Full"
180 spmax=100:DIM s(spmax):sp=-1
190 cvn=58:DIM cvoc$(cvn),dsp(cvn,1)
200 FOR i=0 TO cvn:READ cvoc$(i),dsp(i,0),dsp(i,1):NEXT
210 cvoc$(5)="."+CHR$(34)
220 umax=100:vmax=100:DIM uvoc$(umax),uvex$(umax),var$(vmax),var(vmax)
230 uvn=-1:vrn=-1:PRINT forth$:PRINT:PRINT er$(0)
240 ON ERROR GOTO 2530
2530 er=6:IF sp>100 THEN sp=100:RESUME NEXT ELSE w$="":RESUME 690
2540 REM Data for Core Words
2550 DATA "!",2,-2,"*",2,-1,"+",2,-1,"-",2,-1,".",0,-1,"?",0,0,"/",2,-1,"/
MOD",2,0,"0<",1,0,"0=",1,0,"<",2,-1
2560 DATA
"=",2,-1,">",2,-1,"?",1,-1,"@",1,0,"ABS",1,0,"AND",2,-1,"C@",1,0,"CR",0,0,"DROP",1,-1,"DUP",1,1
2570 DATA "EMIT",1,-1,"KEY",0,1,"MAX",2,-1,"MIN",2,-1,"MINUS",1,0,"MOD",2,-1,"OR",2,-1,"OVER",2,1
2580 DATA "SPACE",0,0,"SPACES",1,-1,"SWAP",2,0,"VARIABLE",1,-1,"XOR",2,-1,"BEGIN",0,0,"UNTIL",1,-1
2590 DATA
"WHILE",1,-1,"REPEAT",0,0,"IF",1,-1,"THEN",0,0,"ELSE",0,0,"FORTH",0,0,"CLEAR",0,0,"ROT",3,0,"DO",2,
-2,"LOOP",0,0,"I",0,+1
2600 REM Data for Amstrad Words
2610 DATA "CLG",1,-1,"DRAW",2,-2,"DRAWR",2,-2,"FRE",0,1,"MOVE",2,-2,"MOVER",2,-2
2620 DATA "PLOT",2,-2,"PLOTR",2,-2,"RND",0,1,"TEST",2,-1,"TESTR",2,-1,"GRAPEN",1,-1
65. 65
100 REM Initialisation
110 MODE 2:BORDER 13:INK 1,0:INK 0,13
120 forth$=CHR$(12)+"Fred Forth V1.1"
130 OPENOUT "dummy":MEMORY HIMEM-1:CLOSEOUT
140 temp=0:DEFINT a-z
150 DIM w$(130),p(130),beg(40),ff(40),df(40),loop(40),ll(40),li(40)
160 er$(0)="OK":er$(1)="Stack Underflow":er$(2)="Empty Stack"
170 er$(3)=" already defined":er$(4)=" - Illegal variable name":er$(5)=" - Bad Word":er$(6)="Stack
Full":er$(7)="Return Stack Full"
180 spmax=100:DIM s(spmax):sp=-1
190 cvn=58:DIM cvoc$(cvn),dsp(cvn,1)
200 FOR i=0 TO cvn:READ cvoc$(i),dsp(i,0),dsp(i,1):NEXT
210 cvoc$(5)="."+CHR$(34)
220 umax=100:vmax=100:DIM uvoc$(umax),uvex$(umax),var$(vmax),var(vmax)
230 uvn=-1:vrn=-1:PRINT forth$:PRINT:PRINT er$(0)
240 ON ERROR GOTO 2530
2530 er=6:IF sp>100 THEN sp=100:RESUME NEXT ELSE w$="":RESUME 690
2540 REM Data for Core Words
2550 DATA "!",2,-2,"*",2,-1,"+",2,-1,"-",2,-1,".",0,-1,"?",0,0,"/",2,-1,"/
MOD",2,0,"0<",1,0,"0=",1,0,"<",2,-1
2560 DATA
"=",2,-1,">",2,-1,"?",1,-1,"@",1,0,"ABS",1,0,"AND",2,-1,"C@",1,0,"CR",0,0,"DROP",1,-1,"DUP",1,1
2570 DATA "EMIT",1,-1,"KEY",0,1,"MAX",2,-1,"MIN",2,-1,"MINUS",1,0,"MOD",2,-1,"OR",2,-1,"OVER",2,1
2580 DATA "SPACE",0,0,"SPACES",1,-1,"SWAP",2,0,"VARIABLE",1,-1,"XOR",2,-1,"BEGIN",0,0,"UNTIL",1,-1
2590 DATA
"WHILE",1,-1,"REPEAT",0,0,"IF",1,-1,"THEN",0,0,"ELSE",0,0,"FORTH",0,0,"CLEAR",0,0,"ROT",3,0,"DO",2,
-2,"LOOP",0,0,"I",0,+1
2600 REM Data for Amstrad Words
2610 DATA "CLG",1,-1,"DRAW",2,-2,"DRAWR",2,-2,"FRE",0,1,"MOVE",2,-2,"MOVER",2,-2
2620 DATA "PLOT",2,-2,"PLOTR",2,-2,"RND",0,1,"TEST",2,-1,"TESTR",2,-1,"GRAPEN",1,-1
66. 66
100 REM Initialisation
110 MODE 2:BORDER 13:INK 1,0:INK 0,13
120 forth$=CHR$(12)+"Fred Forth V1.1"
130 OPENOUT "dummy":MEMORY HIMEM-1:CLOSEOUT
140 temp=0:DEFINT a-z
150 DIM w$(130),p(130),beg(40),ff(40),df(40),loop(40),ll(40),li(40)
160 er$(0)="OK":er$(1)="Stack Underflow":er$(2)="Empty Stack"
170 er$(3)=" already defined":er$(4)=" - Illegal variable name":er$(5)=" - Bad Word":er$(6)="Stack
Full":er$(7)="Return Stack Full"
180 spmax=100:DIM s(spmax):sp=-1
190 cvn=58:DIM cvoc$(cvn),dsp(cvn,1)
200 FOR i=0 TO cvn:READ cvoc$(i),dsp(i,0),dsp(i,1):NEXT
210 cvoc$(5)="."+CHR$(34)
220 umax=100:vmax=100:DIM uvoc$(umax),uvex$(umax),var$(vmax),var(vmax)
230 uvn=-1:vrn=-1:PRINT forth$:PRINT:PRINT er$(0)
240 ON ERROR GOTO 2530
2530 er=6:IF sp>100 THEN sp=100:RESUME NEXT ELSE w$="":RESUME 690
2540 REM Data for Core Words
2550 DATA "!",2,-2,"*",2,-1,"+",2,-1,"-",2,-1,".",0,-1,"?",0,0,"/",2,-1,"/
MOD",2,0,"0<",1,0,"0=",1,0,"<",2,-1
2560 DATA
"=",2,-1,">",2,-1,"?",1,-1,"@",1,0,"ABS",1,0,"AND",2,-1,"C@",1,0,"CR",0,0,"DROP",1,-1,"DUP",1,1
2570 DATA "EMIT",1,-1,"KEY",0,1,"MAX",2,-1,"MIN",2,-1,"MINUS",1,0,"MOD",2,-1,"OR",2,-1,"OVER",2,1
2580 DATA "SPACE",0,0,"SPACES",1,-1,"SWAP",2,0,"VARIABLE",1,-1,"XOR",2,-1,"BEGIN",0,0,"UNTIL",1,-1
2590 DATA
"WHILE",1,-1,"REPEAT",0,0,"IF",1,-1,"THEN",0,0,"ELSE",0,0,"FORTH",0,0,"CLEAR",0,0,"ROT",3,0,"DO",2,
-2,"LOOP",0,0,"I",0,+1
2600 REM Data for Amstrad Words
2610 DATA "CLG",1,-1,"DRAW",2,-2,"DRAWR",2,-2,"FRE",0,1,"MOVE",2,-2,"MOVER",2,-2
2620 DATA "PLOT",2,-2,"PLOTR",2,-2,"RND",0,1,"TEST",2,-1,"TESTR",2,-1,"GRAPEN",1,-1
68. 68
250 REM Input Commands
260 w$="":er=0:LINE INPUT ln$:IF ln$="" THEN 690 ELSE IF LEN(ln$)>240 THEN PRINT"Line too
long":GOTO 260
270 WHILE ASC(ln$)=32:IF LEN(ln$)>1 THEN ln$=RIGHT$(ln$,LEN(ln$)-1):WEND ELSE 690
280 WHILE RIGHT$(ln$,1)=CHR$(32):ln$=LEFT$(ln$,LEN(ln$)-1):WEND
290 ln$=UPPER$(ln$):IF ASC(ln$)=ASC("*") THEN IF LEN(ln$)>1 AND LEFT$(ln$,2)<>"* " THEN GOSUB
1700:IF er THEN 260 ELSE w$="":GOTO 690
300 ln$=ln$+CHR$(32):x$="":q=1:wn=-1:comp=0
310 WHILE q<LEN(ln$)
320 p=q:WHILE MID$(ln$,q,1)<>" ":q=q+1:WEND
330 w$=MID$(ln$,p,q-p):IF w$=":" THEN IF wn=-1 AND RIGHT$(ln$,2)="; " THEN comp=-1:GOTO 640 ELSE
PRINT"Bad definition":GOTO 260
340 FOR i=cvn TO 0 STEP-1:IF cvoc$(i)<>w$ THEN NEXT:GOTO 400
680 REM Error Routine
690 IF POS(#0)>1 THEN PRINT CHR$(32);
700 PRINT w$;er$(er):GOTO 260
69. 69
270 WHILE ASC(ln$)=32:IF LEN(ln$)>1 THEN ln$=RIGHT$(ln$,LEN(ln$)-1):WEND ELSE 690
280 WHILE RIGHT$(ln$,1)=CHR$(32):ln$=LEFT$(ln$,LEN(ln$)-1):WEND
290 ln$=UPPER$(ln$):IF ASC(ln$)=ASC("*") THEN IF LEN(ln$)>1 AND LEFT$(ln$,2)<>"* " THEN GOSUB
1700:IF er THEN 260 ELSE w$="":GOTO 690
300 ln$=ln$+CHR$(32):x$="":q=1:wn=-1:comp=0
310 WHILE q<LEN(ln$)
320 p=q:WHILE MID$(ln$,q,1)<>" ":q=q+1:WEND
330 w$=MID$(ln$,p,q-p):IF w$=":" THEN IF wn=-1 AND RIGHT$(ln$,2)="; " THEN comp=-1:GOTO 640 ELSE
PRINT"Bad definition":GOTO 260
340 FOR i=cvn TO 0 STEP-1:IF cvoc$(i)<>w$ THEN NEXT:GOTO 400
350 IF comp THEN IF wn=0 THEN er=3:GOTO 690
360 IF wn>=0 THEN IF w$(wn)="VARIABLE" THEN er=4:GOTO 690
370 x$=x$+CHR$(0)+CHR$(i+14):IF w$<>"."+CHR$(34) THEN 640
380 te=INSTR(q,ln$,CHR$(34)+CHR$(32)):IF te=0 THEN PRINT".";CHR$(34);" without ";CHR$(34):GOTO 260
390 x$=x$+MID$(ln$,q+1,te-q-1)+CHR$(4):q=te+1:GOTO 640
400 FOR i=uvn TO 0 STEP-1:IF uvoc$(i)<>w$ THEN NEXT:GOTO 440
410 IF comp THEN IF wn=0 THEN er=3:GOTO 690
420 IF wn>=0 THEN IF w$(wn)="VARIABLE" THEN er=4:GOTO 690
430 x$=x$+CHR$(1)+CHR$(i+14):GOTO 640
440 FOR i=vrn TO 0 STEP-1:IF var$(i)<>w$ THEN NEXT:GOTO 480
450 IF comp THEN IF wn=0 THEN er=3:GOTO 690
460 IF wn>=0 THEN IF w$(wn)="VARIABLE" THEN er=3:GOTO 690
470 x$=x$+CHR$(2)+CHR$(i+14):GOTO 640
480 FOR i=1 TO LEN(w$)
490 IF i=1 AND (ASC(w$)=ASC("+") OR ASC(w$)=ASC("-")) AND LEN(w$)>1 THEN 510
500 IF MID$(w$,i,1)<"0" OR MID$(w$,i,1)>"9" THEN 560
510 NEXT i
520 IF comp AND wn=0 THEN er=5:GOTO 690
530 IF wn>=0 THEN IF w$(wn)="VARIABLE" THEN er=5:GOTO 690
540 IF VAL(w$)>32767 OR VAL(w$)<-32767 THEN PRINT"Number ";w$;" too large":GOTO 260
550 x$=x$+CHR$(3)+w$+CHR$(4):GOTO 640
560 IF wn<0 THEN 590 ELSE IF w$(wn)<>"VARIABLE" THEN 590
570 IF comp AND w$=w$(1) THEN er=3:GOTO 690
580 x$=x$+w$+CHR$(4):GOTO 640
590 IF w$<>";" THEN 610
600 IF comp=0 OR q<>LEN(ln$) THEN PRINT"Illegal semi-colon":GOTO 260 ELSE 640
610 IF comp THEN IF wn=0 THEN 640
620 IF comp THEN IF w$<>w$(1) THEN er=5:GOTO 690 ELSE x$=x$+CHR$(1)+CHR$(uvn+15):GOTO 640
630 er=5:GOTO 690
640 wn=wn+1:w$(wn)=w$
650 WHILE MID$(ln$,q,1)=" ":q=q+1:WEND
660 WEND
670 x$=x$+CHR$(13):IF comp THEN 720 ELSE 760
produce token stream
70. 70
270 WHILE ASC(ln$)=32:IF LEN(ln$)>1 THEN ln$=RIGHT$(ln$,LEN(ln$)-1):WEND ELSE 690
280 WHILE RIGHT$(ln$,1)=CHR$(32):ln$=LEFT$(ln$,LEN(ln$)-1):WEND
290 ln$=UPPER$(ln$):IF ASC(ln$)=ASC("*") THEN IF LEN(ln$)>1 AND LEFT$(ln$,2)<>"* " THEN GOSUB
1700:IF er THEN 260 ELSE w$="":GOTO 690
300 ln$=ln$+CHR$(32):x$="":q=1:wn=-1:comp=0
310 WHILE q<LEN(ln$)
320 p=q:WHILE MID$(ln$,q,1)<>" ":q=q+1:WEND
330 w$=MID$(ln$,p,q-p):IF w$=":" THEN IF wn=-1 AND RIGHT$(ln$,2)="; " THEN comp=-1:GOTO 640 ELSE
PRINT"Bad definition":GOTO 260
340 FOR i=cvn TO 0 STEP-1:IF cvoc$(i)<>w$ THEN NEXT:GOTO 400
350 IF comp THEN IF wn=0 THEN er=3:GOTO 690
360 IF wn>=0 THEN IF w$(wn)="VARIABLE" THEN er=4:GOTO 690
370 x$=x$+CHR$(0)+CHR$(i+14):IF w$<>"."+CHR$(34) THEN 640
380 te=INSTR(q,ln$,CHR$(34)+CHR$(32)):IF te=0 THEN PRINT".";CHR$(34);" without ";CHR$(34):GOTO 260
390 x$=x$+MID$(ln$,q+1,te-q-1)+CHR$(4):q=te+1:GOTO 640
400 FOR i=uvn TO 0 STEP-1:IF uvoc$(i)<>w$ THEN NEXT:GOTO 440
410 IF comp THEN IF wn=0 THEN er=3:GOTO 690
420 IF wn>=0 THEN IF w$(wn)="VARIABLE" THEN er=4:GOTO 690
430 x$=x$+CHR$(1)+CHR$(i+14):GOTO 640
440 FOR i=vrn TO 0 STEP-1:IF var$(i)<>w$ THEN NEXT:GOTO 480
450 IF comp THEN IF wn=0 THEN er=3:GOTO 690
460 IF wn>=0 THEN IF w$(wn)="VARIABLE" THEN er=3:GOTO 690
470 x$=x$+CHR$(2)+CHR$(i+14):GOTO 640
480 FOR i=1 TO LEN(w$)
490 IF i=1 AND (ASC(w$)=ASC("+") OR ASC(w$)=ASC("-")) AND LEN(w$)>1 THEN 510
500 IF MID$(w$,i,1)<"0" OR MID$(w$,i,1)>"9" THEN 560
510 NEXT i
520 IF comp AND wn=0 THEN er=5:GOTO 690
530 IF wn>=0 THEN IF w$(wn)="VARIABLE" THEN er=5:GOTO 690
540 IF VAL(w$)>32767 OR VAL(w$)<-32767 THEN PRINT"Number ";w$;" too large":GOTO 260
550 x$=x$+CHR$(3)+w$+CHR$(4):GOTO 640
560 IF wn<0 THEN 590 ELSE IF w$(wn)<>"VARIABLE" THEN 590
570 IF comp AND w$=w$(1) THEN er=3:GOTO 690
580 x$=x$+w$+CHR$(4):GOTO 640
590 IF w$<>";" THEN 610
600 IF comp=0 OR q<>LEN(ln$) THEN PRINT"Illegal semi-colon":GOTO 260 ELSE 640
610 IF comp THEN IF wn=0 THEN 640
620 IF comp THEN IF w$<>w$(1) THEN er=5:GOTO 690 ELSE x$=x$+CHR$(1)+CHR$(uvn+15):GOTO 640
630 er=5:GOTO 690
640 wn=wn+1:w$(wn)=w$
650 WHILE MID$(ln$,q,1)=" ":q=q+1:WEND
660 WEND
670 x$=x$+CHR$(13):IF comp THEN 720 ELSE 760
look for extension words
71. 71
270 WHILE ASC(ln$)=32:IF LEN(ln$)>1 THEN ln$=RIGHT$(ln$,LEN(ln$)-1):WEND ELSE 690
280 WHILE RIGHT$(ln$,1)=CHR$(32):ln$=LEFT$(ln$,LEN(ln$)-1):WEND
290 ln$=UPPER$(ln$):IF ASC(ln$)=ASC("*") THEN IF LEN(ln$)>1 AND LEFT$(ln$,2)<>"* " THEN GOSUB
1700:IF er THEN 260 ELSE w$="":GOTO 690
300 ln$=ln$+CHR$(32):x$="":q=1:wn=-1:comp=0
310 WHILE q<LEN(ln$)
320 p=q:WHILE MID$(ln$,q,1)<>" ":q=q+1:WEND
330 w$=MID$(ln$,p,q-p):IF w$=":" THEN IF wn=-1 AND RIGHT$(ln$,2)="; " THEN comp=-1:GOTO 640 ELSE
PRINT"Bad definition":GOTO 260
340 FOR i=cvn TO 0 STEP-1:IF cvoc$(i)<>w$ THEN NEXT:GOTO 400
350 IF comp THEN IF wn=0 THEN er=3:GOTO 690
360 IF wn>=0 THEN IF w$(wn)="VARIABLE" THEN er=4:GOTO 690
370 x$=x$+CHR$(0)+CHR$(i+14):IF w$<>"."+CHR$(34) THEN 640
380 te=INSTR(q,ln$,CHR$(34)+CHR$(32)):IF te=0 THEN PRINT".";CHR$(34);" without ";CHR$(34):GOTO 260
390 x$=x$+MID$(ln$,q+1,te-q-1)+CHR$(4):q=te+1:GOTO 640
400 FOR i=uvn TO 0 STEP-1:IF uvoc$(i)<>w$ THEN NEXT:GOTO 440
410 IF comp THEN IF wn=0 THEN er=3:GOTO 690
420 IF wn>=0 THEN IF w$(wn)="VARIABLE" THEN er=4:GOTO 690
430 x$=x$+CHR$(1)+CHR$(i+14):GOTO 640
440 FOR i=vrn TO 0 STEP-1:IF var$(i)<>w$ THEN NEXT:GOTO 480
450 IF comp THEN IF wn=0 THEN er=3:GOTO 690
460 IF wn>=0 THEN IF w$(wn)="VARIABLE" THEN er=3:GOTO 690
470 x$=x$+CHR$(2)+CHR$(i+14):GOTO 640
480 FOR i=1 TO LEN(w$)
490 IF i=1 AND (ASC(w$)=ASC("+") OR ASC(w$)=ASC("-")) AND LEN(w$)>1 THEN 510
500 IF MID$(w$,i,1)<"0" OR MID$(w$,i,1)>"9" THEN 560
510 NEXT i
520 IF comp AND wn=0 THEN er=5:GOTO 690
530 IF wn>=0 THEN IF w$(wn)="VARIABLE" THEN er=5:GOTO 690
540 IF VAL(w$)>32767 OR VAL(w$)<-32767 THEN PRINT"Number ";w$;" too large":GOTO 260
550 x$=x$+CHR$(3)+w$+CHR$(4):GOTO 640
560 IF wn<0 THEN 590 ELSE IF w$(wn)<>"VARIABLE" THEN 590
570 IF comp AND w$=w$(1) THEN er=3:GOTO 690
580 x$=x$+w$+CHR$(4):GOTO 640
590 IF w$<>";" THEN 610
600 IF comp=0 OR q<>LEN(ln$) THEN PRINT"Illegal semi-colon":GOTO 260 ELSE 640
610 IF comp THEN IF wn=0 THEN 640
620 IF comp THEN IF w$<>w$(1) THEN er=5:GOTO 690 ELSE x$=x$+CHR$(1)+CHR$(uvn+15):GOTO 640
630 er=5:GOTO 690
640 wn=wn+1:w$(wn)=w$
650 WHILE MID$(ln$,q,1)=" ":q=q+1:WEND
660 WEND
670 x$=x$+CHR$(13):IF comp THEN 720 ELSE 760
outer interpreter loop
72. 72
270 WHILE ASC(ln$)=32:IF LEN(ln$)>1 THEN ln$=RIGHT$(ln$,LEN(ln$)-1):WEND ELSE 690
280 WHILE RIGHT$(ln$,1)=CHR$(32):ln$=LEFT$(ln$,LEN(ln$)-1):WEND
290 ln$=UPPER$(ln$):IF ASC(ln$)=ASC("*") THEN IF LEN(ln$)>1 AND LEFT$(ln$,2)<>"* " THEN GOSUB
1700:IF er THEN 260 ELSE w$="":GOTO 690
300 ln$=ln$+CHR$(32):x$="":q=1:wn=-1:comp=0
310 WHILE q<LEN(ln$)
320 p=q:WHILE MID$(ln$,q,1)<>" ":q=q+1:WEND
330 w$=MID$(ln$,p,q-p):IF w$=":" THEN IF wn=-1 AND RIGHT$(ln$,2)="; " THEN comp=-1:GOTO 640 ELSE
PRINT"Bad definition":GOTO 260
340 FOR i=cvn TO 0 STEP-1:IF cvoc$(i)<>w$ THEN NEXT:GOTO 400
350 IF comp THEN IF wn=0 THEN er=3:GOTO 690
360 IF wn>=0 THEN IF w$(wn)="VARIABLE" THEN er=4:GOTO 690
370 x$=x$+CHR$(0)+CHR$(i+14):IF w$<>"."+CHR$(34) THEN 640
380 te=INSTR(q,ln$,CHR$(34)+CHR$(32)):IF te=0 THEN PRINT".";CHR$(34);" without ";CHR$(34):GOTO 260
390 x$=x$+MID$(ln$,q+1,te-q-1)+CHR$(4):q=te+1:GOTO 640
400 FOR i=uvn TO 0 STEP-1:IF uvoc$(i)<>w$ THEN NEXT:GOTO 440
410 IF comp THEN IF wn=0 THEN er=3:GOTO 690
420 IF wn>=0 THEN IF w$(wn)="VARIABLE" THEN er=4:GOTO 690
430 x$=x$+CHR$(1)+CHR$(i+14):GOTO 640
440 FOR i=vrn TO 0 STEP-1:IF var$(i)<>w$ THEN NEXT:GOTO 480
450 IF comp THEN IF wn=0 THEN er=3:GOTO 690
460 IF wn>=0 THEN IF w$(wn)="VARIABLE" THEN er=3:GOTO 690
470 x$=x$+CHR$(2)+CHR$(i+14):GOTO 640
480 FOR i=1 TO LEN(w$)
490 IF i=1 AND (ASC(w$)=ASC("+") OR ASC(w$)=ASC("-")) AND LEN(w$)>1 THEN 510
500 IF MID$(w$,i,1)<"0" OR MID$(w$,i,1)>"9" THEN 560
510 NEXT i
520 IF comp AND wn=0 THEN er=5:GOTO 690
530 IF wn>=0 THEN IF w$(wn)="VARIABLE" THEN er=5:GOTO 690
540 IF VAL(w$)>32767 OR VAL(w$)<-32767 THEN PRINT"Number ";w$;" too large":GOTO 260
550 x$=x$+CHR$(3)+w$+CHR$(4):GOTO 640
560 IF wn<0 THEN 590 ELSE IF w$(wn)<>"VARIABLE" THEN 590
570 IF comp AND w$=w$(1) THEN er=3:GOTO 690
580 x$=x$+w$+CHR$(4):GOTO 640
590 IF w$<>";" THEN 610
600 IF comp=0 OR q<>LEN(ln$) THEN PRINT"Illegal semi-colon":GOTO 260 ELSE 640
610 IF comp THEN IF wn=0 THEN 640
620 IF comp THEN IF w$<>w$(1) THEN er=5:GOTO 690 ELSE x$=x$+CHR$(1)+CHR$(uvn+15):GOTO 640
630 er=5:GOTO 690
640 wn=wn+1:w$(wn)=w$
650 WHILE MID$(ln$,q,1)=" ":q=q+1:WEND
660 WEND
670 x$=x$+CHR$(13):IF comp THEN 720 ELSE 760
word definition to compile
73. 73
270 WHILE ASC(ln$)=32:IF LEN(ln$)>1 THEN ln$=RIGHT$(ln$,LEN(ln$)-1):WEND ELSE 690
280 WHILE RIGHT$(ln$,1)=CHR$(32):ln$=LEFT$(ln$,LEN(ln$)-1):WEND
290 ln$=UPPER$(ln$):IF ASC(ln$)=ASC("*") THEN IF LEN(ln$)>1 AND LEFT$(ln$,2)<>"* " THEN GOSUB
1700:IF er THEN 260 ELSE w$="":GOTO 690
300 ln$=ln$+CHR$(32):x$="":q=1:wn=-1:comp=0
310 WHILE q<LEN(ln$)
320 p=q:WHILE MID$(ln$,q,1)<>" ":q=q+1:WEND
330 w$=MID$(ln$,p,q-p):IF w$=":" THEN IF wn=-1 AND RIGHT$(ln$,2)="; " THEN comp=-1:GOTO 640 ELSE
PRINT"Bad definition":GOTO 260
340 FOR i=cvn TO 0 STEP-1:IF cvoc$(i)<>w$ THEN NEXT:GOTO 400
350 IF comp THEN IF wn=0 THEN er=3:GOTO 690
360 IF wn>=0 THEN IF w$(wn)="VARIABLE" THEN er=4:GOTO 690
370 x$=x$+CHR$(0)+CHR$(i+14):IF w$<>"."+CHR$(34) THEN 640
380 te=INSTR(q,ln$,CHR$(34)+CHR$(32)):IF te=0 THEN PRINT".";CHR$(34);" without ";CHR$(34):GOTO 260
390 x$=x$+MID$(ln$,q+1,te-q-1)+CHR$(4):q=te+1:GOTO 640
400 FOR i=uvn TO 0 STEP-1:IF uvoc$(i)<>w$ THEN NEXT:GOTO 440
410 IF comp THEN IF wn=0 THEN er=3:GOTO 690
420 IF wn>=0 THEN IF w$(wn)="VARIABLE" THEN er=4:GOTO 690
430 x$=x$+CHR$(1)+CHR$(i+14):GOTO 640
440 FOR i=vrn TO 0 STEP-1:IF var$(i)<>w$ THEN NEXT:GOTO 480
450 IF comp THEN IF wn=0 THEN er=3:GOTO 690
460 IF wn>=0 THEN IF w$(wn)="VARIABLE" THEN er=3:GOTO 690
470 x$=x$+CHR$(2)+CHR$(i+14):GOTO 640
480 FOR i=1 TO LEN(w$)
490 IF i=1 AND (ASC(w$)=ASC("+") OR ASC(w$)=ASC("-")) AND LEN(w$)>1 THEN 510
500 IF MID$(w$,i,1)<"0" OR MID$(w$,i,1)>"9" THEN 560
510 NEXT i
520 IF comp AND wn=0 THEN er=5:GOTO 690
530 IF wn>=0 THEN IF w$(wn)="VARIABLE" THEN er=5:GOTO 690
540 IF VAL(w$)>32767 OR VAL(w$)<-32767 THEN PRINT"Number ";w$;" too large":GOTO 260
550 x$=x$+CHR$(3)+w$+CHR$(4):GOTO 640
560 IF wn<0 THEN 590 ELSE IF w$(wn)<>"VARIABLE" THEN 590
570 IF comp AND w$=w$(1) THEN er=3:GOTO 690
580 x$=x$+w$+CHR$(4):GOTO 640
590 IF w$<>";" THEN 610
600 IF comp=0 OR q<>LEN(ln$) THEN PRINT"Illegal semi-colon":GOTO 260 ELSE 640
610 IF comp THEN IF wn=0 THEN 640
620 IF comp THEN IF w$<>w$(1) THEN er=5:GOTO 690 ELSE x$=x$+CHR$(1)+CHR$(uvn+15):GOTO 640
630 er=5:GOTO 690
640 wn=wn+1:w$(wn)=w$
650 WHILE MID$(ln$,q,1)=" ":q=q+1:WEND
660 WEND
670 x$=x$+CHR$(13):IF comp THEN 720 ELSE 760
execute "byte code" or add to dictionary
check for user defined word
check for user defined variable
must be a number
"byte code" generated for token
74. 74
270 WHILE ASC(ln$)=32:IF LEN(ln$)>1 THEN ln$=RIGHT$(ln$,LEN(ln$)-1):WEND ELSE 690
280 WHILE RIGHT$(ln$,1)=CHR$(32):ln$=LEFT$(ln$,LEN(ln$)-1):WEND
290 ln$=UPPER$(ln$):IF ASC(ln$)=ASC("*") THEN IF LEN(ln$)>1 AND LEFT$(ln$,2)<>"* " THEN GOSUB
1700:IF er THEN 260 ELSE w$="":GOTO 690
300 ln$=ln$+CHR$(32):x$="":q=1:wn=-1:comp=0
310 WHILE q<LEN(ln$)
320 p=q:WHILE MID$(ln$,q,1)<>" ":q=q+1:WEND
330 w$=MID$(ln$,p,q-p):IF w$=":" THEN IF wn=-1 AND RIGHT$(ln$,2)="; " THEN comp=-1:GOTO 640 ELSE
PRINT"Bad definition":GOTO 260
340 FOR i=cvn TO 0 STEP-1:IF cvoc$(i)<>w$ THEN NEXT:GOTO 400
350 IF comp THEN IF wn=0 THEN er=3:GOTO 690
360 IF wn>=0 THEN IF w$(wn)="VARIABLE" THEN er=4:GOTO 690
370 x$=x$+CHR$(0)+CHR$(i+14):IF w$<>"."+CHR$(34) THEN 640
380 te=INSTR(q,ln$,CHR$(34)+CHR$(32)):IF te=0 THEN PRINT".";CHR$(34);" without ";CHR$(34):GOTO 260
390 x$=x$+MID$(ln$,q+1,te-q-1)+CHR$(4):q=te+1:GOTO 640
400 FOR i=uvn TO 0 STEP-1:IF uvoc$(i)<>w$ THEN NEXT:GOTO 440
410 IF comp THEN IF wn=0 THEN er=3:GOTO 690
420 IF wn>=0 THEN IF w$(wn)="VARIABLE" THEN er=4:GOTO 690
430 x$=x$+CHR$(1)+CHR$(i+14):GOTO 640
440 FOR i=vrn TO 0 STEP-1:IF var$(i)<>w$ THEN NEXT:GOTO 480
450 IF comp THEN IF wn=0 THEN er=3:GOTO 690
460 IF wn>=0 THEN IF w$(wn)="VARIABLE" THEN er=3:GOTO 690
470 x$=x$+CHR$(2)+CHR$(i+14):GOTO 640
480 FOR i=1 TO LEN(w$)
490 IF i=1 AND (ASC(w$)=ASC("+") OR ASC(w$)=ASC("-")) AND LEN(w$)>1 THEN 510
500 IF MID$(w$,i,1)<"0" OR MID$(w$,i,1)>"9" THEN 560
510 NEXT i
520 IF comp AND wn=0 THEN er=5:GOTO 690
530 IF wn>=0 THEN IF w$(wn)="VARIABLE" THEN er=5:GOTO 690
540 IF VAL(w$)>32767 OR VAL(w$)<-32767 THEN PRINT"Number ";w$;" too large":GOTO 260
550 x$=x$+CHR$(3)+w$+CHR$(4):GOTO 640
560 IF wn<0 THEN 590 ELSE IF w$(wn)<>"VARIABLE" THEN 590
570 IF comp AND w$=w$(1) THEN er=3:GOTO 690
580 x$=x$+w$+CHR$(4):GOTO 640
590 IF w$<>";" THEN 610
600 IF comp=0 OR q<>LEN(ln$) THEN PRINT"Illegal semi-colon":GOTO 260 ELSE 640
610 IF comp THEN IF wn=0 THEN 640
620 IF comp THEN IF w$<>w$(1) THEN er=5:GOTO 690 ELSE x$=x$+CHR$(1)+CHR$(uvn+15):GOTO 640
630 er=5:GOTO 690
640 wn=wn+1:w$(wn)=w$
650 WHILE MID$(ln$,q,1)=" ":q=q+1:WEND
660 WEND
670 x$=x$+CHR$(13):IF comp THEN 720 ELSE 760
add "byte code" for primitive
add "byte code" for user defined word
add "byte code" for user defined variable
add "byte code" for number
compiler mode sanity checks
76. 76
710 REM Compile New Word
720 IF wn<3 THEN PRINT"Insufficient definition":GOTO 260
730 uvn=uvn+1:uvoc$(uvn)=w$(1):uvex$(uvn)=x$
740 w$="":GOTO 690
77. 77
710 REM Compile New Word
720 IF wn<3 THEN PRINT"Insufficient definition":GOTO 260
730 uvn=uvn+1:uvoc$(uvn)=w$(1):uvex$(uvn)=x$
740 w$="":GOTO 690
78. 78
710 REM Compile New Word
720 IF wn<3 THEN PRINT"Insufficient definition":GOTO 260
730 uvn=uvn+1:uvoc$(uvn)=w$(1):uvex$(uvn)=x$
740 w$="":GOTO 690
80. 80
750 REM Execute Commands
760 ln=0:w$(ln)=x$:er=0
770 GOSUB 780:w$="":GOTO 690
780 p(ln)=1:ff(ln)=0:df(ln)=0
790 WHILE MID$(w$(ln),p(ln),1)<>CHR$(13)
800 class=ASC(MID$(w$(ln),p(ln),1)):p(ln)=p(ln)+1
810 IF class<>0 THEN 920
820 word=ASC(MID$(w$(ln),p(ln),1))-14:p(ln)=p(ln)+1
830 IF ff(ln)=0 OR word=37 OR word=39 OR word=40 THEN 860
840 IF word=5 OR word=32 THEN WHILE ASC(MID$(w$(ln),p(ln),1))<>4:p(ln)=p(ln)+1:WEND:p(ln)=p(ln)+1
850 GOTO 1060
860 IF sp+dsp(word,1)<-1 OR sp+dsp(word,1)>spmax THEN er=1:GOTO 1070
870 IF sp-dsp(word,0)<-1 THEN er=2:GOTO 1070
880 sp=sp+dsp(word,1)
890 IF word <43 THEN ON word+1 GOSUB
1090,1110,1120,1130,1140,1150,1160,1170,1180,1190,1200,1210,1220,1230,1240,1250,1260,1270,1280,1290
,1300,1310,1320,1330,1340,1350,1360,1370,1380,1390,1400,1410,1420,1430,1440,1450,1460,1470,1480,149
0,1500,1510,1520
900 IF word>42 THEN ON word-42 GOSUB
1530,1540,1550,1560,1570,1580,1590,1600,1610,1620,1630,1640,1650,1660,1670,1680
910 IF er=0 THEN 1060 ELSE 1070
920 IF class<>1 THEN 970
930 word=ASC(MID$(w$(ln),p(ln),1))-14:p(ln)=p(ln)+1
940 IF ff(ln) THEN 1060
950 IF ln<34 THEN ln=ln+1:w$(ln)=uvex$(word) ELSE er=7:RETURN
960 GOSUB 780:IF ln=0 OR er=0 THEN 1060 ELSE RETURN
970 IF class<>2 THEN 1010
980 word=ASC(MID$(w$(ln),p(ln),1))-14:p(ln)=p(ln)+1
990 IF ff(ln) THEN 1060
1000 sp=sp+1:s(sp)=@var(word):GOTO 1060
1010 IF class<>3 THEN er=1:GOTO 1070
1020 p=p(ln):WHILE ASC(MID$(w$(ln),p,1))<>4:p=p+1:WEND
1030 v=VAL(MID$(w$(ln),p(ln),p-p(ln)+1)):p(ln)=p+1
1040 IF ff(ln) THEN 1060
1050 sp=sp+1:s(sp)=v
1060 WEND
1070 ln=ln-1:RETURN
81. 81
750 REM Execute Commands
760 ln=0:w$(ln)=x$:er=0
770 GOSUB 780:w$="":GOTO 690
780 p(ln)=1:ff(ln)=0:df(ln)=0
790 WHILE MID$(w$(ln),p(ln),1)<>CHR$(13)
800 class=ASC(MID$(w$(ln),p(ln),1)):p(ln)=p(ln)+1
810 IF class<>0 THEN 920
820 word=ASC(MID$(w$(ln),p(ln),1))-14:p(ln)=p(ln)+1
830 IF ff(ln)=0 OR word=37 OR word=39 OR word=40 THEN 860
840 IF word=5 OR word=32 THEN WHILE ASC(MID$(w$(ln),p(ln),1))<>4:p(ln)=p(ln)+1:WEND:p(ln)=p(ln)+1
850 GOTO 1060
860 IF sp+dsp(word,1)<-1 OR sp+dsp(word,1)>spmax THEN er=1:GOTO 1070
870 IF sp-dsp(word,0)<-1 THEN er=2:GOTO 1070
880 sp=sp+dsp(word,1)
890 IF word <43 THEN ON word+1 GOSUB
1090,1110,1120,1130,1140,1150,1160,1170,1180,1190,1200,1210,1220,1230,1240,1250,1260,1270,1280,1290
,1300,1310,1320,1330,1340,1350,1360,1370,1380,1390,1400,1410,1420,1430,1440,1450,1460,1470,1480,149
0,1500,1510,1520
900 IF word>42 THEN ON word-42 GOSUB
1530,1540,1550,1560,1570,1580,1590,1600,1610,1620,1630,1640,1650,1660,1670,1680
910 IF er=0 THEN 1060 ELSE 1070
920 IF class<>1 THEN 970
930 word=ASC(MID$(w$(ln),p(ln),1))-14:p(ln)=p(ln)+1
940 IF ff(ln) THEN 1060
950 IF ln<34 THEN ln=ln+1:w$(ln)=uvex$(word) ELSE er=7:RETURN
960 GOSUB 780:IF ln=0 OR er=0 THEN 1060 ELSE RETURN
970 IF class<>2 THEN 1010
980 word=ASC(MID$(w$(ln),p(ln),1))-14:p(ln)=p(ln)+1
990 IF ff(ln) THEN 1060
1000 sp=sp+1:s(sp)=@var(word):GOTO 1060
1010 IF class<>3 THEN er=1:GOTO 1070
1020 p=p(ln):WHILE ASC(MID$(w$(ln),p,1))<>4:p=p+1:WEND
1030 v=VAL(MID$(w$(ln),p(ln),p-p(ln)+1)):p(ln)=p+1
1040 IF ff(ln) THEN 1060
1050 sp=sp+1:s(sp)=v
1060 WEND
1070 ln=ln-1:RETURN
these are our execution classes
0 = primitives
1 = user defined word
2 = user defined variable
3 = numbers
82. 82
750 REM Execute Commands
760 ln=0:w$(ln)=x$:er=0
770 GOSUB 780:w$="":GOTO 690
780 p(ln)=1:ff(ln)=0:df(ln)=0
790 WHILE MID$(w$(ln),p(ln),1)<>CHR$(13)
800 class=ASC(MID$(w$(ln),p(ln),1)):p(ln)=p(ln)+1
810 IF class<>0 THEN 920
820 word=ASC(MID$(w$(ln),p(ln),1))-14:p(ln)=p(ln)+1
830 IF ff(ln)=0 OR word=37 OR word=39 OR word=40 THEN 860
840 IF word=5 OR word=32 THEN WHILE ASC(MID$(w$(ln),p(ln),1))<>4:p(ln)=p(ln)+1:WEND:p(ln)=p(ln)+1
850 GOTO 1060
860 IF sp+dsp(word,1)<-1 OR sp+dsp(word,1)>spmax THEN er=1:GOTO 1070
870 IF sp-dsp(word,0)<-1 THEN er=2:GOTO 1070
880 sp=sp+dsp(word,1)
890 IF word <43 THEN ON word+1 GOSUB
1090,1110,1120,1130,1140,1150,1160,1170,1180,1190,1200,1210,1220,1230,1240,1250,1260,1270,1280,1290
,1300,1310,1320,1330,1340,1350,1360,1370,1380,1390,1400,1410,1420,1430,1440,1450,1460,1470,1480,149
0,1500,1510,1520
900 IF word>42 THEN ON word-42 GOSUB
1530,1540,1550,1560,1570,1580,1590,1600,1610,1620,1630,1640,1650,1660,1670,1680
910 IF er=0 THEN 1060 ELSE 1070
920 IF class<>1 THEN 970
930 word=ASC(MID$(w$(ln),p(ln),1))-14:p(ln)=p(ln)+1
940 IF ff(ln) THEN 1060
950 IF ln<34 THEN ln=ln+1:w$(ln)=uvex$(word) ELSE er=7:RETURN
960 GOSUB 780:IF ln=0 OR er=0 THEN 1060 ELSE RETURN
970 IF class<>2 THEN 1010
980 word=ASC(MID$(w$(ln),p(ln),1))-14:p(ln)=p(ln)+1
990 IF ff(ln) THEN 1060
1000 sp=sp+1:s(sp)=@var(word):GOTO 1060
1010 IF class<>3 THEN er=1:GOTO 1070
1020 p=p(ln):WHILE ASC(MID$(w$(ln),p,1))<>4:p=p+1:WEND
1030 v=VAL(MID$(w$(ln),p(ln),p-p(ln)+1)):p(ln)=p+1
1040 IF ff(ln) THEN 1060
1050 sp=sp+1:s(sp)=v
1060 WEND
1070 ln=ln-1:RETURN
these are computed GOSUBs
implementing a despatch table
to BASIC for each primitive
83. 83
1080 REM Command List
1090 temp!=s(sp+1):IF temp!<0 THEN temp!=temp!+65536
1100 POKE s(sp+2),temp!-256*INT(temp!/256):POKE s(sp+2)+1,INT(temp!/256):RETURN
1110 s(sp)=s(sp)*s(sp+1):RETURN
1120 s(sp)=s(sp)+s(sp+1):RETURN
1130 s(sp)=s(sp)-s(sp+1):RETURN
1140 PRINT s(sp+1);CHR$(8);:RETURN
1150 WHILE ASC(MID$(w$(ln),p(ln),1))<>4:PRINT MID$(w$(ln),p(ln),1);:p(ln)=p(ln)+1:WEND:p(ln)=p(ln)
+1:RETURN
1160 s(sp)=INT(s(sp)/s(sp+1)):RETURN
1170 temp=s(sp):s(sp)=INT(s(sp-1)/s(sp)):s(sp-1)=s(sp-1)-s(sp)*temp:RETURN
1180 s(sp)=(s(sp)<0):RETURN
1190 s(sp)=(s(sp)=0):RETURN
1200 s(sp)=(s(sp)<s(sp+1)):RETURN
1210 s(sp)=(s(sp)=s(sp+1)):RETURN
1220 s(sp)=(s(sp)>s(sp+1)):RETURN
1230 temp!=PEEK(s(sp+1))+256*PEEK(s(sp+1)+1):IF temp!>32767 THEN temp!
=temp!-65536:PRINTtemp!;CHR$(8);:RETURN ELSE PRINTtemp!;CHR$(8);:RETURN
1240 temp!=PEEK(s(sp))+256*PEEK(s(sp)+1):IF temp!>32767 THEN s(sp)=temp!-65536:RETURN ELSE
s(sp)=temp!:RETURN
1250 s(sp)=ABS(s(sp)):RETURN
1260 s(sp)=s(sp) AND s(sp+1):RETURN
1270 s(sp)=PEEK(s(sp)):RETURN
1280 PRINT:RETURN
1290 RETURN
1300 s(sp)=s(sp-1):RETURN
1310 PRINTCHR$(s(sp+1));:RETURN
1320 in$=INKEY$:IF in$="" THEN 1320 ELSE s(sp)=ASC(in$):RETURN
1330 s(sp)=MAX(s(sp),s(sp+1)):RETURN
1340 s(sp)=MIN(s(sp),s(sp+1)):RETURN
1350 s(sp)=-s(sp):RETURN
1360 s(sp)=s(sp) MOD s(sp+1):RETURN
1370 s(sp)=s(sp) OR s(sp+1):RETURN
1380 s(sp)=s(sp-2):RETURN
1390 PRINT" ";:RETURN
1400 PRINT USING "&";SPACE$(s(sp+1)-256*INT(s(sp+1)/256));:RETURN
1410 temp=s(sp):s(sp)=s(sp-1):s(sp-1)=temp:RETURN
1420 vrn=vrn+1:var(vrn)=s(sp+1):WHILE ASC(MID$(w$(ln),p(ln),1))<>4:var$(vrn)=var$(vrn)+MID$(w$
(ln),p(ln),1):p(ln)=p(ln)+1:WEND:p(ln)=p(ln)+1:RETURN
1430 s(sp)=s(sp) XOR s(sp+1):RETURN
1440 beg(ln)=p(ln):RETURN
1450 IF s(sp+1)=0 THEN p(ln)=beg(ln):RETURN ELSE RETURN
1460 IF s(sp+1)<>0 THEN RETURN ELSE ff(ln)=-1:RETURN
this is why switch statements exist
and why fallthrough is superior to break!
84. 84
that's probably more than
you ever wanted to know
about Forth or BASIC
or how I spent the 80s...
89. Kent Beck
89
eXtreme Programming
the birth of agile
Planning/feedback loops
Release plan
Code
Iteration plan
Acceptance test
Stand-up meeting
Pair negotiation
Unit test
Pair programming
Months
Weeks
Days
One day
Hours
Minutes
Seconds
By DonWells - Own work based on: XP-feedback.gif, CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=27448045
92. 92
software considerations in airborne systems and equipment certification
RTCA DO-178B
Level Failure condition Objectives[5] Failure Rate
A Catastrophic 66 10−9/h
B Hazardous 65 10−7/h
C Major 57 10−5/h
D Minor 28 10−3/h
E No Effect 0 n/a
93. 93
evolutionary prototyping
the boehm spiral
Plan next Phase
Develop, verify
next-level product
Determine objectives,
alternatives, constraints
Evaluate alternatives
identify, resolve risks
Cummulative
cost
Review
Commitment
partition
Risk
analysis
Risk
analysis
Risk
analysis
Prototype 1 Prototype 2 Prototype 3
Operational
Prototype
Risk
analy-
sis
Requirements plan
life-cycle plan
Develop-
ment plan
Integration
and test
plan
Concept of
operation
Simulations, models, benchmarks
Software
requirements
Requirements
validation
Software
product
design
Design validation
and verification
Detailed
design
Code
Unit
test
Integration
and test
Acceptance
test
Implementation
97. 97
● digital identity
● messaging
● privacy
● trust
what we do
IDENTITY & TRUST IN MONITORED SPACES
THE VIRTUES OF PRIVACY BY DESIGN
Eleanor McHugh
Romek Szczesniak
99. 99
#!/bin/bash
# (c) 2018 Innovative Identity Solutions Limited
# all rights reserved
source scripts/ruby_web_api.sh
print_cic_statement
BASE_SERVICE_PORT=9000
source ./infrastructure.sh
while getopts b:v:sh option
do
case "${option}" in
h) echo
echo "This script launches the infrastructure for user registration and interaction."
echo "For each user and the oracle it creates a running web service."
echo "It initialises the database when it runs."
echo
echo "Usage:"
echo " ./demo.sh -b bearer-name -v validator-name"
echo " ./demo.sh -h"
echo " ./demo.sh -s"
exit 0
;;
b) BEARER=${OPTARG};;
v) VALIDATOR=${OPTARG};;
s) shutdown $DOMAIN_ADDRESS;;
esac
done
if [ -z ${BEARER+x} ]; then
echo "specify bearer name with -b";
exit 1
fi
if [ -z ${VALIDATOR+x} ]; then
echo "specify validator name with -v";
exit 2
fi
scripts/startup.sh $BASE_SERVICE_PORT
heading "Launching bearer devices"
launch_bearer $BEAR_SERVICE $BEARER "bear.jpg"
launch_bearer $VAL_SERVICE $VALIDATOR "val.jpg"
this is part of a proof of concept
for a digital identity system
it's part of a series of prototypes
evolved from a series of pure
BaSH scripts
all the techniques demonstrated
are applicable to any language
with either quick compilation
speed or fast interpreter launch
like golang or ruby
100. 100
#!/bin/bash
# (c) 2018 Innovative Identity Solutions Limited
# all rights reserved
source scripts/ruby_web_api.sh
print_cic_statement
BASE_SERVICE_PORT=9000
source ./infrastructure.sh
while getopts b:v:sh option
do
case "${option}" in
h) echo
echo "This script launches the infrastructure for user registration and interaction."
echo "For each user and the oracle it creates a running web service."
echo "It initialises the database when it runs."
echo
echo "Usage:"
echo " ./demo.sh -b bearer-name -v validator-name"
echo " ./demo.sh -h"
echo " ./demo.sh -s"
exit 0
;;
b) BEARER=${OPTARG};;
v) VALIDATOR=${OPTARG};;
s) shutdown $DOMAIN_ADDRESS;;
esac
done
if [ -z ${BEARER+x} ]; then
echo "specify bearer name with -b";
exit 1
fi
if [ -z ${VALIDATOR+x} ]; then
echo "specify validator name with -v";
exit 2
fi
scripts/startup.sh $BASE_SERVICE_PORT
heading "Launching bearer devices"
launch_bearer $BEAR_SERVICE $BEARER "bear.jpg"
launch_bearer $VAL_SERVICE $VALIDATOR "val.jpg"
Fair Use Exemptions Apply
101. 101
#!/bin/bash
# (c) 2018 Innovative Identity Solutions Limited
# all rights reserved
source scripts/ruby_web_api.sh
print_cic_statement
BASE_SERVICE_PORT=9000
source ./infrastructure.sh
while getopts b:v:sh option
do
case "${option}" in
h) echo
echo "This script launches the infrastructure for user registration and interaction."
echo "For each user and the oracle it creates a running web service."
echo "It initialises the database when it runs."
echo
echo "Usage:"
echo " ./demo.sh -b bearer-name -v validator-name"
echo " ./demo.sh -h"
echo " ./demo.sh -s"
exit 0
;;
b) BEARER=${OPTARG};;
v) VALIDATOR=${OPTARG};;
s) shutdown $DOMAIN_ADDRESS;;
esac
done
if [ -z ${BEARER+x} ]; then
echo "specify bearer name with -b";
exit 1
fi
if [ -z ${VALIDATOR+x} ]; then
echo "specify validator name with -v";
exit 2
fi
scripts/startup.sh $BASE_SERVICE_PORT
heading "Launching bearer devices"
launch_bearer $BEAR_SERVICE $BEARER "bear.jpg"
launch_bearer $VAL_SERVICE $VALIDATOR "val.jpg"
bangs allow scripts to be executable
102. 102
#!/bin/bash
# (c) 2018 Innovative Identity Solutions Limited
# all rights reserved
source scripts/ruby_web_api.sh
print_cic_statement
BASE_SERVICE_PORT=9000
source ./infrastructure.sh
while getopts b:v:sh option
do
case "${option}" in
h) echo
echo "This script launches the infrastructure for user registration and interaction."
echo "For each user and the oracle it creates a running web service."
echo "It initialises the database when it runs."
echo
echo "Usage:"
echo " ./demo.sh -b bearer-name -v validator-name"
echo " ./demo.sh -h"
echo " ./demo.sh -s"
exit 0
;;
b) BEARER=${OPTARG};;
v) VALIDATOR=${OPTARG};;
s) shutdown $DOMAIN_ADDRESS;;
esac
done
if [ -z ${BEARER+x} ]; then
echo "specify bearer name with -b";
exit 1
fi
if [ -z ${VALIDATOR+x} ]; then
echo "specify validator name with -v";
exit 2
fi
scripts/startup.sh $BASE_SERVICE_PORT
heading "Launching bearer devices"
launch_bearer $BEAR_SERVICE $BEARER "bear.jpg"
launch_bearer $VAL_SERVICE $VALIDATOR "val.jpg"
Environment Variables
for configuration
103. 103
#!/bin/bash
# (c) 2018 Innovative Identity Solutions Limited
# all rights reserved
source scripts/ruby_web_api.sh
print_cic_statement
BASE_SERVICE_PORT=9000
source ./infrastructure.sh
while getopts b:v:sh option
do
case "${option}" in
h) echo
echo "This script launches the infrastructure for user registration and interaction."
echo "For each user and the oracle it creates a running web service."
echo "It initialises the database when it runs."
echo
echo "Usage:"
echo " ./demo.sh -b bearer-name -v validator-name"
echo " ./demo.sh -h"
echo " ./demo.sh -s"
exit 0
;;
b) BEARER=${OPTARG};;
v) VALIDATOR=${OPTARG};;
s) shutdown $DOMAIN_ADDRESS;;
esac
done
if [ -z ${BEARER+x} ]; then
echo "specify bearer name with -b";
exit 1
fi
if [ -z ${VALIDATOR+x} ]; then
echo "specify validator name with -v";
exit 2
fi
scripts/startup.sh $BASE_SERVICE_PORT
heading "Launching bearer devices"
launch_bearer $BEAR_SERVICE $BEARER "bear.jpg"
launch_bearer $VAL_SERVICE $VALIDATOR "val.jpg"
Environment Variables
for configuration
104. 104
#!/bin/bash
# (c) 2017 Innovative Identity Solutions Limited
# all rights reserved
# This script defines addresses for a service infrastructure baselined at $BASEPORT."
#
# Usage:"
# export BASE_SERVICE=9000"
# source infrastructure.sh"
#
PORT=$BASE_SERVICE_PORT
ADDRESS=${SERVER_ADDRESS:=localhost}
export DOMAIN_SERVICE=$PORT
export DOMAIN_ADDRESS="$ADDRESS:$DOMAIN_SERVICE"
let PORT++
export LOGGING_SERVICE=$PORT
export LOGGING_ADDRESS="$ADDRESS:$LOGGING_SERVICE"
let PORT++
export SECURE_STORE_SERVICE=$PORT
export SECURE_STORE_ADDRESS="$ADDRESS:$SECURE_STORE_SERVICE"
let PORT++
export REGISTRY_SERVICE=$PORT
export REGISTRY_ADDRESS="$ADDRESS:$REGISTRY_SERVICE"
let PORT++
export ORACLE_SERVICE=$PORT
export ORACLE_ADDRESS="$ADDRESS:$ORACLE_SERVICE"
let PORT++
export BEAR_SERVICE=$PORT
export BEAR_ADDRESS="$ADDRESS:$BEAR_SERVICE"
let PORT++
export VAL_SERVICE=$PORT
export VAL_ADDRESS="$ADDRESS:$VAL_SERVICE"
BASE_SERVICE_PORT=$DOMAIN_SERVICE
Environment Variables
for static configuration
105. 105
#!/bin/bash
# (c) 2018 Innovative Identity Solutions Limited
# all rights reserved
source scripts/ruby_web_api.sh
print_cic_statement
BASE_SERVICE_PORT=9000
source ./infrastructure.sh
while getopts b:v:sh option
do
case "${option}" in
h) echo
echo "This script launches the infrastructure for user registration and interaction."
echo "For each user and the oracle it creates a running web service."
echo "It initialises the database when it runs."
echo
echo "Usage:"
echo " ./demo.sh -b bearer-name -v validator-name"
echo " ./demo.sh -h"
echo " ./demo.sh -s"
exit 0
;;
b) BEARER=${OPTARG};;
v) VALIDATOR=${OPTARG};;
s) shutdown $DOMAIN_ADDRESS;;
esac
done
if [ -z ${BEARER+x} ]; then
echo "specify bearer name with -b";
exit 1
fi
if [ -z ${VALIDATOR+x} ]; then
echo "specify validator name with -v";
exit 2
fi
scripts/startup.sh $BASE_SERVICE_PORT
heading "Launching bearer devices"
launch_bearer $BEAR_SERVICE $BEARER "bear.jpg"
launch_bearer $VAL_SERVICE $VALIDATOR "val.jpg"
command-line switches
for instance variables
106. 106
#!/bin/bash
# (c) 2018 Innovative Identity Solutions Limited
# all rights reserved
source scripts/ruby_web_api.sh
print_cic_statement
BASE_SERVICE_PORT=9000
source ./infrastructure.sh
while getopts b:v:sh option
do
case "${option}" in
h) echo
echo "This script launches the infrastructure for user registration and interaction."
echo "For each user and the oracle it creates a running web service."
echo "It initialises the database when it runs."
echo
echo "Usage:"
echo " ./demo.sh -b bearer-name -v validator-name"
echo " ./demo.sh -h"
echo " ./demo.sh -s"
exit 0
;;
b) BEARER=${OPTARG};;
v) VALIDATOR=${OPTARG};;
s) shutdown $DOMAIN_ADDRESS;;
esac
done
if [ -z ${BEARER+x} ]; then
echo "specify bearer name with -b";
exit 1
fi
if [ -z ${VALIDATOR+x} ]; then
echo "specify validator name with -v";
exit 2
fi
scripts/startup.sh $BASE_SERVICE_PORT
heading "Launching bearer devices"
launch_bearer $BEAR_SERVICE $BEARER "bear.jpg"
launch_bearer $VAL_SERVICE $VALIDATOR "val.jpg"
check for missing parameters
107. 107
#!/bin/bash
# (c) 2018 Innovative Identity Solutions Limited
# all rights reserved
source scripts/ruby_web_api.sh
print_cic_statement
BASE_SERVICE_PORT=9000
source ./infrastructure.sh
while getopts b:v:sh option
do
case "${option}" in
h) echo
echo "This script launches the infrastructure for user registration and interaction."
echo "For each user and the oracle it creates a running web service."
echo "It initialises the database when it runs."
echo
echo "Usage:"
echo " ./demo.sh -b bearer-name -v validator-name"
echo " ./demo.sh -h"
echo " ./demo.sh -s"
exit 0
;;
b) BEARER=${OPTARG};;
v) VALIDATOR=${OPTARG};;
s) shutdown $DOMAIN_ADDRESS;;
esac
done
if [ -z ${BEARER+x} ]; then
echo "specify bearer name with -b";
exit 1
fi
if [ -z ${VALIDATOR+x} ]; then
echo "specify validator name with -v";
exit 2
fi
scripts/startup.sh $BASE_SERVICE_PORT
heading "Launching bearer devices"
launch_bearer $BEAR_SERVICE $BEARER "bear.jpg"
launch_bearer $VAL_SERVICE $VALIDATOR "val.jpg"
now for some Ruby magic
108. 108
RUBY_DIR="$ROOT_DIR/ruby"
source scripts/basics.sh
# http_requests will print headers and response body along with stack dumps
# if the env variable DEBUG_HTTP_REQUESTS exists
ruby_web_client () {
local program=$1
ruby -e "
require 'json'
require '$CLIENTS_DIR/web'
$program
"
}
http_request () {
local version=$1
local method=$2
local address=$3
local endpoint=$4
local request_body=$5
ruby_web_client "
if ENV['DEBUG_HTTP_REQUESTS']
response = WebClient.$method($version, '$address', endpoint = $endpoint) do |req|
puts 'REQUEST:'
puts $request_body
$request_body
end
puts 'RESPONSE:'
response.each_header do |k, v|
puts "#{k}: #{v}"
end
puts "body: #{response.body}"
puts
else
WebClient.$method($version, '$address', endpoint = $endpoint) do |req|
$request_body
end rescue nil
end
"
}
where we keep our ruby scripts
some handy Bash functions
110. 110
DATA_DIR="$ROOT_DIR/data"
COMMANDS_DIR="$ROOT_DIR/commands"
MODELS_DIR="$ROOT_DIR/models"
detect_wsl () {
set -e
grep -qE "(Microsoft|WSL)" /proc/version &> /dev/null
}
UNIX_PROCESS_STARTUP_DELAY=1
WSL_PROCESS_STARTUP_DELAY=5
if detect_wsl ; then
wait_for_process_launch () {
sleep WSL_PROCESS_STARTUP_DELAY
}
else
wait_for_process_launch () {
sleep UNIX_PROCESS_STARTUP_DELAY
}
fi
heading () {
ruby -e "
require '$COMMANDS_DIR/console'
Console.heading '$1'
"
}
subheading () {
ruby -e "
require '$COMMANDS_DIR/console'
Console.subheading '$1'
"
}
print_cic_statement() {
ruby "$COMMANDS_DIR/cic_banner.rb"
}
finished () {
heading "DONE"
}
WSL can take a long time
to launch a Linux process
so we check for it and add
a longer startup delay for
our system to boot
111. 111
DATA_DIR="$ROOT_DIR/data"
COMMANDS_DIR="$ROOT_DIR/commands"
MODELS_DIR="$ROOT_DIR/models"
detect_wsl () {
set -e
grep -qE "(Microsoft|WSL)" /proc/version &> /dev/null
}
UNIX_PROCESS_STARTUP_DELAY=1
WSL_PROCESS_STARTUP_DELAY=5
if detect_wsl ; then
wait_for_process_launch () {
sleep WSL_PROCESS_STARTUP_DELAY
}
else
wait_for_process_launch () {
sleep UNIX_PROCESS_STARTUP_DELAY
}
fi
heading () {
ruby -e "
require '$COMMANDS_DIR/console'
Console.heading '$1'
"
}
subheading () {
ruby -e "
require '$COMMANDS_DIR/console'
Console.subheading '$1'
"
}
print_cic_statement() {
ruby "$COMMANDS_DIR/cic_banner.rb"
}
finished () {
heading "DONE"
}
each of these is a string
containing Ruby code to
be executed by the
interpreter
112. 112
RUBY_DIR="$ROOT_DIR/ruby"
source scripts/basics.sh
# http_requests will print headers and response body along with stack dumps
# if the env variable DEBUG_HTTP_REQUESTS exists
ruby_web_client () {
local program=$1
ruby -e "
require 'json'
require '$CLIENTS_DIR/web'
$program
"
}
http_request () {
local version=$1
local method=$2
local address=$3
local endpoint=$4
local request_body=$5
ruby_web_client "
if ENV['DEBUG_HTTP_REQUESTS']
response = WebClient.$method($version, '$address', endpoint = $endpoint) do |req|
puts 'REQUEST:'
puts $request_body
$request_body
end
puts 'RESPONSE:'
response.each_header do |k, v|
puts "#{k}: #{v}"
end
puts "body: #{response.body}"
puts
else
WebClient.$method($version, '$address', endpoint = $endpoint) do |req|
$request_body
end rescue nil
end
"
}
use local to give shell function
parameters meaningful names
113. 113
RUBY_DIR="$ROOT_DIR/ruby"
source scripts/basics.sh
# http_requests will print headers and response body along with stack dumps
# if the env variable DEBUG_HTTP_REQUESTS exists
ruby_web_client () {
local program=$1
ruby -e "
require 'json'
require '$CLIENTS_DIR/web'
$program
"
}
http_request () {
local version=$1
local method=$2
local address=$3
local endpoint=$4
local request_body=$5
ruby_web_client "
if ENV['DEBUG_HTTP_REQUESTS']
response = WebClient.$method($version, '$address', endpoint = $endpoint) do |req|
puts 'REQUEST:'
puts $request_body
$request_body
end
puts 'RESPONSE:'
response.each_header do |k, v|
puts "#{k}: #{v}"
end
puts "body: #{response.body}"
puts
else
WebClient.$method($version, '$address', endpoint = $endpoint) do |req|
$request_body
end rescue nil
end
"
}
shell variables are strings
this allows us to pass in a
ruby program as a string
which will then be injected
into this string as a text
replacement
114. 114
RUBY_DIR="$ROOT_DIR/ruby"
source scripts/basics.sh
# http_requests will print headers and response body along with stack dumps
# if the env variable DEBUG_HTTP_REQUESTS exists
ruby_web_client () {
local program=$1
ruby -e "
require 'json'
require '$CLIENTS_DIR/web'
$program
"
}
http_request () {
local version=$1
local method=$2
local address=$3
local endpoint=$4
local request_body=$5
ruby_web_client "
if ENV['DEBUG_HTTP_REQUESTS']
response = WebClient.$method($version, '$address', endpoint = $endpoint) do |req|
puts 'REQUEST:'
puts $request_body
$request_body
end
puts 'RESPONSE:'
response.each_header do |k, v|
puts "#{k}: #{v}"
end
puts "body: #{response.body}"
puts
else
WebClient.$method($version, '$address', endpoint = $endpoint) do |req|
$request_body
end rescue nil
end
"
}
here we use it to make an
HTTP call using our Ruby
WebClient object
115. 115
#!/bin/bash
# (c) 2018 Innovative Identity Solutions Limited
# all rights reserved
source scripts/ruby_web_api.sh
print_cic_statement
BASE_SERVICE_PORT=9000
source ./infrastructure.sh
while getopts b:v:sh option
do
case "${option}" in
h) echo
echo "This script launches the infrastructure for user registration and interaction."
echo "For each user and the oracle it creates a running web service."
echo "It initialises the database when it runs."
echo
echo "Usage:"
echo " ./demo.sh -b bearer-name -v validator-name"
echo " ./demo.sh -h"
echo " ./demo.sh -s"
exit 0
;;
b) BEARER=${OPTARG};;
v) VALIDATOR=${OPTARG};;
s) shutdown $DOMAIN_ADDRESS;;
esac
done
if [ -z ${BEARER+x} ]; then
echo "specify bearer name with -b";
exit 1
fi
if [ -z ${VALIDATOR+x} ]; then
echo "specify validator name with -v";
exit 2
fi
scripts/startup.sh $BASE_SERVICE_PORT
heading "Launching bearer devices"
launch_bearer $BEAR_SERVICE $BEARER "bear.jpg"
launch_bearer $VAL_SERVICE $VALIDATOR "val.jpg"
launch our service network
117. 117
ROOT_DIR=`pwd`
REGISTRY_DIR="$ROOT_DIR/registry"
COMMANDS_DIR="$ROOT_DIR/commands"
MODELS_DIR="$ROOT_DIR/models"
create_registry () {
subheading "create registry"
rm -Rf "$REGISTRY_DIR"
mkdir -p "$REGISTRY_DIR"
pushd "$REGISTRY_DIR"
ruby -e "
require '$MODELS_DIR/oracle'
require '$COMMANDS_DIR/encryption'
Console.section 'Create $REGISTRY_DIR/Oracle.db' do
oracle = Models::Oracle.new
Console.section 'Create User Zero' do
key = Encryption::create_rsa_key filename: 'keyzero.pem', save_to_disk: true
digest = OpenSSL::Digest::SHA256.new(Base64.encode64 key.to_pem)
oracle.keys.insert ID: 0,
Label: '::1',
Key: key.public_key.to_pem,
Checksum: ENV['USE_AMALGALITE'] ? digest : digest.to_s
Console.display_records oracle, :Keys
end
end
"
popd
}
create_user_database () {
local database_dir="$REGISTRY_DIR/$1"
local selfie="$ROOT_DIR/$2"
heading "create user database: $database_dir"
mkdir -p "$database_dir"
pushd "$database_dir"
ln -s "$REGISTRY_DIR/oracle.db" "$database_dir"
ln -s "$selfie" "$database_dir"
popd "$database_dir"
}
we can directly use Ruby's
OpenSSL wrapper as well
as our own API over that
118. 118
ROOT_DIR=`pwd`
REGISTRY_DIR="$ROOT_DIR/registry"
COMMANDS_DIR="$ROOT_DIR/commands"
MODELS_DIR="$ROOT_DIR/models"
create_registry () {
subheading "create registry"
rm -Rf "$REGISTRY_DIR"
mkdir -p "$REGISTRY_DIR"
pushd "$REGISTRY_DIR"
ruby -e "
require '$MODELS_DIR/oracle'
require '$COMMANDS_DIR/encryption'
Console.section 'Create $REGISTRY_DIR/Oracle.db' do
oracle = Models::Oracle.new
Console.section 'Create User Zero' do
key = Encryption::create_rsa_key filename: 'keyzero.pem', save_to_disk: true
digest = OpenSSL::Digest::SHA256.new(Base64.encode64 key.to_pem)
oracle.keys.insert ID: 0,
Label: '::1',
Key: key.public_key.to_pem,
Checksum: ENV['USE_AMALGALITE'] ? digest : digest.to_s
Console.display_records oracle, :Keys
end
end
"
popd
}
create_user_database () {
local database_dir="$REGISTRY_DIR/$1"
local selfie="$ROOT_DIR/$2"
heading "create user database: $database_dir"
mkdir -p "$database_dir"
pushd "$database_dir"
ln -s "$REGISTRY_DIR/oracle.db" "$database_dir"
ln -s "$selfie" "$database_dir"
popd "$database_dir"
}
we're also able to use
SQLite via Amalgalite
which compiles it as an
in-process extension
119. 119
#!/bin/bash
# (c) 2018 Innovative Identity Solutions Limited
# all rights reserved
source scripts/ruby_web_api.sh
print_cic_statement
BASE_SERVICE_PORT=9000
source ./infrastructure.sh
while getopts b:v:sh option
do
case "${option}" in
h) echo
echo "This script launches the infrastructure for user registration and interaction."
echo "For each user and the oracle it creates a running web service."
echo "It initialises the database when it runs."
echo
echo "Usage:"
echo " ./demo.sh -b bearer-name -v validator-name"
echo " ./demo.sh -h"
echo " ./demo.sh -s"
exit 0
;;
b) BEARER=${OPTARG};;
v) VALIDATOR=${OPTARG};;
s) shutdown $DOMAIN_ADDRESS;;
esac
done
if [ -z ${BEARER+x} ]; then
echo "specify bearer name with -b";
exit 1
fi
if [ -z ${VALIDATOR+x} ]; then
echo "specify validator name with -v";
exit 2
fi
scripts/startup.sh $BASE_SERVICE_PORT
heading "Launching bearer devices"
launch_bearer $BEAR_SERVICE $BEARER "bear.jpg"
launch_bearer $VAL_SERVICE $VALIDATOR "val.jpg"
to create Ruby web services
120. 120
source "$SCRIPTS_DIR/ruby_web_client.sh"
launch_ruby_service () {
local service=$1
local address=$2
local directory="$REGISTRY_DIR$3"
local command_key=$4
pushd "$directory"
ADDRESS="$address" COMMAND_KEY="$command_key" ruby "$SERVICES_DIR/$service""_service.rb" &
wait_for_process_launch
popd
}
launch_service () {
local service=$1
local address=$2
local command_key=$3
local service_name="$service""_service"
http_request :v1 post $DOMAIN_ADDRESS :A "
req.set_form_data name: '$service_name', address: '$address'"
launch_ruby_service "$service" "$address" "" "$command_key"
}
halt_service () {
local version=$1
local address=$2
local command_key=$3
http_request :v1 shutdown $address nil "req.body = '$command_key'"
}
launch_bearer () {
local port="$1"
local name="$2"
local selfie="$3"
local command_key="$4"
create_user_database "$name" "$selfie"
pushd "$REGISTRY_DIR/$name"
PORT="$port" COMMAND_KEY="$command_key" ruby "$SERVICES_DIR/bearer_service.rb" &
sleep 1
popd
}
we need this to make web requests
121. 121
source "$SCRIPTS_DIR/ruby_web_client.sh"
launch_ruby_service () {
local service=$1
local address=$2
local directory="$REGISTRY_DIR$3"
local command_key=$4
pushd "$directory"
ADDRESS="$address" COMMAND_KEY="$command_key" ruby "$SERVICES_DIR/$service""_service.rb" &
wait_for_process_launch
popd
}
launch_service () {
local service=$1
local address=$2
local command_key=$3
local service_name="$service""_service"
http_request :v1 post $DOMAIN_ADDRESS :A "
req.set_form_data name: '$service_name', address: '$address'"
launch_ruby_service "$service" "$address" "" "$command_key"
}
halt_service () {
local version=$1
local address=$2
local command_key=$3
http_request :v1 shutdown $address nil "req.body = '$command_key'"
}
launch_bearer () {
local port="$1"
local name="$2"
local selfie="$3"
local command_key="$4"
create_user_database "$name" "$selfie"
pushd "$REGISTRY_DIR/$name"
PORT="$port" COMMAND_KEY="$command_key" ruby "$SERVICES_DIR/bearer_service.rb" &
sleep 1
popd
}
we can also start Ruby programs
with dynamically set Environment
Variables to configure them
122. 122
source "$SCRIPTS_DIR/ruby_web_client.sh"
launch_ruby_service () {
local service=$1
local address=$2
local directory="$REGISTRY_DIR$3"
local command_key=$4
pushd "$directory"
ADDRESS="$address" COMMAND_KEY="$command_key" ruby "$SERVICES_DIR/$service""_service.rb" &
wait_for_process_launch
popd
}
launch_service () {
local service=$1
local address=$2
local command_key=$3
local service_name="$service""_service"
http_request :v1 post $DOMAIN_ADDRESS :A "
req.set_form_data name: '$service_name', address: '$address'"
launch_ruby_service "$service" "$address" "" "$command_key"
}
halt_service () {
local version=$1
local address=$2
local command_key=$3
http_request :v1 shutdown $address nil "req.body = '$command_key'"
}
launch_bearer () {
local port="$1"
local name="$2"
local selfie="$3"
local command_key="$4"
create_user_database "$name" "$selfie"
pushd "$REGISTRY_DIR/$name"
PORT="$port" COMMAND_KEY="$command_key" ruby "$SERVICES_DIR/bearer_service.rb" &
sleep 1
popd
}
for each credential bearer in our
system we can launch a custom
ruby process in the background
to handle their behaviour
123. 123
known by their works
Love is a poet, love sings the songs
Pointing his
fi
nger you follow along
Voices are calling,
The monster wants out of you
Paws you and claws you, you try not to fall
- The Beast, Concrete Blonde
124. 124
● I have mixed feelings
on patents
● I filed some, and selling
the IP paid for several
years of research
● it also means people
can see what I do
● but the process can be
complicated
● and many patents suck
The Agony & The Ecstasy
125. 125
● original inventions
● not preexisting in
nature - except biotech
● no maths - unless it's
software and you're in
the US
● must have a concrete
implementation
● cannot have been
published before
What Can We Patent?
Dell? Mac? WTF?!?!
126. 126
● inventors have to publish
how their invention works
- except Marconi?
● the patent provides a
fixed term monopoly
● but the description of the
invention is in the public
domain
● only granted claims are
enforceable
Why Should We Patent?
Nikola Tesla!